2011-11-13 4 views
0

次のJavascript機能に問題があります。私は2つのULを持っており、ユーザーがLIをクリックすると、この要素は他のULに転送される必要があります。Javascriptを使用してHTML要素を別のリストに転送する

私はそれらをリスト上から別のものに移動することができましたが、以前に他の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をループの繰り返しごとに2回呼び出すことを意味します。それはあなたが神々を怒らせたいと思うようなものです。 – Raynos

答えて

0

問題は、あなたがリストBにリストAから要素を移動した後でも、それはまだ、まだ、「削除言う古いのonclickハンドラを、保持していることです私はリストAから私をリストBに追加します。 "あなたは "リストBから私を削除し、リストAに私を追加する"と言うためにonclickハンドラを変更する必要があります。ここではそれを修正する一つの方法です:

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; 

(。私も与えNNNNNN正確な理由から、cloneNodeものを処分した)

+0

-1はコードの一部を修正するためのものです。 – Raynos

+0

@レイノス:え?あなたは 'cloneNode'ものを修正してはならないと言っていますか? – ruakh

+0

お元気ですか、ありがとうございます、あなたが見ることができるように、私は初心者ですが、これは私にとって非常に便利です! –

3

あなたは要素を「移動」していないので、コピーを作成して元のファイルを削除しています。これはユーザーの視点から見ると「移動」のように見えますが、作成する新しい要素にはクリックハンドラが割り当てられていません。 MDNから: "ノードを複製すると、すべての属性とその値がコピーされますが、イベントリスナーはコピーされません。

MDNによれば、.appendChild()は現在の親から子を削除しますので、現在実行している2段階のクローン/削除は必要ありません。私はそれをテストしていないが、おそらくちょうど.appendChild()を使用して、それはハンドラを保つだろうか?そうであれば、そのハンドラを削除し、新しいハンドラを割り当てて、それが現在属するリストを許可する必要があります。

または、現在の親のリスト(.parentNodeを見てください)をチェックし、他のリストに移動するようにハンドラを書き換えます。ターゲット/ソース要素から始まり、アップあなたはおそらく<li>がクリックされた親<ul>要素その後、テストにあなたのクリックハンドラを設定する方がいいでしょう階層構造の親でイベント「バブルアップ」をクリック念頭に

ベアリング。そうすれば、新しい子の<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 
    } 
} 
関連する問題