我是JavaScript的新手,我使用vanilla js、html和css来调查网站,用户可以在网站上添加问题和选项,当他们点击按钮时,它会创建一个容器,可以用"tag:textarea"填充。我正在使用"createElement(("、"setAttribute(("方法来创建一个新容器。但由于每个容器都有这么多嵌套的节点或组件,我写了大量的样板代码来创建一个容器,加上我必须用嵌套的"Hell"更改一些元素的id,这变得很难管理。我的html代码如下:
<div id="create-question-container-id" class="create-question-container" >
<div id="create-question-textarea-container-id_0" class="create-question-textarea-container">
<textarea id="create-question-textarea-id"
name="textareaquestion" class="create-question-textarea"
cols="50" row="1" style="font-size: 20pt;">
Untitled Question
</textarea>
<div id="create-answer-textarea-container-id-0" class="create-answer-textarea-container">
<div id="create-answer-N-container-id-0-0" class="create-answer-N-container">
<div class="create-qeuestion-radio-outer-circle" >
<div class="create-qeuestion-radio-innner-circle"></div>
</div>
<textarea id="opt1" name="textareaopt" class="create-answer-textarea"
placeholder="opt1" style="font-size: 14pt;">
</textarea>
</div>
</div>
<button onclick="addOption()" class="create-add-answer-btn" >
Add Option
</button>
</div>
</div>
<div class="create-main-container-submit-button">
<button onclick="clonecontainer()" class="create-main-submit-btn" >
Submit
</button>
</div>
这是来自地狱的Javascript代码:
var answer_container = document.getElementsByClassName('create-answer-textarea-container');
//increment this one
var answer_container_id = document.getElementById('create-answer-textarea-container-id-0');
var lastChildAnswer = answer_container[answer_container.length - 1];
var asnwer_container_list = answer_container_id.childNodes[answer_container.length];
//id of container wrapping around the question and the options named questionasnwcontain(this need to increment id)
var question_answer_container_list = document.getElementById('create-question-textarea-container-id_0')
//id of container wrapping around the questionasnwcontain(main container)
var all_question_asnwer_container = document.getElementById('create-question-container-id');
var all_question_asnwer_container_class_Name = document.getElementsByClassName('create-question-container');
var all_counter = all_question_asnwer_container.childElementCount -1;
function clonecontainer() {
var dashed_delimeter = '-';
var lastChildContainer = answer_container_id.lastElementChild.getAttribute('id')
var trimlastChild = answer_container_id.lastElementChild.lastElementChild.getAttribute('id')
var delimeter = 't'
var trimlastChildSubString = trimlastChild.split(delimeter);
var lastChildString = trimlastChildSubString[1]
//split lastChildContainer
var splitted_lastChildContainer = lastChildContainer.split(dashed_delimeter)[5];
var new_id_spliited_lastChildContainer = 'create-answer-N-container-id-' + ((parseInt(splitted_lastChildContainer)) + (all_question_asnwer_container.childElementCount -1) ) + '-0';
//get the cloned container's child id for incremental
var last_main_container_child = all_question_asnwer_container.lastElementChild.getAttribute('id');
var trimlast_id = seperateWithDelimeter(last_main_container_child);
var trimlast_new_id ='_' + (parseInt(trimlast_id[1]) + (all_question_asnwer_container.childElementCount -1) );
console.log(trimlast_new_id)
//(fixed)
var last_cloned_delimeter = '_';
var last_cloned_container = all_question_asnwer_container.childNodes[all_question_asnwer_container_class_Name.length].getAttribute('id')
var splitted_cloned_container = last_cloned_container.split(last_cloned_delimeter);
var new_splitted_cloned_container_id = 'create-answer-textarea-container-id-' + ((parseInt(splitted_cloned_container[1])) + (all_question_asnwer_container.childElementCount )) ;
console.log(new_splitted_cloned_container_id)
//new div fr asnwer container
var new_div_fr_answer_container_id = document.createElement('div');
new_div_fr_answer_container_id.setAttribute('class' , 'create-question-textarea-container');
new_div_fr_answer_container_id.setAttribute('id' ,'create-question-textarea-container-id' + trimlast_new_id)
console.log(new_div_fr_answer_container_id)
//new question text area
var new_textarea_fr_create_question_textarea_id = document.createElement('textarea');
new_textarea_fr_create_question_textarea_id.setAttribute('class' , 'create-question-textarea');
new_textarea_fr_create_question_textarea_id.setAttribute('id' , 'create-question-textarea-id')
new_textarea_fr_create_question_textarea_id.setAttribute('cols' , 50);
new_textarea_fr_create_question_textarea_id.setAttribute('row' , 1);
new_textarea_fr_create_question_textarea_id.style.fontSize = '20pt';
//new for option text area wrrapeer
var new_option_text_area_wrapper = document.createElement('div');
new_option_text_area_wrapper.setAttribute('class' , 'create-answer-textarea-container');
new_option_text_area_wrapper.setAttribute('id' , new_splitted_cloned_container_id);
var new_option_N_text_area_wrapper = document.createElement('div');
new_option_N_text_area_wrapper.setAttribute('class' , 'create-answer-N-container');
new_option_N_text_area_wrapper.setAttribute('id', new_id_spliited_lastChildContainer);
var new_checkbox_inner = document.createElement('div');
new_checkbox_inner.setAttribute('class' , 'create-qeuestion-radio-inner-circle');
//create Element for checkBox outerCircle
var new_checkbox = document.createElement('div');
new_checkbox.setAttribute('class' , 'create-qeuestion-radio-outer-circle');
//append innerCircle
new_checkbox.appendChild(new_checkbox_inner);
var new_answer = document.createElement('textarea');
new_answer.setAttribute('name' , 'textareaopt');
new_answer.setAttribute('id' , 'opt'+ (parseInt(lastChildString) + 1));
new_answer.setAttribute('class' , 'create-answer-textarea');
new_answer.setAttribute('placeholder' , 'opt'+ (parseInt(lastChildString) + 1))
new_answer.style.fontSize = "14pt";
new_option_N_text_area_wrapper.appendChild(new_checkbox);
new_option_N_text_area_wrapper.appendChild(new_answer);
new_option_text_area_wrapper.appendChild(new_option_N_text_area_wrapper);
new_div_fr_answer_container_id.appendChild(new_textarea_fr_create_question_textarea_id);
new_div_fr_answer_container_id.appendChild(new_option_text_area_wrapper);
all_question_asnwer_container.appendChild(new_div_fr_answer_container_id);
}
所有这些都只是重复的方法。所以我的问题是,有没有一种更有效的方法来做到这一点,或者有没有一个类可以让它更易于管理。
您有几个选项,其中两个是:
-
如果你不介意每次解析HTML(在现代浏览器上解析HTML真的很快(,你可以使用
insertAdjacentHTML
,也许还有一个模板文字,这样你就可以很容易地嵌入换行符,并使用${x}
语法来嵌入值:all_question_asnwer_container.insertAdjacentHTML("beforeend", `<div> (etc.) </div>`);
-
您可以在HTML中使用
template
元素,根据需要(通过cloneNode
(进行克隆。以下是链接页面中MDN示例的克隆部分var tbody = document.querySelector("tbody"); var template = document.querySelector('#productrow'); // The template element // Clone the new row and insert it into the table var clone = template.content.cloneNode(true); var td = clone.querySelectorAll("td"); td[0].textContent = "1235646565"; td[1].textContent = "Stuff"; tbody.appendChild(clone);
const
btAdd = document.querySelector('button#bt-add')
, container = document.querySelector('div#container')
, builder =
{ ref_id : 0
, newDiv()
{
let sub_id = 0
, div = document.createElement('div')
;
div.id = ++this.ref_id
div.innerHTML = `
<div id="bla-bla-id_${this.ref_id}" class="xxzw">
<em> text areas: </em><br>
<textarea id="opt${this.ref_id}-${++sub_id}" placeholder="txt-area ${this.ref_id}-${sub_id} "></textarea><br>
<textarea id="opt${this.ref_id}-${++sub_id}" placeholder="txt-area ${this.ref_id}-${sub_id} "></textarea>
</div>`
container.appendChild(div)
}
}
btAdd.onclick = e =>
{
builder.newDiv()
}
div#container {
margin : 1em;
width : 20em;
}
div#container > div {
margin : .8em 0;
padding : .2em;
border : 1px solid lightblue;
}
em {
font-size : .7em;
font-weight : bold;
}
textarea {
width : 90%;
}
<button id="bt-add">add</button>
<div id="container"> </div>