سؤال

لدي قليلا من التعليمات البرمجية حيث أنا حلقات من خلال جميع حدد مربعات على صفحة ملزمة .hover الحدث عليها أن تفعل قليلا من twiddling مع العرض على mouse on/off.

يحدث هذا في الصفحة جاهزة و يعمل على ما يرام.

المشكلة لدي هو أن أي حدد مربعات إضافة عبر Ajax أو دوم بعد الأولي حلقة لن يكون الحدث ملزمة.

لقد وجدت هذا البرنامج المساعد (مسج يعيش الاستعلام المساعد) ، ولكن قبل إضافة آخر 5k إلى صفحات مع البرنامج المساعد, أريد أن أرى إذا كان أي شخص يعرف طريقة للقيام بذلك ، إما مع مسج مباشرة أو عن طريق خيار آخر.

هل كانت مفيدة؟

المحلول

كما مسج 1.7 يجب عليك استخدام jQuery.fn.on:

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

قبل هذا, فإن النهج الموصى به هو استخدام live():

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

ومع ذلك ، live() تم إهمال 1.7 لصالح on(), و إزالتها تماما في 1.9.على live() التوقيع:

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

...يمكن استبدال التالية on() التوقيع:

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

على سبيل المثال ، إذا كانت الصفحة الخاصة بك هو خلق حيوي العناصر مع اسم الفئة dosomething يمكنك ربط الحدث الأم التي موجود بالفعل (هذا هو لب المشكلة هنا, كنت بحاجة إلى شيء موجود لربط لا ربط المحتوى الديناميكي) ، يمكن أن يكون هذا (و الخيار الأسهل) ، document.على الرغم من أن نضع في اعتبارنا document قد لا يكون الخيار الأكثر كفاءة.

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

أي الأصل موجود وقت الحدث لا بد ما يرام.على سبيل المثال

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

تنطبق على

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

نصائح أخرى

هناك تفسير جيد في وثائق jQuery.fn.on.

باختصار:

معالجات الأحداث هي ملزمة فقط حاليا اختيار العناصر ؛ يجب أن توجد على الصفحة في وقت الكود يجعل الدعوة إلى .on().

وهكذا في المثال التالي #dataTable tbody tr يجب أن يكون موجودا قبل أن يتم إنشاء التعليمات البرمجية.

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

إذا HTML جديد يتم حقنها في الصفحة ، فمن الأفضل استخدام تفويض الأحداث إرفاق معالج الحدث ، كما هو موضح المقبل.

تفويض الأحداث لديها ميزة أنها يمكن معالجة الأحداث من سليل العناصر التي تضاف إلى الوثيقة في وقت لاحق.على سبيل المثال ، إذا كان الجدول موجودا ، ولكن يتم إضافة صفوف حيوي باستخدام التعليمات البرمجية التالية سيتم التعامل معها:

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

بالإضافة إلى قدرتها على التعامل مع الأحداث على سليل العناصر التي لم يتم بعد إنشاء ميزة أخرى من تفويض الأحداث هو احتمال أقل بكثير من النفقات العامة عند العديد من العناصر يجب أن يتم رصدها.على جدول البيانات مع 1000 الصفوف في tbody, أول رمز المثال تعلق معالج 1000 العناصر.

وهو تفويض-الأحداث النهج (الثانية المثال التعليمات البرمجية) تعلق معالج الحدث إلى عنصر واحد فقط ، tbody, و الحدث يحتاج فقط إلى فقاعة يصل مستوى واحد (من النقر tr إلى tbody).

ملاحظة: تفويض الأحداث لا تعمل SVG.

هذا هو نقية جافا سكريبت الحل دون أي المكتبات أو الإضافات:

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);

حيث hasClass هو

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

يعيش التجريبي

الفضل يعود إلى ديف و سايم Vidas

باستخدام أكثر حداثة شبيبة ، hasClass يمكن تنفيذها:

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

ويمكنك إضافة أحداث إلى كائنات عند إنشائها. إذا كنت تقوم بإضافة نفس الأحداث إلى كائنات متعددة في أوقات مختلفة، وخلق وظيفة اسمه قد يكون أفضل طريقة للذهاب.

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 */ )
;

هل يمكن ببساطة التفاف الحدث الخاص بك ملزمة استدعاء إلى وظيفة ومن ثم استدعاء مرتين:مرة واحدة على الوثيقة جاهزة و مرة بعد الحدث الخاص بك أن يضيف الجديد عناصر DOM.إذا كنت تفعل ذلك سوف تحتاج إلى تجنب ملزمة نفس الحدث مرتين على العناصر الموجودة لذلك سوف تحتاج إما إلغاء توثيق الأحداث الحالية أو (الأفضل) فقط ربط عناصر DOM التي تم إنشاؤها حديثا.رمز ننظر بشيء من هذا القبيل:

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

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

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

