Soru Dinamik olarak oluşturulmuş öğeler üzerinde olay bağlama?


Bir sayfada tüm seçmeli kutular arasında dolaştığım ve .hover Onlara kendi genişliği ile twiddling yapmak için olay mouse on/off.

Bu sayfada hazır olur ve iyi çalışır.

Sahip olduğum sorun, ilk döngüden sonra Ajax veya DOM yoluyla eklediğim seçme kutuların etkinliğe sahip olmamasıdır.

Bu eklentiyi buldum (jQuery Canlı Sorgu Eklentisi), ancak bir eklenti ile sayfalarıma başka bir 5k eklemeden önce, kim ya doğrudan ya da başka bir seçenek ile jQuery ile bunu yapmak için bir yolu bilen var mı görmek istiyorum.


1679
2017-10-14 23:25


Menşei


Dinamik öğe için tıklama etkinliğinin nasıl bağlanacağıyla ilgili ayrıntılı bir makale goo.gl/zlEbnv - Satinder singh


Cevaplar:


JQuery 1.7'den itibaren kullanmalısın jQuery.fn.on:

$(staticAncestors).on(eventName, dynamicChild, function() {});

Bundan önce, önerilen yaklaşım kullanmaktı live():

$(selector).live( eventName, function(){} );

Ancak, live() lehine 1,7'de reddedildi on()ve tamamen 1.9'da kaldırıldı. live() imza:

$(selector).live( eventName, function(){} );

... aşağıdaki ile değiştirilebilir on() imza:

$(document).on( eventName, selector, function(){} );

Örneğin, sayfanız dinamik olarak sınıf adıyla öğeler oluşturuyorsa dosomething etkinliği bağlayacaksınız zaten var olan bir ebeveyn (Buradaki problemin özü, bağlanması gereken, dinamik içeriğe bağlanmayan bir şeye ihtiyacınız var), bu (ve en kolay seçenek) olabilir document. Aklında ayı olmasına rağmen document en verimli seçenek olmayabilir.

$(document).on('mouseover mouseout', '.dosomething', function(){
    // what you want to happen when mouseover and mouseout 
    // occurs on elements that match '.dosomething'
});

Etkinliğin o anda bağlı olduğu herhangi bir ebeveyn iyi. Örneğin

$('.buttons').on('click', 'button', function(){
    // do something here
});

için geçerli

<div class="buttons">
    <!-- <button>s that are generated dynamically and added here -->
</div>

1791
2017-08-09 09:51



Canlı yöntemin yalnızca belirli olaylar için çalıştığını ve loadmetadata gibi başkalarının çalışmadığını unutmayın. (Dokümantasyondaki uyarılar bölümüne bakın.) - Sam Dutton
Etkinlik temsilciliği hakkında daha fazla bilgiyi buradan edinebilirsiniz: learn.jquery.com/events/event-delegation. - Felix Kling
Bunu saf javascript / vanilla js ile gerçekleştirmenin herhangi bir yolu var mı? - Ram Patra
@Ramswaroop jQuery'de yapabileceğiniz her şey jQuery olmadan gerçekleştirilebilir. JQuery olmaksızın etkinlik temsilcisine iyi bir örnek - dave
@dave Cevapladığınız cevabın neden burada listelenmediğini merak ediyorum. Eli, mümkünse eklenti olmaksızın bir çözüm istemişti. - Ram Patra


Belgelerinde iyi bir açıklama var jQuery.fn.on.

Kısacası:

Olay işleyicileri yalnızca seçili olan öğelere bağlanır; kodunuzun çağrıyı yaptığı sırada sayfada bulunması gerekir .on().

Böylece aşağıdaki örnekte #dataTable tbody tr Kod oluşturulmadan önce mevcut olmalıdır.

$("#dataTable tbody tr").on("click", function(event){
    console.log($(this).text());
});

Yeni HTML sayfaya enjekte edilirse, daha sonra açıklandığı gibi bir olay işleyicisini eklemek için temsilci etkinliklerinin kullanılması tercih edilir.

