Distinguishing real events from simulated events
Simulated events are one of the real joys of jQuery. Geniusly, to simulate an event in jQuery you simply call the method relating to the event in question (or use the trigger() method) without any arguments.
1//set up the event
2$('#tabs').on(''click', 'li', function() {
3 alert('Hello!');
4});
5
6//simulate the event immediately on the first LI
7$('#tabs li:first').click();
This is a common situation. Here, I have some tabs which, when clicked, show a corresponding tab content area, which are all hidden to start with. By simulating the event on the first tab, it is automatically turned on as though we had clicked it ourselves.
(Yes, I could avoid this by having the first tab area showing by default via CSS, but let's imagine our event handler does more than simply show and hide DIVs, but also some more complex code).
So far, so easy, and so common. But how do you differentiate a simulated event from a real one?
I had a situation the other day where I had a carousel-like widget on the page, and a bigger version of the same carousel, hidden, to appear in a lightbox should the user wish. Traversing one of the carousels (i.e. changing slide) should update the other one, too.
Consider the following.
1var carousels = $('.carousel');
2
3//listen for clicks to carousel left & right buttons
4carousels.on('click', 'button', function(evt) {
5
6 //get this carousel, other carousel and click direction
7 var this_carousel = $(this).closest('.carousel'),
8 other_carousel = carousels[$(this).is('#carousel1') ? 'first' : 'last'](),
9 direction = $(this).is('.left') ? 'left' : 'right';
10
11 //simulate the same click on the other carousel
12 other_carousel.find('button.'+click_direction).click();
13
14 //more code here...
15
16});
There, we listen for clicks to the left/right buttons of each carousel and then simulate the same click on the other carousel.
But there's an obvious problem; the simulated click uses the same event handler, so it too will invoke a simulated click on the first carousel, and so on and so on, without end.
What we actually want, of course, is for a simulated click to occur only in response to a real click. In other words, how do we spot the difference between a real and simulated event with jQuery?
Simple: with a simulated event, the originalEvent property of the event object will be undefined, whereas with a real event it will be the native event object.
1$('#tabs').on('click', 'li', function(evt) {
2 if (evt.originalEvent) {
3 //real event
4 } else {
5 //simulated event
6 }
7});
Obviously you don't have to simulate events - you could assign their callbacks to a named function and call the function manually. But then you'd have no event object passed, so this often means filling your code with lots of conditions - to work both as an event callback and as a direct function call. Simulated event calls save the need for this reengineering.
Comments (0)