在Javascript中克隆节点

时间:2015-05-14 14:06:02

标签: javascript html css

我在这里摆弄了我的代码 - https://jsfiddle.net/wxd2pw88/2/

HTML

<body>
    <input type="text" id="textbox"/> 
    <button type="button" id="addition" onclick="add()"> + </button>
    <button type="button" id="subtraction" onclick="sub()"> - </button>
    <div id="replace"></div>
</body>

JS

window.add =  function() {
    var inpt = document.getElementById('textbox');
    var clone = inpt.cloneNode(false);
    inpt.parentNode.appendChild(clone);

    var button1 = document.getElementById('addition');
    button1.parentNode.appendChild(button1.cloneNode(true));

    var button2 = document.getElementById('subtraction');
    button2.parentNode.appendChild(button2.cloneNode(true)); 

    var div1 = document.getElementById('replace');
    div1.parentNode.appendChild(div1.cloneNode(false));
}

window.sub = function() {
    var clonedTextbox = document.querySelectorAll('#textbox');
    var clonedButton1 = document.querySelectorAll('#addition');
    var clonedButton2 = document.querySelectorAll('#subtraction');

    clonedTextbox[clonedTextbox.length-1].parentNode.removeChild(clonedTextbox[clonedTextbox.length-1]);
    clonedButton1[clonedButton1.length-1].parentNode.removeChild(clonedButton1[clonedButton1.length-1]);
    clonedButton2[clonedButton2.length-1].parentNode.removeChild(clonedButton2[clonedButton2.length-1]);
}

CSS

input{
    margin: 0px;
}

div {
    margin: 3px;
}

以下是我面临的问题:

  1. 按钮类型为无边距的子节点

  2. 按下“+”按钮时,会创建一个新的子节点。我只希望最后一个孩子能够做到这一点。目前,所有孩子和父母都能够创造孩子。我只希望最后一个孩子的“+”按钮处于活动状态。应禁用所有其他孩子和父母的按钮。

  3. 我在文本框中输入的任何文本也会被复制到子项中。我认为这是因为克隆方法,所以我尝试使用createElement方法。使用它时遇到的问题是没有子节点能够创建子节点。只有父级才能创建多个子节点。

4 个答案:

答案 0 :(得分:1)

首先,您过度使用ID,它们必须是唯一的,因此我将它们更改为类。

其次,添加了一个变量来跟踪克隆的数量,以便更容易访问最后一个。

jsfiddle DEMO

var numClones = 0;

window.add = function () {
    var inpt = document.querySelectorAll('.textbox')[numClones];
    var clone = inpt.cloneNode(false);
    clone.value = "";
    inpt.parentNode.appendChild(clone);

    var button1 = document.querySelectorAll('.addition')[numClones];
    button1.parentNode.appendChild(button1.cloneNode(true));

    var button2 = document.querySelectorAll('.subtraction')[numClones];
    button2.parentNode.appendChild(button2.cloneNode(true));

    button1.disabled = true;
    button2.disabled = true;

    var div1 = document.querySelectorAll('.replace')[numClones];
    div1.parentNode.appendChild(div1.cloneNode(false));
    numClones++;
}

window.sub = function () {
    var clonedTextbox = document.querySelectorAll('.textbox')[numClones];
    var clonedButton1 = document.querySelectorAll('.addition')[numClones];
    var clonedButton2 = document.querySelectorAll('.subtraction')[numClones];

    clonedTextbox.parentNode.removeChild(clonedTextbox);
    clonedButton1.parentNode.removeChild(clonedButton1);
    clonedButton2.parentNode.removeChild(clonedButton2);

    numClones--;

    if (numClones >= 0) {
        var lastAdd = document.querySelectorAll('.addition')[numClones];
        var lastSub = document.querySelectorAll('.subtraction')[numClones];
        lastAdd.disabled = false;
        lastSub.disabled = false;
    }
}

修改:

额外的空间用于换行,只需将它们放在另一个之后,而不是换行。

答案 1 :(得分:0)

好吧,回答你的#2点我已经看过你jsfiddle并提出了这个解决方案:

window.add =  function(element) {
	var inpt = element.previousElementSibling;
	var clone = inpt.cloneNode(false);
    clone.value = ''; //Question #3
	inpt.parentNode.appendChild(clone);
	var button1 = element;
	button1.parentNode.appendChild(button1.cloneNode(true));

	var button2 = element.nextElementSibling;
	button2.parentNode.appendChild(button2.cloneNode(true)); 
    button2.setAttribute('disabled','disabled')
    button1.setAttribute('disabled','disabled');

	var div1 = document.getElementById('replace');
	div1.parentNode.appendChild(div1.cloneNode(false));
}