وحاول استخدام .live() بدلا من .bind(). سوف .live() ربط .hover إلى مربع بك بعد تنفيذ طلب اياكس.

يمكنك استخدام الأسلوب المباشر () لربط العناصر (حتى أنشئت حديثا منها) للأحداث ومعالجات، مثل الحدث onclick.

وهنا هو رمز عينة كنت قد كتبت، حيث يمكنك أن ترى كيف يربط طريقة العيش () عناصر المختار، حتى تم إنشاؤها حديثا منها، إلى الأحداث:

<!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>

الحدث ملزمة إنشاؤه بشكل حيوي العناصر

عنصر واحد:

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

عنصر الطفل:

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

إشعار إضافة *.الحدث سيتم تشغيل جميع الأطفال من هذا العنصر.

وقد لاحظت أن:

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

فمن لا يعمل أي أكثر من ذلك ، لكنه كان يعمل من قبل.لقد تم استخدام مسج من جوجل CDN, ولكن أنا لا أعرف ما إذا كانت تغييره.

وهناك حل آخر هو إضافة المستمع عند إنشاء عنصر. بدلا من وضع المستمع في الجسم، ويمكنك وضع المستمع في العنصر في لحظة أن خلق لكم ما يلي:

var myElement = $('<button/>', {
    text: 'Go to Google!'
});

myElement.bind( 'click', goToGoogle);
myElement.append('body');


function goToGoogle(event){
    window.location.replace("http://www.google.com");
}

وانا افضل استخدام محدد وأنا تطبيقه على الوثيقة.

وهذا يربط نفسه على الوثيقة، وسوف تكون قابلة للتطبيق على العناصر التي سيتم تقديم بعد تحميل الصفحة.

وعلى سبيل المثال:

$(document).on("click", $(selector), function() {
    // Your code here
});

ويتم وضع العنصر، على سبيل المثال يحيط علما الطبقة "MAIN"،

<div class="container">
     <ul class="select">
         <li> First</li>
         <li>Second</li>
    </ul>
</div>

في السيناريو أعلاه، فإن الهدف الرئيسي سوف مسج مشاهدة هو "حاوية".

وبعد ذلك سيكون لديك أساسا عناصر أسماء ضمن حاوية مثل ul، li، وselect:

$(document).ready(function(e) {
    $('.container').on( 'click',".select", function(e) {
        alert("CLICKED");
    });
 });

ويمكنك إرفاق الحدث لعنصر عند إنشاؤه بشكل حيوي باستخدام jQuery(html, attributes) .

<اقتباس فقرة>   

<القوي> اعتبارا من مسج 1.8 ، أو أي أسلوب مثيل مسج (وسيلة لjQuery.fn) يمكن استخدام خاصية الكائن الذي تم تمريره إلى   المعلمة الثانية:

function handleDynamicElementEvent(event) {
  console.log(event.type, this.value)
}
// create and attach event to dynamic element
jQuery("<select>", {
    html: $.map(Array(3), function(_, index) {
      return new Option(index, index)
    }),
    on: {
      change: handleDynamicElementEvent
    }
  })
  .appendTo("body");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>

هل يمكن استخدام

$('.buttons').on('click', 'button', function(){
    // your magic goes here
});

أو

$('.buttons').delegate('button', 'click', function() {
    // your magic goes here
});

وهاتين الطريقتين تعادل ولكن لها ترتيب مختلفة من المعلمات.

وراجع: مسج مندوب حدث

وهنا هو لماذا عناصر إنشاؤه بشكل حيوي لا تستجيب لنقرات:

var body = $("body");
var btns = $("button");
var btnB = $("<button>B</button>");
// `<button>B</button>` is not yet in the document.
// Thus, `$("button")` gives `[<button>A</button>]`.
// Only `<button>A</button>` gets a click listener.
btns.on("click", function () {
  console.log(this);
});
// Too late for `<button>B</button>`...
body.append(btnB);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>

وكحل مؤقت، لديك للاستماع إلى كل النقرات وتحقق عنصر مصدر:

var body = $("body");
var btnB = $("<button>B</button>");
var btnC = $("<button>C</button>");
// Listen to all clicks and
// check if the source element
// is a `<button></button>`.
body.on("click", function (ev) {
  if ($(ev.target).is("button")) {
    console.log(ev.target);
  }
});
// Now you can add any number
// of `<button></button>`.
body.append(btnB);
body.append(btnC);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>

