Posts Tagged ‘Events’
Posted in 'General, JavaScript' by James on April 29th, 2010
Without UI events we’d be totally lost on the client-side — it is only via User Interface Events that we can know what the user wants to do. User-initiated events such as “click”, “mouseover” and “mousemove” are absolutely essential to upholding a user-centred experience and I want to make it clear that my quarrel is not with these types of events. Any event that gives us information about users’ intentions is a good event.
I feel that there are bad events too though — events that we feel we must utilise just because they exist — and we feel we must build into our APIs just because event-driven design dictates absolute submission to this way of thinking.
DOM mutation events
Every single time I’ve ever considered using a DOM-mutation event I’ve subsequently discovered that the problem can be better solved by re-architecting the codebase. The DOM2 mutation events aren’t well supported in less capable browsers but offer an interesting opportunity — to listen for document mutation such as attribute changes, node insertion and node removal.
This sounds cool and I’m sure your mind was buzzing with ideas when you first heard about these events, but have you actually encountered a situation where utilising these events is the only viable solution? If so, I’d love to hear it.
Posted in 'JavaScript' by James on July 10th, 2009
After recently considering the impact of a native DOM implementation of two possible scroll events; “scrollstop” and “scrollstart”, I eventually came to the realisation that it would probably be a bad idea. Consider these two potential events yourself – what would initiate the “scrollstop” event? – how does the browser know when a user has stopped scrolling; it can’t just fire the event on every single step of a scroll (like the native “scroll” event)…
No, the only way to even simulate such an event would be to have a delay between the last scrolling action and the event itself – a timer could start on every “scroll” event and then if that timer is not cleared in time (say 500 milliseconds) then it can be assumed a user has “stopped scrolling”, or, has taken a break from a lengthy scroll; either circumstance warrants a “scrollstop” event in my opinion.
While we’re at it we may as well add a “scrollstart” event – this will only fire once at the start of each scrolling session.
I had always wanted a decent psuedo-event to create using jQuery’s cool “Special Events” API – when I first heard about it I wasn’t sure how I might make use of it. By the way, jQuery uses this technique to implement the non-cross-browser “mousenter” and “mouseleave” events as well as the infamous “ready” event! Here, we can use it to create our two new events, “scrollstart” and “scrollstop”.
Because of jQuery’s (relatively) simple API, creating these new events couldn’t be much easier:
Posted in 'JavaScript' by James on May 6th, 2009
As things currently stand, the vast majority of event handling between JavaScript and the DOM is somewhat primative; only involving the element being affected by the event. An example of this is a simple rollover effect:
$(elem).hover(function(){
$(this).addClass('over');
}, function(){
$(this).removeClass('over');
});
The only effect induced by the event is on the element itself. Even with something as simple as the above example there’s a lot of uneccessary bloat, all of which could be avoided by a simple abstraction; consider this plugin:
$.fn.hoverClass = function(className){
return this.hover(function(){
$(this).addClass(className);
}, function(){
$(this).removeClass(className);
});
};
// Usage:
$(elem).hoverClass('over');
While that hugely simplifies the process it doesn’t provide much scope as a plugin; it can only be used for adding and removing a class when an element is hovered over. These kind of abstractions, as far as I’m concerned, are perfectly welcome; anything that makes the end product more readable is a bonus!
On the topic of readability, a thread came up a while ago on jQuery’s development group within which the benefits of “ultra-chaining” were discussed; a term first highlighted by John Resig in a blog post back in ‘08. It’s definitely worth a read!
The resulting proposals were all of the same basic idea; provide methods to enable more seamless chaining in jQuery. Here’s an example:
// From the Dev thread:
jQuery("div").hide("slow")
.wait()
.addClass("done")
.find("span")
.addClass("done")
.end()
.show("slow")
.wait()
.removeClass("done")
As John stated in his post, this style, if adopted, would transform jQuery into a domain-specific-language, one with little or no resemblance to JavaScript as it normally exists.
Take what you will from John’s post and the enthralling discussion that followed. I for one am not too fussed either way; the syntax itself is seamless and somewhat more graceful than current techniques but, if adopted, it would fall much more hardly on the developer to ensure proper indentation, without which the readability of the code would suffer massively.
I was only really interested in one aspect of this new chaining technique; event handling. Throughout the Dev thread there were a number of similar suggestions for easier event handling in jQuery; here’s one example (proposed by Ariel Flesler):
Posted in 'Code Snippets, JavaScript' by James on March 31st, 2009
When registering event handlers in jQuery, chaining ‘mouseup’ after ‘click’ after ‘focus’ can produce, what is, in my opinion, ugly code:
$(elem)
.focus(function(){...})
.click(function(){...})
.mouseup(function(){...});
It really depends on taste; personally I’d prefer a far more intuitive interface which would enable me to specify all event handlers within a single declaration:
$(elem).events({
focus : function(){...},
click : function(){...},
mouseup : function(){...},
// Namespaced event:
'mousedown.namespace' : function(){...},
// Custom event:
exit : function(){...}
});
Made possible with a tiny plugin:
jQuery.fn.events = function(o){
for (var i in o) {
this.bind(i, o[i]);
}
return this;
};
In my opinion this offers a semantically superior means to bind event handlers in jQuery.
Posted in 'General, JavaScript, Screencasts' by James on January 12th, 2009
Last week Nettuts’ editor Jeffrey posted about a new screencast competition. This isn’t my entry – it’s just a test-runner to see if I’m any good at the whole screencast thing. It’s a 30-minute screencast about event delegation in jQuery and in it I explain event bubbling/propagation and then go on to demonstrate how to develop an event delegation plugin for jQuery.
Note: The quality isn’t too great but if you make it full screen it’s much better!
Thanks for watching, if you have any feedback I’d love to hear it! I’m planning on recording my entry for that competition soon, it’ll also be on jQuery although I’m not sure of the exact topic yet…