Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
439 views
in Technique[技术] by (71.8m points)

jquery - How do you force your Javascript event to run first, regardless of the order in which the events were added?

I have Javascript that people are including in their page. In my Javascript I have a version of jQuery (1.8 for sake of easy reference) that is sectioned off into its own namespace, and referenced via a global variable (but not one of the two default vars of "$" or "jQuery"). This allows users to have jQuery in their page and have it not interfere with the stuff I'm doing internally in my functions.

So we have one page that has jQuery already (1.4), and everything works fine, except that the user and my code are both listening to "click" events on elements, and theirs is going first, so on the few events they do that return false, jQuery stops propagation and my event never gets triggered. I need my event to go first. The user is expecting my onClick functionality to still work.

Now I know that jQuery keeps its own order of events internally through the _data() object, and through this it is possible to unbind existing events, bind my event, then rebind the existing events, but that only applies to objects bound through that instance of jQuery. I'd rather not just blindly look for the jQuery object in hopes that the conflict was introduced by a user's own version of jQuery. After all what happens when a user binds the event not through jQuery? Trying to manipulate the existing jQuery object in the page isn't a good solution.

I know that, depending on browser, they are using addEventListener/removeEventListener or attachEvent/detachEvent. If only I could get a listing of the already added events, I could rebind them in the order I wanted, but I can't find out how. Looking through the DOM via Chrome inspect I don't see onclick bound anywhere (not on the object, not on window or document either).

I'm having the darndest time trying to figure out just exactly where jQuery binds its listening. To be able to control the order of its own events, jQuery must blanketly listen somewhere and then fire off its own functions right? If I could figure out where that's done I might get some insight into how to ensure my event is always first. Or maybe there's some Javascript API I haven't been able to find on Google.

Any suggestions?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

We solved this by just adding a little jQuery extension that inserts events at the head of the event chain:

$.fn.bindFirst = function(name, fn) {
  var elem, handlers, i, _len;
  this.bind(name, fn);
  for (i = 0, _len = this.length; i < _len; i++) {
    elem = this[i];
    handlers = jQuery._data(elem).events[name.split('.')[0]];
    handlers.unshift(handlers.pop());
  }
};

Then, to bind your event:

$(".foo").bindFirst("click", function() { /* Your handler */ });

Easy peasy!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...