وهذا ما يسمى "وفد الحدث". الخبر السار، انها ميزة مدمج في مسج: -)

var i = 11;
var body = $("body");
body.on("click", "button", function () {
  var letter = (i++).toString(36).toUpperCase();
  body.append($("<button>" + letter + "</button>"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>

أي pتخلخل موجود في وقت الحدث لا بد و إذا كان الخاص بك الصفحة بشكل حيوي إنشاء عناصر مع اسم الفئة زر يمكنك ربط هذا الحدث إلى الأصل وهو موجود بالفعل

$(document).ready(function(){
  //Particular Parent chield click
  $(".buttons").on("click","button",function(){
    alert("Clicked");
  });  
  
  //Dynamic event bind on button class  
  $(document).on("click",".button",function(){
    alert("Dymamic Clicked");
  });
  $("input").addClass("button");  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="buttons">
  <input type="button" value="1">
  <button>2</button>
  <input type="text">
  <button>3</button>  
  <input type="button" value="5">  
  </div>
<button>6</button>

وحاول مثل هذا -

$(document).on( 'click', '.click-activity', function () { ... });

ويتم ذلك من خلال الحدث وفد.الحدث سيتم ربط على المجمع الدرجة عنصر ولكن سيتم تفويض محدد من الدرجة عنصر.هذا هو كيف يعمل.

$('.wrapper-class').on("click", '.selector-class', function() {
    // Your code here
});

ملاحظة:

المجمع الدرجة عنصر يمكن أن يكون أي شيء السابقين.الوثيقة أو هيئة أو المجمع الخاص بك. المجمع يجب موجودة.ومع ذلك ، selector لا تحتاج بالضرورة أن تكون موجودة في وقت تحميل الصفحة.قد تأتي في وقت لاحق وسوف الحدث ربط على selector دون أن تفشل.

استخدم طريقة .on() من مسج http://api.jquery.com/on/ لإرفاق معالجات الأحداث للعيش العنصر.

وأيضا اعتبارا من النسخة تتم إزالة 1.9 طريقة .live().

وربط هذا الحدث لأحد الوالدين الذي موجود بالفعل:

$(document).on("click", "selector", function() {
    // Your code here
});

وأنا أفضل أن يكون المستمعين الحدث نشرها في وظيفة الأزياء وحدات بدلا من البرمجة مستمع الحدث مستوى document. لذا، أنا لا أحب أدناه. ملاحظة، لا يمكنك oversubscribe عنصر مع نفس المستمع الحدث حتى لا تقلق بشأن ربط المستمع أكثر من مرة واحدة - واحد فقط العصي

var iterations = 4;
var button;
var body = document.querySelector("body");

for (var i = 0; i < iterations; i++) {
    button = document.createElement("button");
    button.classList.add("my-button");
    button.appendChild(document.createTextNode(i));
    button.addEventListener("click", myButtonWasClicked);
    body.appendChild(button);
}

function myButtonWasClicked(e) {
    console.log(e.target); //access to this specific button
}

آخر حلول مرنة لإنشاء عناصر ربط الأحداث (المصدر)

// creating a dynamic element (container div)
var $div = $("<div>", {id: 'myid1', class: 'myclass'});

//creating a dynamic button
 var $btn = $("<button>", { type: 'button', text: 'Click me', class: 'btn' });

// binding the event
 $btn.click(function () { //for mouseover--> $btn.on('mouseover', function () {
    console.log('clicked');
 });

// append dynamic button to the dynamic container
$div.append($btn);

// add the dynamically created element(s) to a static element
$("#box").append($div);

ملاحظة: هذا سوف إنشاء معالج الحدث سبيل المثال لكل عنصر (قد تؤثر على الأداء عند استخدامها في الحلقات)

<html>
    <head>
        <title>HTML Document</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
    </head>

    <body>
        <div id="hover-id">
            Hello World
        </div>

        <script>
            jQuery(document).ready(function($){
                $(document).on('mouseover', '#hover-id', function(){
                    $(this).css('color','yellowgreen');
                });

                $(document).on('mouseout', '#hover-id', function(){
                    $(this).css('color','black');
                });
            });
        </script>
    </body>
</html>

وكنت أبحث عن حل للحصول على $.bind و$.unbind العمل دون مشاكل في العناصر إضافتها بشكل حيوي.

على () يجعل خدعة إرفاق الأحداث، من أجل إنشاء UNBIND وهمية على تلك جئت إلى:

const sendAction = function(e){ ... }
// bind the click
$('body').on('click', 'button.send', sendAction );

// unbind the click
$('body').on('click', 'button.send', function(){} );
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top