【问题标题】:I can't set JS removeChild to work properly我无法将 JS removeChild 设置为正常工作
【发布时间】:2021-01-19 01:17:26
【问题描述】:

抱歉我的愚蠢问题和糟糕的解释

目前我正在学习 JS,我不明白出了什么问题。

我正在尝试制作新的

点击按钮时列出,点击X时我想删除它

它在某些方面确实有效,但它仅在 P 标签超过 1 个时有效。所以不可能删除所有提交的内容

var list = document.querySelector("#list");
var text = document.querySelector("#write");
var btn = document.querySelector("#submit");

btn.addEventListener("click", add);

function add(){
    var newP = document.createElement("p");
    var newUl = document.createElement("ul");
    var newLi = document.createElement("li");
    var newText = document.createTextNode(text.value);
    var delbtn = document.createElement("span");
    delbtn.setAttribute("class", "del")
    var delText = document.createTextNode("X");
    var delbtns = document.querySelectorAll(".del")
    list.appendChild(newP);
    newP.appendChild(newUl);
    newUl.appendChild(newLi);
    newLi.appendChild(newText);
    newP.appendChild(delbtn);
    delbtn.appendChild(delText);
    text.value = ""
    text.focus();
    
    for (var i = 0; i < delbtns.length; i++){
        delbtns[i].addEventListener("click", function () {
            if(this.parentNode.parentNode)
            this.parentNode.parentNode.removeChild(this.parentNode)
        });
    }
}
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style>
        p{
            width: 80%;
        }
        .del{
            border: 1px solid #999;
            display: flex;
            flex-basis: 200;
        }
    </style>
</head>
<body>
    <h1>hello world</h1>
    <form action="">
        <input type="text" id="write" />
        <input type="button" id="submit"/>
    </form>
    <div id="list"></div>
    <script src="index.js"></script>
</body>
</html>

【问题讨论】:

  • 您是否尝试在插入按钮后移动var delbtns = document.querySelectorAll(".del")?看起来它一开始就找不到它,因为它还没有插入。

标签: javascript for-loop object removechild createelement


【解决方案1】:

每次单击添加按钮时,您都在向所有按钮添加侦听器,而不是删除(导致一个按钮有多个侦听器)。

您可以直接在delbtn 元素中设置事件处理程序。

delbtn.addEventListener("click", function(e) {
   if (this.parentNode.parentNode)
      this.parentNode.parentNode.removeChild(this.parentNode)
});

工作小提琴:https://jsfiddle.net/mrlew/g1fckz6t/3/

