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

时间:2011-11-13 23:44:50

标签: javascript html dom javascript-events

我遇到以下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它不起作用?

2 个答案:

答案 0 :(得分:4)

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

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

或者,重写处理程序,以便他们检查哪个列表是当前父级(查看.parentNode)并根据需要移至其他列表。

请记住点击事件从目标/源元素开始“冒泡”并向上通过父级别,你可能最好在父<ul>元素上设置点击处理程序,然后测试哪个{点击了{1}}。这样您就不必担心在新的子<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()

答案 1 :(得分:2)

问题是,即使你已经将一个元素从列表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给出的原因。)