2013-01-05 21 views
5

Onclick işlevleri olan bir div içindeki bir div üzerinde olay köpürmesini önlemek için olay dinleyicilerini kullanmak istiyorum. Bu planladığım nasıl parametreler iletme çalışır: AncakJavascript birden çok dinamik addEventListener döngü geçirmeyen parametreler için oluşturulmadı

<div onclick="doMouseClick(0, 'Dog', 'Cat');" id="button_id_0"></div> 
<div onclick="doMouseClick(1, 'Dog', 'Cat');" id="button_id_1"></div> 
<div onclick="doMouseClick(2, 'Dog', 'Cat');" id="button_id_2"></div> 

<script> 
function doMouseClick(peram1, peram2, peram3){ 
    alert("doMouseClick() called AND peram1 = "+peram1+" AND peram2 = "+peram2+" AND peram3 = "+peram3); 
} 
</script> 

, bu bir döngü içinde birden fazla olay dinleyicileri oluşturmaya çalıştık:

<div id="button_id_0"></div> 
<div id="button_id_1"></div> 
<div id="button_id_2"></div> 

<script> 
function doMouseClick(peram1, peram2, peram3){ 
    alert("doMouseClick() called AND peram1 = "+peram1+" AND peram2 = "+peram2+" AND peram3 = "+peram3); 
} 

var names = ['button_id_0', 'button_id_1', 'button_id_2']; 

    for (var i=0; i<names.length; i++){ 

     document.getElementById(names[i]).addEventListener("click", function(){ 
     doMouseClick(i, "Dog", "Cat"); 

    },false); 

} 

</script> 

O doğru her div tıklama işlevi atar ama Her biri için peram1 numaralı parametre, 3'dur. peram1 için i farklı değerlerini geçen 3 farklı olay işleyicisini bekliyordum.

neden oluyor? Olay işleyicileri ayrı değil mi?

cevap

19

Sorun i kullanmak zaten son değerdir zaman böylece olay işlevi başka kapsamını oluşturduğundan JS i düşündüğün değil blok kapsamını (yalnızca işlev kapsamı) olmadığı için, kapanışları olan for döngüsü. i değerini korumalısınız.

for (var i=0; i<names.length; i++) { 
    (function(i) { 
    // use i here 
    }(i)); 
} 

forEach Kullanılması:

bir hayattan kullanma

names.forEach(function(v,i) { 
    // i can be used anywhere in this scope 
}); 
+0

Çok teşekkür ederim:)! – KDawg

+0

Teşekkürler. Neden kapsam dışında kaldığımı ve “undefined” elemanını iade ettiğimi merak ediyordum. –

1

Her şey javascript'te global. Döngününüzden sonra 3 olarak ayarlanmış olan i değişkenini çağırıyor ... döngüden sonra i 1000 değerini ayarlarsanız, i için 1000 yöntemini her yöntem çağrısı görürsünüz.

Durumu korumak istiyorsanız, nesneleri kullanmalısınız. Nesnenin tıklama yöntemine atadığınız geri arama yöntemine sahip olmasını sağlayın.

Etkinlik bublling'i durdurmak için bu köpürmeyi yapmak için bunu yaptığınızdan bahsetmişsinizdir, dilin içine yerleştirildiği için buna gerçekten ihtiyacınız yok. Olay köpürmesini önlemek istiyorsanız, geri aramaya iletilen event nesnesinin stopPropagation() yöntemini kullanmalısınız.

function doStuff(event) { 
    //Do things 
    //stop bubbling 
    event.stopPropagation(); 
} 
+0

Teşekkür kullanacak - Diğer çözüldü benim sorunumun bir parçası. Etkinlik listesi verenin önerdiğine göre aynı köpürme problemini bıraktım - çözmeye çalışıyorum - ama buradaki cevap, köpürme problemimi de çözdü. Tekrar teşekkürler:) Adam! Bu Stackoverflow, yararlı bir insan grubudur! – KDawg

+0

"İfadeden sonra 1000'e ayarladıysanız, her bir yöntemin 1000 için üretildiğini görüyorsanız" hakkındaki yorumlarınız da "tam olarak doğruydu:") – KDawg

3

Daha önce sorun kapanışları ve değişken kapsamı ile ilgisi olduğunu işaret etti. Doğru değerin geçtiğinden emin olmanın bir yolu, istenen işlevi döndüren ve değişkenleri doğru kapsamda tutan başka bir işlev yazmaktır. jsfiddle

var names = ['button_id_0', 'button_id_1', 'button_id_2']; 

function getClickFunction(a, b, c) { 
    return function() { 
    doMouseClick(a, b, c) 
    } 
} 
for (var i = 0; i < names.length; i++) { 
    document.getElementById(names[i]).addEventListener("click", getClickFunction(i, "Dog", "Cat"), false); 
} 

Ve bunun yerine bir nesneyle bu yapabileceğini bir yolu göstermek için: biraz farklı

var names = ['button_id_0', 'button_id_1', 'button_id_2']; 

function Button(id, number) { 
    var self = this; 
    this.number = number; 
    this.element = document.getElementById(id); 
    this.click = function() { 
    alert('My number is ' + self.number); 
    } 
    this.element.addEventListener('click', this.click, false); 
} 
for (var i = 0; i < names.length; i++) { 
    new Button(names[i], i); 
} 

ya:

function Button(id, number) { 
    var element = document.getElementById(id); 
    function click() { 
    alert('My number is ' + number); 
    } 
    element.addEventListener('click', click, false); 
} 
for (var i = 0; i < names.length; i++) { 
    new Button(names[i], i); 
} 
+0

Bu çok yardımcı oldu teşekkürler. Javascript'te etkinlik dinleyicilerini kullanmaya başladığım için biraz ilerlemiştim - bunu daha fazla çalışacağım. – KDawg

-1

Çünkü kapanışları var.

Kontrol şuna: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#Creating_closures_in_loops_A_common_mistake

örnek kod ve kod "kapatma" bilmiyorum olanlar için bir hatadır, esasen aynıdır.

Basitleştirmek gerekirse, bir işleyici işlevi oluşturduğunuzda, dış ortamdan i değişkenine erişmez, aynı zamanda "hatırlar" i. işleyicisi çağrıldığında

Yani, hem de) (stopPropogation ile bana yardımcı olduğunuz için, i ama değişken i For döngüsü sonra, şimdi 2.

+1

Dış kaynaklara olan bağlantılar teşvik edilir, ancak lütfen bağlantı etrafında bir bağlam ekleyin, böylece diğer kullanıcılarınızın ne olduğu ve neden orada olduğu hakkında bir fikirleri olur. Hedef siteye ulaşılamaması veya sürekli olarak çevrimdışı olması durumunda, her zaman önemli bir bağlantının en alakalı bölümünü belirtin. [Nasıl Cevap Verilir] 'den (http://stackoverflow.com/help/how-to-answer). –

+0

@MoralesBatovski Hatırlattığınız için teşekkür ederiz. Gönderiyi yeni düzenledim. – olindk

İlgili konular