Yetki verilen olaylar Sonrasında, belgeye eklenen alt öğelerden olayları daha sonra işleyebilme avantajına sahip olmaları. Örneğin, tablo varsa, ancak satırlar kod kullanılarak dinamik olarak eklenirse, aşağıdakiler işlenir:

$("#dataTable tbody").on("click", "tr", function(event){
    console.log($(this).text());
});

Henüz yaratılmamış olan elementler üzerindeki olaylarla başa çıkma becerilerine ek olarak, temsil edilen olayların bir başka avantajı, birçok unsurun izlenmesi gerektiğinde daha düşük bir ek yük potansiyeli olmasıdır. 1000 satırlık bir veri tablosunda tbodyİlk kod örneği 1000 öğeye bir işleyiciyi ekler.

Yetki verilen olaylar yaklaşımı (ikinci kod örneği) bir olay işleyicisini yalnızca bir öğeye ekler, tbodyve etkinliğin yalnızca bir seviye yukarı çıkması gerekiyor (tıklanandan) tr için tbody).

Not: Yetki verilen olaylar için çalışmaz SVG.


301
2017-12-09 07:59



Bu daha iyi kabul edilmiş bir cevap olurdu çünkü belgeden tüm yoldan ziyade belirli bir tablodan daha hızlı bir şekilde temsilci seçmek daha hızlı olurdu (arama alanı çok daha küçük olurdu) - msanjay
@msanjay: Aramayı elemanlara yakınlaştırmak tercih edilmesine rağmen, uygulamada arama / hız farkı çok azdır. Bir şey fark etmek için saniyede 50.000 kere tıklamanız gerekecek :) - Gone Coding
Bu yaklaşım, değiştirerek üst üste onay kutusu tıklamalarına işlemek için uygulanabilir mi? tr uygun bir seçiciye 'input[type=checkbox]'ve bu yeni eklenen satırlar için otomatik olarak ele alınacak mı? - JoeBrockhaus


Bu bir saf JavaScript herhangi bir kütüphane veya eklenti olmayan çözüm:

document.addEventListener('click', function (e) {
    if (hasClass(e.target, 'bu')) {
        // .bu clicked
        // Do your thing
    } else if (hasClass(e.target, 'test')) {
        // .test clicked
        // Do your other thing
    }
}, false);

nerede hasClass olduğu

function hasClass(elem, className) {
    return elem.className.split(' ').indexOf(className) > -1;
}

Canlı demo

Kredi Dave ve Sime Vidas'a gidiyor

Daha modern JS kullanmak, hasClass aşağıdaki gibi uygulanabilir:

function hasClass(elem, className) {
    return elem.classList.contains(className);
}

158
2017-10-14 23:31



stackoverflow.com/questions/9106329/... - zloctb
Kullanabilirsin Element.classList bölünmek yerine - Eugen Konkov
@EugenKonkov Element.classList eski tarayıcılarda desteklenmez. Örneğin, IE <9. - Ram Patra
JQuery yerine vanilya komut dosyasını kullanarak işlerin nasıl yapıldığına dair güzel bir yazı - toddmotto.com/... - Ram Patra
kabarcıklanma ne dersin? Tıklama etkinliği, ilgilendiğiniz öğenin alt öğesinde gerçekleştiyse ne olur? - Andreas Trantidis


Nesneleri oluştururken nesnelere ekleyebilirsiniz. Aynı olayları farklı zamanlarda birden çok nesneye ekliyorsanız, adlandırılmış bir işlev oluşturmanın yolu olabilir.

var mouseOverHandler = function() {
    // Do stuff
};
var mouseOutHandler = function () {
    // Do stuff
};

$(function() {
    // On the document load, apply to existing elements
    $('select').hover(mouseOverHandler, mouseOutHandler);
});

