简体   繁体   中英

jQuery click functions in included files not firing

This question is kind of a duplicate, but the answer provided doesn't actually solve the issue. Here's the related question:

Why jQuery click doesn't work when included in a separate file

I've got a php template that has an overlay div I am dynamically populating with different content, depending upon which link is clicked. So for example, I have this in my template:

<a class="icon-search" href="#"></a>
<div id="overlay" class="hidden"></div>

In my global.js file, I have these functions:

$(document).ready(function(){
$("a.icon-search").click(function () {
$("#overlay").load("inc/search.php");
$("#overlay").toggleClass('show hidden');
});
$("#cancel").click(function() {
$("#overlay").toggleClass('show hidden');
});
});

The cancel button is in "inc/search.php"

When you click "icon-search", the overlay toggles properly, and the content of search.php gets loaded, but pressing the cancel button doesn't work, unless I move that function into the search.php file. I really hate doing this, because it makes the html really messy, and it makes reusing things difficult. Is there any way to overcome this issue, so that functions will work on elements that are included?

You need to use event delegation in order to have generated content fire events.

Lookup the .on() method in the jQuery documentation ( http://api.jquery.com/on/ )

Try this instead:

$(document).ready(function(){
    $("a.icon-search").click(function () {
       $("#overlay").load("inc/search.php");
       $("#overlay").toggleClass('show hidden');
    });

    $(document).on('click','#cancel',function() {
       $("#overlay").toggleClass('show hidden');
    });
});

Using .on() will delegate click events on the document to the elements with the specified selector and this will work for all current elements (which are in the DOM when this code runs) and future elements (like those which are appended using AJAX, like when you use the .load() method).

The event handlers like you are using (which I call static event handlers), must be attached directly to the DOM object they are handling events for. That means that when you run the code to attach the event handler, the DOM object you want to attach to must already exist.

If you are running this code on .ready() , but your dynamically loaded content has not yet been loaded, then no event handler will be attached because there's no DOM object yet to attach it to.

There are two general approaches to solving this type of issue:

  1. Run the code AFTER you've loaded the dynamic content (this is what putting the script into your dynamically loaded PHP content does).

  2. Switch to using delegated event handling. In delegated event handling, you attach an event handler to a parent of the dynamic content that is itself not dynamically loaded and thus it already exists. Then, when a click happens on the dynamic content, that click will "bubble" up through it's parents and encounter the click handler you have. jQuery automates a lot of this for you when using the delegated form of .on() which is of this form $("#staticParent").on("click", "#dynamicChild", fn) . You can read the details about using the delegated for of .on() in these references:

Does jQuery.on() work for elements that are added after the event handler is created?

jQuery .live() vs .on() method for adding a click event after loading dynamic html

jQuery .on does not work but .live does

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM