首页 > 解决方案 > 如何删除

  • 列出项目并使其余项目更改其位置和ID?
  • 问题描述

    棘手的问题,对我的水平(js学生)来说太高级了。

    假设我使用 append 方法<li>在 an 中生成项目<ol>,并且我需要这些 li 项目中的每一个项目都有一个唯一的 id,所以我想通过这样说来获取<li>我生成的(长度)项目的数量:var index = document.getElementById("ol1").getElementsByTagName("li").length+1;并使用这个数字通过这样做为我生成的每个项目创建唯一的 id:li.id="li"+index;所以我生成的第一个变为 # li1(因为 li 项目的数量是一个),下一个变为 # li2等等。*顺便说一句,这样做是正确的方法吗?

    现在假设我要删除#li1,然后#li2 将其替换到列表的位置1,但它的id 仍然是#li2,因为它已经得到它。

    例如,我最终想要的是当我删除#li1,然后#li2 变成#li1,#li3 变成#li2,#li4 变成#li3......等等。

    做这种噱头的正确逻辑方法是什么?

    function append() {
    
      var index = document.getElementById("ol1").getElementsByTagName("li").length + 1;
    
    
      var ol = document.getElementById("ol1");
      var li = document.createElement("li");
    
      li.id = "li" + index;
      li.innerHTML = (`LIST ITEM <input value=this&nbsp;is&nbsp;id:&nbsp;#li${index}><button class=remove id= button${index} onclick=remove${index}()>REMOVE</button>`);
      ol.append(li)
    
    
    }
    
    function remove1() {
      var rem = document.getElementById("li1");
      rem.remove();
    }
    
    function displayIndex() {
      var index = document.getElementById("ol1").getElementsByTagName("li").length;
    
      alert(index);
    }
    #li1 {
      color: red;
    }
    
    #li2 {
      color: green;
    }
    
    #li3 {
      color: blue;
    }
    
    ol button {
      color: red;
      visibility: hidden;
    }
    
    #button1 {
      color: red;
      visibility: visible;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <html>
    
    <head>
      <button id="btn1" onclick="append()">Append</button>
      <button id="btn2" onclick="displayIndex()">Index</button>
    </head>
    
    <body>
      <ol id="ol1">
      </ol>
    </body>
    
    </html>

    标签: javascripthtmlcss

    解决方案


    首先:
    没有“正确”的方法。只有有效的实现。它的实现方式可能因开发人员而异,只要它有效,就应该被认为是“正确”的方式(但是,不一定是最有效或优化的方式或任何其他方式)。

    一种方法是使用一个remove()函数来重新分配剩余<li>s 的 ID(显然是在删除之后)作为副作用。

    function removeItemOf(list, listItem) {
      if (!list.contains(listItem)) return;
      
      listItem.remove();
      indexItemsOf(list);
      
      // For displaying the removed ID on-screen
      document.querySelector('div').append(
        document.createElement('br'),
        document.createTextNode(`Removed <li> with id '${listItem.id}'`)
      );
    }
    
    function indexItemsOf(list) {
      for (var i = 0; list.children[i]; ++i) {
        list.children[i].id = (list.id || list.tagName) + '-li' + i;
        
        // For displaying the <li>'s ID on-screen
        list.children[i].textContent = `With ID '${list.children[i].id}'`;
      }
    }
    
    var list = document.querySelector('ol');
    
    indexItemsOf(list);
    setTimeout(() => {
      removeItemOf(list, list.children[0]);
    }, 2000);
    setTimeout(() => {
      removeItemOf(list, list.children[1]);
    }, 4000);
    <ol>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ol>
    
    <div></div>

    但是,重新分配以前使用的 ID 会使它对一个元素不是唯一的,因为它现在标识了以前未标识的另一个元素。对于这很重要的环境(例如,依赖一个元素来引用某些其他元素,或者拥有某个事件侦听器等),重新使用 ID 会破坏环境。

    为了规避这个问题,可以跟踪一个列表在其整个生命周期内有多少个唯一项目,并使用该数量创建具有 ID 的下一个项目,然后将数量增加一个。

    这是一个例子:

    var list = document.querySelector('ol');
    list.uniqueItems = 0;
    
    // Here: Using Event-Delegation for removing a <li>
    list.addEventListener('click', function(evt) {
      if (evt.target.classList.contains('btn-delete'))
        evt.target.closest('li').remove();
    });
    
    document.querySelector('button').addEventListener('click', function() {
      var item = document.createElement('li');
      item.id = 'li-' + list.uniqueItems;
      item.textContent = `Has the ID '${item.id}' `;
      
      var btnDelete = document.createElement('button');
      btnDelete.classList.add('btn-delete');
      btnDelete.textContent = 'Delete Item';
      
      item.append(btnDelete);
      list.append(item);
      
      list.uniqueItems++;
    });
    <button>New Item</button>
    
    <ol></ol>


    推荐阅读