[英]Is there a way to dynamically create nested divs onclick?
我正在尝试创建一个页面,用户可以通过添加额外的div或嵌套的div(根据他们喜欢的多层深度)来自定义表单。 在每个div中,我想要文本输入和一个按钮,它在同一级别上添加另一个div和一个嵌入div的按钮。 两个div应该再次具有文本输入和按钮,它们执行相同的操作。
但是我有点卡住了。 当我尝试创建一个嵌套的div时,我总是最后将它添加到底部而不是在其父级内部。
<html>
<script type="text/javascript">
var counter = 1;
function addNode() {
var newDiv = document.createElement('div');
counter++;
newDiv.innerHTML = "Entry " + counter + " <br><input type='text' name='myInputs'>";
document.getElementById("dynamicInput").appendChild(newDiv);
var newButton = document.createElement('button');
newButton.type = "button";
newButton.onclick = addSub;
document.getElementById("dynamicInput").appendChild(newButton);
}
function addSub() {
var newDiv = document.createElement('div');
counter++;
newDiv.innerHTML = "Entry " + counter + " <br><input type='text' name='myInputs' style='margin:10px'>";
document.getElementById("subInput").appendChild(newDiv);
}
</script>
<form class="form" method="POST">
<div id="dynamicInput" name="dynamicInput" multiple="multiple">
Entry 1<br><input type="text" name="myInputs">
<div id="subInput" name="subInput" multiple="multiple">
<input type="button" value="add nested" onClick="addSub();">
</div>
</div>
<input type="button" value="Add another text input" onClick="addNode();" >
<input type="submit" value = "answer" multiple="multiple"/>
</form>
</html>
这是一个完整的解决方案,请记住,如果您需要在生成的输入和按钮上绑定额外的事件,您必须在函数addNode或addSub中执行它,就像我对按钮上的click事件所做的那样。
工作示例: https : //jsfiddle.net/r70wqav7/
var counter = 1; function addNode(element) { counter++; var new_entry="Entry "+counter+"<br><input type='text' name='myInputs'><br>"; element.insertAdjacentHTML("beforebegin",new_entry); } function addSub(element) { counter++; var new_sub_entry="<div class='block'>" +"Entry "+counter+"<br><input type='text' name='myInputs'><br>" +"<div class='buttons'>" +"<input class='add_sub_button' type='button' value='add nested'>" +"<input class='add_button' type='button' value='Add another text input' >" +"</div>" +"</div><br />" +"</div>"; element.insertAdjacentHTML("beforebegin",new_sub_entry); var blocks=element.parentNode.getElementsByClassName("block"); blocks[blocks.length-1].getElementsByClassName("add_sub_button")[0].addEventListener("click",function(){ addSub(this.parentNode); }); blocks[blocks.length-1].getElementsByClassName("add_button")[0].addEventListener("click",function(){ addNode(this.parentNode); }); } var buttons=document.getElementsByClassName("add_button"); for(i=0;i<buttons.length;i++){ buttons[i].addEventListener("click",function(){ addNode(this.parentNode); }); } var nested_buttons=document.getElementsByClassName("add_sub_button"); for(i=0;i<buttons.length;i++){ nested_buttons[i].addEventListener("click",function(){ addSub(this.parentNode); }); }
div.block{ padding:5px; border:2px solid #000; }
<form class="form" method="POST"> <div class="block"> Entry 1<br><input type="text" name="myInputs"><br> <div class="buttons"> <input class="add_sub_button" type="button" value="add nested"> <input class="add_button" type="button" value="Add another text input" > </div> </div><br /> <input type="submit" value = "answer" multiple="multiple"/> </form>
已编辑:绑定更新的嵌套项上的click事件以使其正常工作时出错
这是另一个有用的例子,它利用了我之前评论中提到的概念。 我已经在表单外移动了Add-Item按钮,并更改了用于确定添加的每个新项目的文本的方法。 我不是保留一个计数器,而是计算文档中现有项目的数量并将其递增,使用它作为字符串“Entry n”中的n
我应该在创建新的按钮之前添加(附加)子项,但是在添加了另一个新元素之后在按钮上调用了appendChild
- 最终结果是相同的,但效率较低并且会导致性能降低/电池寿命缩短。
当我点击“添加新项目”时,我将使用.dynamicInput
div的.cloneNode
方法,但是这将复制所选目标的所有子项,我们仍然需要为该按钮调用addEventListener
,所以我选择了简单地创建添加了“添加新项”按钮的每个输入项。
<!doctype html>
<html>
<head>
<script>
"use strict";
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}
function allByClass(className,parent){return (parent == undefined ? document : parent).getElementsByClassName(className);}
function allByTag(tagName,parent){return (parent == undefined ? document : parent).getElementsByTagName(tagName);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('addNewInputBtn').addEventListener('click', myAddNewItem, false);
var subItemBtn = document.querySelectorAll('.dynamicInput button')[0];
subItemBtn.addEventListener('click', myAddSubItem, false);
}
function makeNewItem(titleStr)
{
var div = newEl('div');
div.className = 'dynamicInput';
var heading = newEl('h3');
heading.innerText = titleStr;
div.appendChild(heading);
var input = newEl('input');
div.appendChild(input);
var btn = newEl('button');
btn.innerText = 'Add sub-items';
btn.addEventListener('click', myAddSubItem, false);
div.appendChild(btn);
return div;
}
function myAddNewItem(evt)
{
var numAlreadyExisting = allByClass('dynamicInput').length; // count number of divs with className = dynamicInput
var newNum = numAlreadyExisting + 1;
var newInputPanel = makeNewItem('Entry ' + newNum);
byId('myForm').appendChild(newInputPanel);
return false;
}
function myAddSubItem(evt)
{
evt.preventDefault(); // stops this button causing the form to be submitted
var clickedBtn = this;
var inputDiv = clickedBtn.parentNode;
var newInput = newEl('input');
inputDiv.appendChild(newInput);
inputDiv.appendChild(clickedBtn);
}
</script>
</head>
<body>
<form id='myForm'>
<div class='dynamicInput'>
<h3>Entry 1</h3>
<input type='text'/><button>Add sub-item</button>
</div>
</form>
<button id='addNewInputBtn'>Add new item</button>
</body>
</html>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.