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

使用Javascript将HTML元素从一个列表传输到另一个列表,javascript,html,dom,javascript-events,Javascript,Html,Dom,Javascript Events,我对下面的Javascript函数有问题。我有两个UL,当用户点击一个LI时,这个元素转移到另一个UL 我已经成功地将它们从列表中的onClick移动到另一个列表中,当我再次尝试移动之前在另一个UL中的LI时,问题出现了,当这种情况发生时,它就是不起作用 function testList() { usersA = document.getElementById("users-a"); usersB = document.getElementById("users-b")

我对下面的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;
        }

    }

}
函数测试列表(){
usersA=document.getElementById(“users-a”);
usersB=document.getElementById(“users-b”);
对于(var i=0;i
我知道我的逻辑很糟糕,但这是我唯一能想到的。你知道为什么我第一次传输LI时它能工作吗?但是当我尝试移回原始UL时它不能工作?

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

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

或者,重写处理程序,以便它们检查哪个列表是当前父列表(查看一下),并根据需要移动到另一个列表

请记住,单击事件从目标/源元素开始“冒泡”,直至父继承权,您最好在父
元素上设置单击处理程序,然后测试单击了哪个
  • 。这样,您就不必担心在新的子
  • 元素上设置新的单击处理程序

    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
        }
    }
    
    for(var i=0,lis=usersA.getElementsByTagName(“li”);i
    问题在于,即使将元素从列表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;
    
    var usersA=document.getElementById(“users-a”);
    var usersB=document.getElementById(“users-b”);
    文氏变种;
    var onclickB=函数(){
    usersA.appendChild(this);
    this.onclick=onclick;
    返回false;
    };
    onclickA=函数(){
    使用某人的孩子(这个);
    this.onclick=onclickB;
    返回false;
    };
    对于(var i=0;i

    (我还去掉了
    cloneNode
    的东西,这正是nnnn给出的原因。)

    我的眼睛流血了。我的意思是为循环的每次迭代调用两次gEBTN。就像你想激怒众神一样。@Raynos:嗯?你是说我不应该修复
    cloneNode
    之类的东西吗?嘿,伙计们,谢谢你们,你们可以看到我是一个完全的新手,但这对我非常有用!