Playing with CSS hooks

So, I wanted to give the new CSS hooks in jQuery a try. Unfortunately, the usually well documented jQuery has this as the total documentation on the hooks:

As of version 1.4.3, jQuery’s CSS module was rewritten to provide a set of “hooks” for the .css() method. This advanced feature, $.cssHooks, allows for fine-grained control over the way jQuery handles certain style properties and enables the creation of custom, browser-normalized properties. The $.cssHooks object also extends the set of properties available to the .animate() method.

Which isn’t much to go on. So, I broke out the old source code to see whats up. Basically, you can hook into a CSS property and create setters and getters for it. I started by making a simple hook that allows you to use show and hide on the display property, and have it call show() and hide(). The code is pretty simple:


jQuery.cssHooks.display = {
set: function(elem, value) {
if (typeof (value) === 'string') {
if (value === 'hide') {
$(elem).hide();
} else if (value === 'show') {
$(elem).show();
} else {
elem.style['display'] = value;
}
} else {
if (value.hide) {
$(elem).hide(value.hide);
} else if (value.show) {
$(elem).show(value.show);
} else {
elem.style['display'] = value;
}
}
}
};

This simply checks if you are passing in a string or an object, and then calls show/hide with the supplied value (in the case of an object.) If you are not using show/hide it runs node.style[‘display’] = value; which is what normally happens when you call .css.

I made an example for it here:

I’m a thing!




The code here is pretty simple too:


$('#hookButton').click(function(e) {
var $this = $(this);
if($this.text() === 'Hide') {
$('#cssHookTest').css('display', 'hide');
$this.text('Show');
} else {
$('#cssHookTest').css('display', 'show');
$this.text('Hide');
}
});

$('#hookButton2').click(function(e) {
var $this = $(this);
if($this.text() === 'Hide Slow') {
$('#cssHookTest').css('display', {'hide': 'slow'});
$this.text('Show Slow');
} else {
$('#cssHookTest').css('display', {'show': 'slow'});
$this.text('Hide Slow');
}
});

$('#hookButton3').click(function(e) {
var $this = $(this);
if($this.text() === 'Hide REALLY Slow') {
$('#cssHookTest').css('display', {'hide': 1400});
$this.text('Show REALLY Slow');
} else {
$('#cssHookTest').css('display', {'show': 1400});
$this.text('Hide REALLY Slow');
}
});

$('#hookButton4').click(function(e) {
var $this = $(this);
if($this.text() === 'Hide Normal') {
$('#cssHookTest').css('display', 'none');
$this.text('Show Slow');
} else {
$('#cssHookTest').css('display', 'block');
$this.text('Hide Normal');
}
});

So, that’s about it, the CSS hooks, although called an advanced feature are really not that hard to use. So, give ’em a try.

jQuery Live DOM sub/pub plugin

Updated 2/10/10 – for the updates to the plugin (See: here)

I made a new jQuery plugin the other day, it is pretty simple, it expands on the idea subscribe/publish idea. Basically it allows you to bind subscriptions to DOM nodes.

You use it like this:



//subscribe a node
$(selector).subscribe(
'subscription/name',
function(subName, [arg1], [arg2],...)
{/*do something*/}
);

//publish
$.publish(
'subscription/name', [arg1], [arg2],...
);

The idea is that you are probably using sub/pub to keep your DOM interaction separate from your non DOM related javascript. So, when you publish, there is a good chance that the subscriber will take the published information and do something to the DOM based on it. Inside of you sub callback, this is the DOM node following jQuerys normal pattern for this.

You can still setup normal subscriptions like so:


$.subscribe(
'subscription/name',
function(subName, [arg1], [arg2],...)
{/*do something*/}
);

One thing to note is that nothing is actually bound to the nodes. In reality the selector that you give is simply saved, and used again when you publish, so this works like .live in that it will even work on nodes added to the DOM after you subscribe. Also like .live though, you must provide the full selector as a string, and you can’t use any of the traversal methods to select your nodes.

Demo:

You must enter something here
Watch me.

The code for this is :


$('#formId').submit(function(e){
validateForm();
return false;
});

$('#response').subscribe('formValidateDone', function(subName, result) {
if(result) {
$(this).html('The form is valid!');
} else {
$(this).html('Please try again!');
}
});

function validateForm() {
$.publish('formValidateDone', $('#textInput').val() !== '');
}

Plugin Link: Plugin page

Download: Download