JQuery.on ('click') before jQuery.click?

I have an external script that I cannot change. This script loads the button and adds jQuery.click to it ... and ends with "return false".

I need to run my own code in this click. When I load the page, it does not exist, so I need to use .on ('click') to bind the "live". But it looks like .on ('click') is loading "after" .click, and when it uses "return false", my .on ('click') is not loading.

So the question is how ... How can I activate my click on this dynamically loaded # btn that already has a .click function returning false?

Here is the fiddle: http://jsfiddle.net/PLpqU/

And here is a sample code:

<div id="container"></div> 
 // I want this action to be executed on click, and the other too // I can't use .click because on the "real" code, the a#btn is loaded after the page by another script jQuery(document).on('click','a#btn',function(){ ga('send', 'event', { eventCategory: 'xxxx', eventAction: 'yyyy' }); }) ; // http://www.xxxxxx.com/distant-script.js // This one is binded in a script that i cannot edit : // Just before it load a#btn on the page, and then bind .click on it // as he return false, the other on('click') are not executed jQuery('#container').append('<a id="btn" />') ; jQuery('a#btn').click(function(){ // Some code stuff i need to be executed, but i can't manage return false ; }) ; 

As you can, the task is to trigger a Google Analytics event on the link button loaded by the remote script.

+6
source share
4 answers

It seems that you are facing a few problems, but all the more important it would be to know when an element is rendered in the DOM so that you can manipulate its collection of events.

Once an element is available, simply unbind the plugin handlers, bind them and reassign the plugin, knowing that you can access the jQuery event collection: $ ._ data (domEl, 'events');

Here is an example:

 var $div = $('<div>').click(function () { console.log('plugin'); return false; }), clickListener = jQuery._data($div[0], 'events').click[0]; //unbind all $div.off('click'); //bind yours $div.click(function () { console.log('yours'); }); //rebind the plugin one //note that I do not register the listener by honoring the same configs, //but you could since you can see them in the clickListener object $div.click(clickListener.handler); //test out everyting $div.triggerHandler('click'); 

If you don't want to unleash, I believe that you can also use the DOM level 0 event model and follow these steps:

 element.onclick = yourHandler; 

To know, to know when an element is available, is much more problematic if the plug-in renders this element asynchronously and does not provide a way to know when the process will be completed.

If you want to support older browsers, you will have no choice but to override the plugin code (provided that the appropriate methods are public) or poll the DOM with setInterval until the item you were looking for is part of the DOM, and then you can do what we talked about above.

If you use modern browsers, you can use the MutationObserver object to listen for DOM changes.

+3
source

You can cancel the event and then add your function as an event handler. http://api.jquery.com/unbind/

Check out this jsfiddle http://jsfiddle.net/Xm5MB/

 $(function(){ $("#testDiv").append("<a id='btn'>link</a>"); $("a#btn").click(function(){ alert("first bind"); }); $("a#btn").unbind("click"); $("a#btn").on("click", function(){ alert("second bind"); }); }); 
+3
source

One thing that may work is to bind the click event that you want to fire first to the child of the element that the other click event is bound to. Since the click event will start from the lowest level of the DOM to the highest level, it must fire all handlers associated with the children before they are bound to their parents.

If you want to stop another event from firing, you can manually use event.stopPropagation() or return false from the function that you linked to the child that calls both event.stopPropagation() and event.preventDefault() .

+2
source

Here is the solution provided by @plalx:

 var os = jQuery('#container') ; // the #container is written by me on the code. He empty on load and is filled by the distant script wich add the a#btn on it. if ( os.length > 0 ) // I just check if he is on my page, just in case. { var timer = setInterval(function () { var btn_os = jQuery('a#btn') ; if (btn_os.length) // Button is loaded on page : we can do the trick { clickListener = jQuery._data(btn_os[0], 'events').click[0]; // caching the first .click bind btn_os.off('click'); // Removing all binds // Adding my own bind btn_os.click(function () { console.log('test') ; ga('send', 'event', { eventCategory: 'xxxx', eventAction: 'yyyy', eventLabel : 'zzzz' }); // You can either trigger here the previous handler or rebind it out of here, 6 lines bottom // In my case i prefer to trigger it myself, with a little delay to make sure that my ga('send') has time to register setTimeout(function(){clickListener.handler() ;}, 150); }); // And rebinding the old one if needed // In my particular case i don't want to rebind it, i prefer triggering it manually on my .click function with a setTimeout delay // btn_os.click(clickListener.handler); clearInterval(timer) ; // Removing the interval timer } } , 100); } 
0
source

All Articles