繁体   English   中英

使用 JavaScript 将 HTML 元素从一个列表传输到另一个列表

[英]Transfer HTML elements from one list to another with JavaScript

我对以下 JavaScript 函数有疑问。 我有两个 UL,我需要当用户点击一个 LI 时,这个元素转移到另一个 UL。

我已经设法将它们从列表中的onClick移动到另一个,当我尝试再次移动以前在另一个 UL 中的 LI 时出现问题,当发生这种情况时它就不起作用了......

    function testList() {
    usersA = document.getElementById("users-a");
    usersB = document.getElementById("users-b");
    
    for (var i=0; i < usersA.getElementsByTagName("li").length; i++) {
        usersA.getElementsByTagName("li")[i].onclick = function() {
            transfer = this.cloneNode(true);
            usersB.appendChild(transfer);
            usersA.removeChild(this);
            return false;
        }

    }
    for (var i=0; i < usersB.getElementsByTagName("li").length; i++) {          
        usersB.getElementsByTagName("li")[i].onclick = function() {
            transfer = this.cloneNode(true);
            usersA.appendChild(transfer);
            usersB.removeChild(this);
            return false;
        }

    }
    
}

我知道我的逻辑很糟糕,但这是我能想到的。 任何想法为什么它在我第一次转移 LI 时起作用,但是当我尝试移回其原始 UL 时它不起作用?

您不是在“移动”元素,而是在创建副本并删除原始元素。 尽管从用户的角度来看,这似乎是一个“移动”,但您创建的新元素没有分配点击处理程序。 来自MDN :“克隆节点会复制其所有属性及其值,但不会复制事件侦听器。”

根据MDN.appendChild()将从当前父级中删除子级,因此您不需要当前正在执行的两步克隆/删除。 我还没有测试过它,但也许只使用.appendChild()它会保留处理程序? 如果是这样,您需要删除该处理程序并分配一个新的处理程序以允许它现在属于哪个列表。

或者,重写您的处理程序,以便它们检查哪个列表是当前父级(查看.parentNode )并酌情移动到另一个列表。

请记住,单击事件从目标/源元素开始“冒泡”并向上通过父层次结构,您最好在父<ul>元素上设置单击处理程序,然后测试单击了哪个<li> 这样您就不必担心在新的子<li>元素上设置新的点击处理程序。

function testList() {
   var usersA = document.getElementById("users-a"),
       usersB = document.getElementById("users-b");

   usersA.onclick = function(e) {
      // allow for the IE and non-IE way of handling the event object
      if (!e) e = window.event;
      var el = e.target || e.srcElement;

      if (el.tagName === "li") {
         usersB.appendChild(el);
      }
   }

   usersB.onclick = function(e) {
      // allow for the IE and non-IE way of handling the event object
      if (!e) e = window.event;
      var el = e.target || e.srcElement;

      if (el.tagName === "li") {
         usersA.appendChild(el);
      }
   }
}

此外,如果您使用.getElementsByTagName()在循环初始化中调用它一次并将结果分配给一个变量,然后使用该变量 - 不要一次又一次地调用该函数来测试长度或访问个人循环内的元素:

for (var i=0, lis = usersA.getElementsByTagName("li"); i < lis.length; i++) {
    lis[i].onclick = function() {
       // etc
    }
}

问题是,即使您将元素从列表 A 移动到列表 B,它仍然保留其旧的 onclick 处理程序,该处理程序仍然显示“将我从列表 A 中删除并将我添加到列表 B”。 您需要将其 onclick 处理程序更改为“将我从列表 B 中删除并将我添加到列表 A”。 这是解决此问题的一种方法:

var usersA = document.getElementById("users-a");
var usersB = document.getElementById("users-b");

var onclickA;
var onclickB = function() {
        usersA.appendChild(this);
        this.onclick = onclickA;
        return false;
    };
onclickA = function() {
        usersB.appendChild(this);
        this.onclick = onclickB;
        return false;
    };

for (var i=0; i < usersA.getElementsByTagName("li").length; i++)
    usersA.getElementsByTagName("li")[i].onclick = onclickA;
for (var i=0; i < usersB.getElementsByTagName("li").length; i++)      
    usersB.getElementsByTagName("li")[i].onclick = onclickB;

(我也摆脱了cloneNode的东西,这正是 nnnnnn 给出的原因。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM