jQuery.click之前的jQuery.on(’click’)?

我有一个外部脚本,我无法修改。 这个脚本加载一个按钮,并在其上添加一个jQuery .click …它以“return false”结束。

我需要在这次点击时触发我自己的代码。 当我加载页面时,不存在,所以我需要使用.on(’click’)来绑定“live”。 但看起来.on(’click’)在“.click之后”加载,并且当他使用“return false”时,我的.on(’click’)没有被加载。

所以问题是……如何触发我点击这个动态加载的#btn已经有一个.click函数返回false?

这是小提琴: http : //jsfiddle.net/PLpqU/

这里有一个代码示例:

 // 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('') ; jQuery('a#btn').click(function(){ // Some code stuff i need to be executed, but i can't manage return false ; }) ; 

尽可能地,目标是在由远程脚本加载的链接按钮上触发Google Analytics事件。

您似乎面临着多个问题,但更重要的是知道何时在DOM中呈现元素,以便您可以操纵它的事件集合。

一旦元素可访问,取消绑定插件的处理程序,绑定你的并重新绑定插件就知道jQuery的事件集合可以被访问,如:$ ._ data(domEl,’events’);

这是一个例子:

 var $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's 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');

如果您不想解除绑定,我相信您也可以使用DOM 0级事件模型并执行:

 element.onclick = yourHandler; 

知道,如果插件以异步方式呈现此元素并且不提供了解过程何时完成的方法,那么知道元素何时可用是更多问题。

如果你想支持旧的浏览器,除了覆盖插件的代码(假设有关的方法是公共的)或者用setInterval轮询DOM,直到你要查找的元素是DOM的一部分然后你可以做我们上面讨论过的事情。

如果您要定位现代浏览器,则可以使用MutationObserver对象来侦听DOM更改。

您可以解除绑定事件,然后将您的函数添加为事件处理程序。 http://api.jquery.com/unbind/

检查这个jsfiddle http://jsfiddle.net/Xm5MB/

 $(function(){ $("#testDiv").append("link"); $("a#btn").click(function(){ alert("first bind"); }); $("a#btn").unbind("click"); $("a#btn").on("click", function(){ alert("second bind"); }); }); 

可能有用的一件事是将您要首先触发的click事件绑定到另一个click事件绑定到的元素的子节点。 由于click事件将从DOM的最低级别冒泡到最高级别,因此它应该在绑定到其父级之前绑定到子级的任何处理程序。

如果要阻止其他事件触发,可以手动使用event.stopPropagation()或者从绑定到子event.stopPropagation()的函数返回false ,该函数调用event.stopPropagation()event.preventDefault()

这是@plalx提供的解决方案:

 var os = jQuery('#container') ; // the #container is written by me on the code. He's 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); }