Treehouse

Adding Events to Adding Events in jQuery

By on  

Earlier this week I posted a usability tip about using CSS and MooTools' custom event functionality to automatically add the "pointer" cursor when an element gets a "click" event attached to it. I received numerous requests for a jQuery version and I think I've figured out how to replicate the functionality.

The jQuery JavaScript FAIL

/* create custom event */
jQuery.event.special.click = {
	 setup: function() {
		  $(this).css('cursor','pointer');
	 },
	 teardown: function(namespaces) {
		  $(this).css('cursor','');
	 }
};
/* usage; nothing different than usual*/
$(document).ready(function() {
	$('#click-me').click(function() {
		var col = 'rgb(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ')';
		$(this).css('background',col);
	});
});

I use the special event object to add a custom event named click. When the event is added, the setup method changes the element's cursor to pointer. If we were to remove that event, the pointer cursor would be removed. The problem with the above code is that it appears to override the default click event and when you actually click on the element, nothing happens. Damn!

The jQuery JavaScript "Success"

/* listen for hover/click */
$(document).ready(function() {
	/* attempt fix */
	$('*').each(function() {
		$(this).mouseover(function() {
				if(jQuery.data(this,'events').click) {
					$(this).css('cursor','pointer');
				}
		});
	});
	/* usage? */
	$('#click-me').click(function() {
		var col = 'rgb(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ')';
		$('#click-me').css('background',col);
	});
});

The only way I could get this to work without modifying the jQuery core is to place a mouseenter event on each element in the DOM that checked to see if a click event was present for the given element. If so, show the cursor pointer. This is an ugly method to achieve the goal but the only one I found. If an element were to be added to the DOM dynamically, the above wouldn't work.

UPDATE: The jQuery JavaScript Solution

jQuery.event.special.click = {
    setup: function() {
        $(this).css('cursor','pointer');
        return false;
    },
    teardown: fuction() {
        $(this).css('cursor','');
        return false;
    }
};

Brandon Aaron and Scott Kyle blessed us with the solution; it looks like I was very close. Adding return false; would have done it.

Thank you to Brandon and Scott for helping me out!

ydkjs-3.png

Recent Features

  • Create Namespaced Classes with MooTools

    MooTools has always gotten a bit of grief for not inherently using and standardizing namespaced-based JavaScript classes like the Dojo Toolkit does.  Many developers create their classes as globals which is generally frowned up.  I mostly disagree with that stance, but each to their own.  In any event,...

  • 6 Things You Didn’t Know About Firefox OS

    Firefox OS is all over the tech news and for good reason:  Mozilla's finally given web developers the platform that they need to create apps the way they've been creating them for years -- with CSS, HTML, and JavaScript.  Firefox OS has been rapidly improving,...

Incredible Demos

  • CSS Kwicks

    One of the effects that made me excited about client side and JavaScript was the Kwicks effect.  Take a list of items and react to them accordingly when hovered.  Simple, sweet.  The effect was originally created with JavaScript but come five years later, our...

  • jQuery topLink Plugin

    Last week I released a snippet of code for MooTools that allowed you to fade in and out a "to the top" link on any page. Here's how to implement that functionality using jQuery. The XHTML <a href="#top" id="top-link">Top of Page</a> A simple link. The CSS #top-link{ display:none; position:fixed; right:5px;...

Discussion

  1. It’s great. It will be a gain of time ! I don’t see how I could do that in an other way.

  2. Your “FAIL” method will work just fine if you return false from both the setup and teardown functions. Also, just a note to readers, you should use “jQuery” rather than a $ in production code, or $ in a closure (my preferred method).

  3. Hey David,

    I decided to respond via a blog post of my own on this topic. As Scott mentioned the Special Event hooks must return false in order to make this work. Hopefully my blog post clears this up.

  4. Thank you Brandon — I commented on your blog.

  5. A very good idea David! :)

    I can only think of one caveat – if you want to take advantage of event delegation then you wouldn’t want the parent (to which you want the events to bubble) to have that CSS property. Using either jQuery’s live() binding or “manual event delegation” might lead to unexpected results.

  6. madhu

    hi,

    i have one doubt

    when i have two links if iclick first link one alert will display, if i click second link another alert will display how it is possible. Can you pls tell me the code if you know.

    thank You

  7. I have found custom jquery events extremely useful!

  8. [...] Add Events jQuery — Ajouter «cursor: pointer» sur tous les événements «click». [...]

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!