javascript - 创建新元素 JS 的更有效方法(不知道标题应该叫什么)
问题描述
我是 JavaScript 新手,我正在使用 vanilla js、html 和 css 来调查网站,用户可以在其中添加问题和选项,当他们单击按钮时,它将创建一个容器,他们可以用“tag:textarea”填充该容器. 我正在使用“createElement()”、“setAttribute()”方法来创建一个新容器。但是由于每个容器都有这么多嵌套的节点或组件,我已经编写了大量的样板代码来创建容器,而且我必须使用嵌套的“地狱”更改某些元素的 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>`);
您可以根据需要
template
在 HTML 中使用克隆(通过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);
推荐阅读
- c# - 在两个表和 M:M 表中插入记录 - Entity Framework Core
- javascript - 使用 jQuery 选择器组合多个 JS 选择器
- flutter - Flutter:在构建之前获取小部件大小
- oauth-2.0 - 如何使用相同的 ADFS 身份验证服务器验证来自第三方的令牌?
- python - scipy.optimize.curve_fit 返回 inf pcov
- python - 在 python 中使用 ML.NET 训练的模型
- xcode - Apple TV 与 Xcode 12 配对
- python - Python 中的石头、纸和剪刀
- c - C程序返回带有答案的%
- r - R将虚拟变量转换为因子变量