window.sub = function() {
	var clonedTextbox = document.querySelectorAll('#textbox');
	var clonedButton1 = document.querySelectorAll('#addition');
	var clonedButton2 = document.querySelectorAll('#subtraction');

	clonedTextbox[clonedTextbox.length-1].parentNode.removeChild(clonedTextbox[clonedTextbox.length-1]);
	clonedButton1[clonedButton1.length-1].parentNode.removeChild(clonedButton1[clonedButton1.length-1]);
	clonedButton2[clonedButton2.length-1].parentNode.removeChild(clonedButton2[clonedButton2.length-1]);
    
    //remove disabled
    clonedButton2[clonedButton2.length-2].removeAttribute('disabled');
    clonedButton1[clonedButton1.length-2].removeAttribute('disabled');
}
input{
	margin: 0px;
}

div {
	margin: 3px;
}
<body>
    <input type="text" id="textbox"/> 
    <button type="button" id="addition" onclick="add(this)"> + </button>
    <button type="button" id="subtraction" onclick="sub(this)"> - </button>
    <div id="replace"></div>
</body>

关于你的#1和#3点,我会尽可能地看看它。

编辑1:

通过重置克隆值解决了#3。

注意:

  1. 您使用的是同一个ID's,它们应该是唯一的!
  2. 此解决方案以您的为基础,但有最简单的方法。这里的一些答案突出了这些。

答案 2 :(得分:0)

你是说这样的意思吗?在我的版本中,你只能在至少有1个时删除它,并且你只能在最后一个上点击添加。

如果你想禁用它,我想你可以改为改变css;)

var templateRow, content;

function removeLast()
{
    var children = content.children || [], 
        index = (children.length || 0) - 1;
    if (children.length > 0) {
        children[index].className = children[index].className.replace(/last/g, '');
    }
}

function setLast()
{
    var children = content.children || [], 
        index = (children.length || 0) - 1;
    if (children.length > 0) {
        children[index].className += ' last';
    }
}

function add() {
    removeLast();
    var el = document.createElement('div');
    el.innerHTML = templateRow;
    el.className = 'inputrow';
    if (content.children.length === 0) {
        el.className += ' first';
    }
    content.appendChild(el);
    setLast();
}

function retract(el) {
    var parent = el.parentNode;
    content.removeChild(parent);
    setLast();
}

window.addEventListener('load', function() {
    templateRow  = document.getElementById('rowtemplate').innerHTML;
    content = document.getElementById('entire');
    add();
});
.inputrow .input {
    margin: 0;
}
.inputrow button {
    margin: 3px;
}
.hidden {
    display: none;
}
.first .remove-button
{
    display: none;
}
.add-button 
{
    display: none;
}
.last .add-button
{
    display: inline-block;
}
<template class="hidden" id="rowtemplate"><input type="text" name="textbox" /><button type="button" class="add-button" onclick="add();">+</button><button type="button" class="remove-button" onclick="retract(this);">-</button></template>
<div id="entire"></div>

答案 3 :(得分:0)

首先,你是克隆元素,因为HTML / JS中不允许重复的ID,所以它们不能拥有ID。

你没有使用jQuery,我认为你不能/不想使用它,有些我会使用普通的JS。

我还假设要求使用DOM0 event attachements(直接在HTML中)而不是更现代的addEventListener()方式。

实现这一目标的最简单方法是使用某种委托事件。您可以将它们包装在容器中,并将该容器用作副本点,而不是使用元素本身。

Fiddle here

HTML

<body>
    <div class="container">
        <input type="text" class="textbox"/> 
        <button type="button" class="addition" onclick="add.call(this)">+</button>
        <button type="button" class="subtraction" onclick="sub.call(this)">-</button>
        <div class="replace"></div>
    </div>
</body>

的Javascript

window.add =  function() {
    var addBtn = this,
        cnt = addBtn.parentNode,
        delBtn = cnt.getElementsByClassName('subtraction')[0],
        clone = cnt.cloneNode(true);

    // duplicate box
    cnt.parentNode.appendChild(clone);

    //hide buttons from this box
    addBtn.style.display = 'none';
    delBtn.style.display = 'none';
}

window.sub = function() {
    var cnt = this.parentNode,
        sibling = cnt.previousElementSibling;

    // show buttons from previous sibling
    sibling.getElementsByTagName('button')[0].style.display = 'inline-block';
    sibling.getElementsByTagName('button')[1].style.display = 'inline-block';

    //delete this box
    cnt.parentNode.removeChild(cnt);    
}

注意

注意我正在使用onclick="add.call(this)",以便在上下文中调用该函数,将事件附加到的节点作为参数传递给函数。