2011-11-13 148 views
0

我對以下Javascript函數有問題。我有兩個UL,當用戶點擊一個LI時,我需要這個元素,這個元素轉移到另一個UL。使用Javascript將HTML元素從一個列表傳輸到另一個列表

我已經設法將它們從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

我的眼睛,他們流血。我的意思是在循環的每次迭代中調用gEBTN兩次。這就像你想憤怒的神。 – Raynos

回答

0

的問題是,你從列表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給出的原因)

+0

-1用於修復一小部分代碼。 – Raynos

+0

@Raynos:恩?你是說我不應該修復'cloneNode'的東西嗎? – ruakh

+0

嘿夥計們,非常感謝,因爲你可以看到我是一個全新的人,但這對我來說非常有用! –

3

您不是「移動」元素,而是創建副本並刪除原件。儘管從用戶的角度來看這看起來像是一個「移動」,但您創建的新元素沒有分配處理程序。從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 
    } 
} 
相關問題