【讨论】:

    【解决方案2】:

    你通过循环不断地冒泡你的事件,这是第一个错误。当您创建新项目时,您需要单独向其添加事件监听器一次。如果您使用开发工具检查您的结构,您会在一个项目上看到几个相同的事件。

    所以在你创建元素之后只定位最后一个:

    document.querySelector("#list > p:last-of-type > span.del:last-of-type").addEventListener("click", function () {
            if(this.parentNode.parentNode)
            this.parentNode.parentNode.removeChild(this.parentNode)
        });
    

    示例:

    var list = document.querySelector("#list");
    var text = document.querySelector("#write");
    var btn = document.querySelector("#submit");
    
    btn.addEventListener("click", add);
    
    function add(){
        var newP = document.createElement("p");
        var newUl = document.createElement("ul");
        var newLi = document.createElement("li");
        var newText = document.createTextNode(text.value);
        var delbtn = document.createElement("span");
        delbtn.setAttribute("class", "del")
        var delText = document.createTextNode("X");
        var delbtns = document.querySelectorAll(".del")
        list.appendChild(newP);
        newP.appendChild(newUl);
        newUl.appendChild(newLi);
        newLi.appendChild(newText);
        newP.appendChild(delbtn);
        delbtn.appendChild(delText);
        text.value = ""
        text.focus();
        
        document.querySelector("#list > p:last-of-type > span.del:last-of-type").addEventListener("click", function () {
                if(this.parentNode.parentNode)
                this.parentNode.parentNode.removeChild(this.parentNode)
            });
     
    }
    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <style>
            p{
                width: 80%;
            }
            .del{
                border: 1px solid #999;
                display: flex;
                flex-basis: 200;
            }
        </style>
    </head>
    <body>
        <h1>hello world</h1>
        <form action="">
            <input type="text" id="write" />
            <input type="button" id="submit"/>
        </form>
        <div id="list"></div>
        <script src="index.js"></script>
    </body>
    </html>

    请注意,您正在创建新段落,其中包含一个列表,其中只有一个项目。不确定这是故意的,但这不是 HTML 列表应该如何工作的。你应该有 ul 元素和更多 li's 里面...

    【讨论】:

      【解决方案3】:

      你不需要用for循环添加多个事件,你只需要同时为每个添加的按钮添加事件,这里是一个有效的sn-p

      var list = document.querySelector("#list");
      var text = document.querySelector("#write");
      var btn = document.querySelector("#submit");
      
      btn.addEventListener("click", add);
      
      function add(){
          var newP = document.createElement("p");
          var newUl = document.createElement("ul");
          var newLi = document.createElement("li");
          var newText = document.createTextNode(text.value);
          var delbtn = document.createElement("span");
          delbtn.setAttribute("class", "del")
          var delText = document.createTextNode("X");
          newP.appendChild(newUl);
          newUl.appendChild(newLi);
          newLi.appendChild(newText);
          newP.appendChild(delbtn);
          delbtn.appendChild(delText);
          list.appendChild(newP);
          text.value = ""
          text.focus();
          delbtn.addEventListener("click", function () {
                  if(this.parentNode.parentNode)
                  this.parentNode.parentNode.removeChild(this.parentNode)
              });
      }
      <!doctype html>
      <html lang="en">
      <head>
          <meta charset="UTF-8" />
          <title>Document</title>
          <style>
              p{
                  width: 80%;
              }
              .del{
                  border: 1px solid #999;
                  display: flex;
                  flex-basis: 200;
              }
          </style>
      </head>
      <body>
          <h1>hello world</h1>
          <form action="">
              <input type="text" id="write" />
              <input type="button" value="add" id="submit"/>
          </form>
          <div id="list"></div>
          <script src="index.js"></script>
      </body>
      </html>

      【讨论】:

      【解决方案4】:

      我在这个答案中使用了闭包的力量,如果你想理解这个答案,你需要先了解 javascript 闭包。

      const input = document.querySelector('#input');
                      const btn = document.querySelector('#btn');
                      
                      function add() {
                          const inputVal = input.value;
                          input.value = '';
                          const ul = document.createElement('ul');
                          const li = document.createElement('li');
                          const p = document.createElement('p');
                          p.textContent = inputVal;
                          const deleteBtn = document.createElement('button');
                          deleteBtn.textContent = 'delete';
                          document.body.appendChild(ul);
                          ul.appendChild(li);
                          li.appendChild(p);
                          li.appendChild(deleteBtn);
                          deleteBtn.addEventListener('click', () => {
                              li.remove();
                          });
                      };
                      btn.addEventListener('click', add);
      <input type="text" id="input" />
                  <button id="btn">submit</button>

      【讨论】:

        【解决方案5】:

        我的方法是不要与浏览器对抗,不要循环太多。 首先放弃遍历 DOM 以查找父级然后尝试查找子级然后将其删除的老派方法。

        有一个简单的方法来做这个事件委托。

        您正在以任何方式动态创建节点。好工作。 只需为其添加 onclick 事件侦听器并触发 element.remove() 函数。是的,这就是新的正确方法

        在我的示例中,我将其替换为 this.parentElement.remove()因此它删除了发生事件的元素。

        一旦创建了节点并随之注册了事件,就不再是您头疼的问题了。

        创建了一个 p 元素 为 X 创建了 span 元素 P 元素的 innerHTMl 使用文本字段的值更新,之后将 span 元素添加为子元素。 然后最后将 P 元素添加到列表 div 中。 当您单击 X 时,它会删除 P 元素及其所有内容。

         <!doctype html>
            <html lang="en">
            <head>
                <meta charset="UTF-8" />
                <title>Document</title>
                <style>
                    p{
                        width: 80%;
                    }
                    .del{
                        border: 1px solid #999;
                        display: flex;
                        flex-basis: 200;
                    }
                </style>
            </head>
            <body>
                <h1>hello world</h1>
                <form action="">
                    <input type="text" id="write" />
                    <input type="button" onclick="add()" value="add" id="submit"/>
                </form>
                <div id="list"></div>
            <script>
        
            function add(){
            var mylist = document.getElementById("list");
            var p = document.createElement("P");
            var span = document.createElement("SPAN");
            span.innerHTML ='\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0'+'X'; 
        span.onclick = function () {
                this.parentElement.remove();
            }; 
            p.innerHTML = document.getElementById("write").value; 
                p.appendChild(span); 
            
            mylist.appendChild(p); 
        
            }
        
            </script>
            </body>
            </html>

        补充说明:它都是原生的,不需要库。 除了一堆 HTML 之外,没有太多笨拙的 JS 代码。保持简单,并使用浏览器的强大功能并随之增强设计。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-10
          • 2017-08-13
          • 1970-01-01
          • 2013-02-08
          • 2014-09-28
          • 1970-01-01
          • 1970-01-01
          • 2011-07-01
          相关资源
          最近更新 更多