I'm using jQuery to bind to all links on the page (I'm using the 'click' event, but have tried various binations of 'mousedown' and 'mouseup',together with bind() and live() to no avail).
I can intercept the click no problem (with all the above methods). What I am trying to do is send some data via a GET request, and when it pletes, allow the default click action to proceed.
Since I am municating across-domain, I must use GET rather than POST, and so cannot make a synchronous call.
Therefore I have to return 'false' from the intercepted click event, store the event for later, then manually fire it again once the munication has pleted. If I return true, the munication gets cut off mid-way as the page location changes.
The problem is, I can't find a way to fire the native click event later on.
var storedEvent;
$("#wrapper a").bind('click', function(event, processed) {
$(event.target).unbind('click'); // temporary to make code branching easier
storedEvent = event.target;
event.stopPropagation();
$.ajax({
dataType: 'jsonp',
data: linkData,
jsonp: 'cb',
url: 'xxx',
cache: false,
plete: function(response) {
// How do I now go back and fire the native click event here?
$(storedEvent).click();
}
});
return false;
}
I've tried using click()
and trigger()
where indicated, but neither worked.
I know the submission is succeeding, and the code is branching correctly -- I have debugged that far. I just don't seem to be able to replay the event.
Note that I can't do something simple, like store the href and set window.location later -- some of the links have their own onClicks
set, while others have various targets specified. I'd ideally like to just replay the event I stopped earlier.
I started off using event delegation with live()
and had everything working, apart from this -- I have simplified it down to a bind()
in order to simplify the problem.
I'm using jQuery to bind to all links on the page (I'm using the 'click' event, but have tried various binations of 'mousedown' and 'mouseup',together with bind() and live() to no avail).
I can intercept the click no problem (with all the above methods). What I am trying to do is send some data via a GET request, and when it pletes, allow the default click action to proceed.
Since I am municating across-domain, I must use GET rather than POST, and so cannot make a synchronous call.
Therefore I have to return 'false' from the intercepted click event, store the event for later, then manually fire it again once the munication has pleted. If I return true, the munication gets cut off mid-way as the page location changes.
The problem is, I can't find a way to fire the native click event later on.
var storedEvent;
$("#wrapper a").bind('click', function(event, processed) {
$(event.target).unbind('click'); // temporary to make code branching easier
storedEvent = event.target;
event.stopPropagation();
$.ajax({
dataType: 'jsonp',
data: linkData,
jsonp: 'cb',
url: 'xxx',
cache: false,
plete: function(response) {
// How do I now go back and fire the native click event here?
$(storedEvent).click();
}
});
return false;
}
I've tried using click()
and trigger()
where indicated, but neither worked.
I know the submission is succeeding, and the code is branching correctly -- I have debugged that far. I just don't seem to be able to replay the event.
Note that I can't do something simple, like store the href and set window.location later -- some of the links have their own onClicks
set, while others have various targets specified. I'd ideally like to just replay the event I stopped earlier.
I started off using event delegation with live()
and had everything working, apart from this -- I have simplified it down to a bind()
in order to simplify the problem.
- 1 What does the original click event look like? Is that different for everything? – spinon Commented Jul 19, 2010 at 3:58
- Sometimes it is a specific onclick, sometimes a bound click (e.g. for thickbox/colorbox), sometimes no event -- just a link, but can have various targets (e.g. _top). I managed to get native JavScript dispatchEvent working in firefox -- but I need it to work in IE. Do I have to inspect the element and manually figure out whether to trigger a bound event, or set the (target).location? – Jhong Commented Jul 19, 2010 at 4:08
- I believe you would have to work it out yourself yes – redsquare Commented Jul 19, 2010 at 4:18
3 Answers
Reset to default 2Up-to-date answer: yes, you can (assuming you no longer support IE8).
Use dispatchEvent() to fire a copy of the original event.
First you need an utility function to clone the event (as browsers only allow events to be dispatched once, for security reasons):
var cloneNativeMouseEvent = function (original) {
var copy;
try {
copy = new MouseEvent(original.type, original);
} catch (stupidInternetExplorer) {
copy = document.createEvent('MouseEvent');
copy.initMouseEvent(original.type, original.bubbles, original.cancelable, original.view,
original.detail, original.screenX, original.screenY, original.clientX, original.clientY,
original.ctrlKey, original.altKey, original.shiftKey, original.metaKey, original.button,
original.relatedTarget)
}
return copy;
};
In your click handler store a reference to the jQuery event for later replay:
$("#wrapper a").bind('click', function (event) {
event.preventDefault();
storedEvent = event;
...
}
And finally, in the callback where you want to trigger the click again, do it as follows:
var originalEventClone = cloneNativeMouseEvent(storedEvent.originalEvent);
storedEvent.target.dispatchEvent(originalEventClone);
Please note that, in general, events created or modified by JavaScript are marked as "not trusted" by user agents so they can't trigger default actions. Luckily click events are the only exception. (1)
You cannot trigger a click event on an anchor and get it to follow the href cross browser.
It turns out redsquare is basically correct -- it doesn't work without tearing your hair out.
IE is the problem. dispatchEvent() works fine in FireFox. In IE, you can choose fireEvent to fire any associated events (but not the click), or click() (for clicks but not events), but you can't do both properly.
I got it "almost working" by temporarily changing links' hrefs and targets so that they loaded a blank page in an iframe. I then listened for iframe "load" events to determine if the link's default action had taken place. In IE I could then fire "click" if needed, or "fireEvent" otherwise, after changing the href and target back.
However, it was too much of a hack -- what if one of the links has a bound event that relied on the href attribute being there? (thickbox seemed to carry on working, but I expect it was a race condition).
In the end I didn't need to do it at all anyway ( JavaScript/jQuery: How to make sure cross-domain click tracking event succeeds before the user leaves the page? ), so I am relieved. It turns out that I had to use POST in this case.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745451898a4628309.html
评论列表(0条)