【问题标题】:javascript clone a tree of elements and change all the IDs in the clonejavascript克隆元素树并更改克隆中的所有ID
【发布时间】:2014-12-04 07:00:43
【问题描述】:

我创建了一个按钮,可让您克隆元素树。这是我的代码:

   function add_party(number) {
    var n = number.replace("party", ""); 
    var newparty = document.getElementById("party"+n);
    var div = document.createElement("div");
    var con = document.getElementById("party1").innerHTML;
    document.createElement("div");
    div.id = 'party' + ++n;
    div.innerHTML = con;
    newparty.parentNode.insertBefore(div, newparty.nextSibling);
    renumberDivs(div, n, "div","party");
   }

这是我的 HTML:

   <div id="party1">
    <h1>Party 1</h1>
    <table>
     <tbody>
      <tr>
       <th>party name:</th>
       <td><input type="text" name="name1" value="some name"></td>
     </tr>
     <tr>
      <th>party time:</th>
      <td><input type="text" name="time1" value="some time"></td>
     </tr>
    </tbody>
   </table>
   <input type="button" onclick="add_party(this.parentNode.id)" value="add party">
  </div>

但是,由于每个元素都有唯一的 ID 或名称,因此克隆不应具有相同的 ID 或名称。相反,新的 ID 和名称应该加 1。所以克隆的树应该是这样的:

   <div id="party2">
    <h1>Party 2</h1>
    <table>
     <tbody>
      <tr>
       <th>party name:</th>
       <td><input type="text" name="name2" value=""></td>
     </tr>
     <tr>
      <th>party time:</th>
      <td><input type="text" name="time2" value=""></td>
     </tr>
    </tbody>
   </table>
   <input type="button" onclick="add_party(this.parentNode.id)" value="add party">
  </div>

此外,克隆的输入值应该为空。我怎么能用javascript做到这一点? (请不要使用 jQuery)。

谢谢。

编辑:

此代码更新计数,因此它们始终按顺序显示:

function renumberDivs(el, n, tagn, ass) {
    while (el = el.nextSibling) {
    if (el.tagName && el.tagName.toLowerCase() == tagn){
      el.id = ass + ++n;
     }
    }
   }

【问题讨论】:

    标签: javascript clone


    【解决方案1】:

    通常,此解决方案分为两步:

    1. 从最后一个到插入点一一操作现有的各方。
    2. 将新方插入到插入点。

    function add_party(divId) {
        var party = document.getElementById(divId);
        var newParty = party.cloneNode(true);
        var allParties = document.querySelectorAll('div[id^="party"]');
        var newId = parseInt(divId.replace('party', ''), 10) + 1;
    
        for(var i = allParties.length-1; i > newId-2; i--) {
            allParties[i].setAttribute('id', 'party' + (i+2));
            allParties[i].querySelector('h1').innerHTML = 'Party ' + (i+2);
            var partyInputs = allParties[i].querySelectorAll('input[type="text"]');
            for(var j = 0; j < partyInputs.length; j++) {
                var prefix = partyInputs[j].getAttribute("name").replace(/\d+/, "");
                partyInputs[j].setAttribute("name", prefix + (i+2));
            }
        }
    
        newParty.setAttribute('id', 'party' + newId);
        newParty.querySelector('h1').innerHTML = 'Party ' + newId;
        var inputs = newParty.querySelectorAll('input[type="text"]');
        for(var i = 0; i < inputs.length; i++) {
            var prefix = inputs[i].getAttribute("name").replace(/\d+/, "");
            inputs[i].setAttribute("name", prefix + newId);
            inputs[i].setAttribute("value", "");
            inputs[i].value = "";
        }
    
        party.parentNode.insertBefore(newParty, party.nextSibling);
    }
    <div id="party1">
        <h1>Party 1</h1>
        <table>
            <tbody>
                <tr>
                    <th>party name:</th>
                    <td><input type="text" name="name1" value="some name"></td>
                </tr>
                <tr>
                    <th>party time:</th>
                    <td><input type="text" name="time1" value="some time"></td>
                </tr>
            </tbody>
        </table>
        <input type="button" onclick="add_party(this.parentNode.id)" value="add party">
    </div>

    【讨论】:

    • 我们快到了,但还有两个问题:首先,新派对应该出现在按下按钮的派对下方(我的原始代码就是这样做的),其次,因为我们在旧的政党之间有新的政党,那么计数中的数字将不匹配。我将代码添加到我的问题中,将旧数字更新为新数字。但是我找不到将您的代码与我的代码结合起来的方法。
    • @CainNuke 说,你点击添加按钮,现在你有 1 和 2。然后你点击 1 的添加按钮,你想在 1 和 2 之间插入一个派对,并且你想要新添加到是 2,原来的 2 变成了 3。这是你想要的吗?
    • @CainNuke 答案更新了,看看是不是你想要的?
    • 是的,现在完美了。非常感谢。现在只有一个问题:这条线到底是做什么的? parseInt(divId.replace('party', ''), 10) + 1;
    • divId 是 DIV 的 id,其中包含您单击的按钮,例如 "party2"divId.replace('party', '') 检索数字部分,"2"。但这仍然是一个字符串(表示一个数字),所以我们使用parseInt,转换为十进制数。然后+1获取新加入方的ID号。
    【解决方案2】:

    您最好使用addEventListener 将事件附加到元素。我发现它很有趣。请参考DEMO...,但是有一个问题,对于新生成的表单,没有附加事件处理程序,所以你应该为新生成的表单附加新的事件处理程序。如果你可以使用 jQuery 或其他一些,你可以使用像 Delegate 这样的函数来自动绑定事件处理程序

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-02
      • 2013-03-27
      • 1970-01-01
      • 1970-01-01
      • 2013-01-26
      • 1970-01-01
      • 2016-01-30
      相关资源
      最近更新 更多