// This next part would be in the callback from your Ajax call
$("<select></select>")
    .append( /* Your <option>s */ )
    .hover(mouseOverHandler, mouseOutHandler)
    .appendTo( /* Wherever you need the select box */ )
;

59
2017-10-14 23:35





Etkinlik bağlama çağrınızı bir işlev haline getirebilir ve daha sonra iki kez çağırabilirsiniz: belgeye hazır olduğunda ve etkinliğinizden sonra yeni DOM öğelerini ekleyen bir kez. Bunu yaparsanız, aynı olayı varolan öğelere iki kez eklemekten kaçınmak istersiniz. Böylece, mevcut etkinlikleri ya da (daha iyi) yalnızca yeni oluşturulan DOM öğelerine bağlanmanız gerekir. Kod böyle bir şeye benziyordu:

function addCallbacks(eles){
    eles.hover(function(){alert("gotcha!")});
}

$(document).ready(function(){
    addCallbacks($(".myEles"))
});

// ... add elements ...
addCallbacks($(".myNewElements"))

40
2018-03-21 22:35



Bu yazı, aynı formu doldurduğum ve 1,2,4,8,16 ... gönderim aldığım bir soruna gerçekten kavuşmama yardımcı oldu. .Live () kullanmak yerine .load () geriçağırımında sadece .bind () kullandım. Sorun çözüldü. Teşekkürler! - Thomas McCabe


Kullanmaya çalışmak .live() yerine .bind(); .live() bağlayacak .hover Ajax isteği yürütüldükten sonra onay kutunuza.


37
2017-12-21 07:26



Yöntem live() lehine 1.7 sürümünde reddedildi on 1.9 sürümünde silinir. - chridam


Onclick olayı gibi olayları ve işleyicilere öğelerini (yeni oluşturulanları bile) bağlamak için live () yöntemini kullanabilirsiniz.

İşte yazdığım örnek kod, live () yönteminin, yeni oluşturulanları bile seçilen öğelere olaylara nasıl bağlandığını görebilirsiniz:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Untitled Document</title>
    </head>

    <body>
        <script src="http://code.jquery.com/jquery-latest.js"></script>
        <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js"></script>

        <input type="button" id="theButton" value="Click" />
        <script type="text/javascript">
            $(document).ready(function()
                {
                    $('.FOO').live("click", function (){alert("It Works!")});
                    var $dialog = $('<div></div>').html('<div id="container"><input type ="button" id="CUSTOM" value="click"/>This dialog will show every time!</div>').dialog({
                                                                                                         autoOpen: false,
                                                                                                         tite: 'Basic Dialog'
                                                                                                     });
                    $('#theButton').click(function()
                    {
                        $dialog.dialog('open');
                        return('false');
                    });
                    $('#CUSTOM').click(function(){
                        //$('#container').append('<input type="button" value="clickmee" class="FOO" /></br>');
                        var button = document.createElement("input");
                        button.setAttribute('class','FOO');
                        button.setAttribute('type','button');
                        button.setAttribute('value','CLICKMEE');
                        $('#container').append(button);
                    });
                    /* $('#FOO').click(function(){
                                                     alert("It Works!");
                                                 }); */
            });
        </script>
    </body>
</html>

21
2018-01-22 01:06



canlı kullanımdan kaldırıldı - gorgi93


Dinamik olarak oluşturulmuş öğeler üzerinde olay bağlama

Tek eleman:

$(document.body).on('click','.element', function(e) {  });

Çocuk öğesi:

 $(document.body).on('click','.element *', function(e) {  });

Ekledi dikkat edin *. Bu elemanın tüm çocukları için bir olay tetiklenecektir.

Bunu fark ettim:

$(document.body).on('click','.#element_id > element', function(e) {  });

Daha fazla çalışmıyor, ama daha önce çalışıyordu. Google'dan jQuery kullanıyorum CDNama değiştiklerini bilmiyorum.


18
2017-10-07 17:43



Yeap ve diyorlar (document.body) diyor ki atası hemen hemen her şey olabilir. - MadeInDreams