views:

41

answers:

3

I'm writing a jQuery plugin and I would like my code to take advantage of the jQuery UI show(effect, [options], [speed], [callback]) and hide(effect, [options], [speed], [callback]) functions, which allow you to show and hide elements with a nice animation.

However, I'd also like my plugin to degrade gracefully if jQuery UI isn't available, switching back to use the basic, non-animating show() and hide() functions present in the standard jQuery API.

I'll need to test for the show and hide functions specifically, as even if jQuery UI is available it could potentially be a custom version, without the Effects components included.

At first I thought that I might be able to do something like:

if(typeof myelement.show('blind', 'slow') == 'undefined')
{
    myelement.show('blind', 'slow');
}
else
{
    myelement.show();
}

But of course this doesn't work, as even if UI isn't present, show() is still a function, it just has a different signature—so typeof returns object in either case.

So, what's the best way for me to check if jQuery UI is available to my plugin? Any help is much appreciated!

A: 

If you know how the code of the individual code looks, you can just compare or test it on a particular occurence for instance. Like:

function test(){
  alert('method A');
}

var check = test.toString();

if(/alert/.test(check))
  alert('method a');
jAndy
This is a *very* bad way to check for a function, please never, ever, ever do this.
Nick Craver
I agree. How do you know what bit of the code to match? If the code in the jQuery function body changes (which it obviously will from version to version), my plugin will break.
Mark B
+2  A: 

You can check for an effect like this:

function hasEffect(effect) {
    return $.effects && $.effects[effect];
}

Then you can use that anywhere:

if(hasEffect('blind')) {
  myelement.show('blind', 'slow');
} else {
  myElement.show();
}
//or, you can shorten it further:
//$.fn.show.apply(myelement, hasEffect('blind') ? ['blind','slow'] : []);​

You can view a demo here, check/uncheck jQuery UI on the left and click "Run" up top to see it in action. This works because effects are declared like this:

$.effects.blind = function(o) { ...effecty stuff... };

For example, you can see "blind" here. The reason I check for both $.effects and $.effects.effect in the code above is you can only download some of the effects when you download jQuery UI, so this accounts for that possibility.

Nick Craver
Great, thanks—exactly what I was looking for. I'm surprised that function isn't part of jQuery; this must be quite a common requirement for plugin authors.
Mark B
+1  A: 

Nick's function worked perfectly; for consistency, I ended up adding it as a jQuery utility function from within my plugin code:

$.extend({
    hasEffect: function (effect) {
        return $.effects && $.effects[effect];
    }
});

So now I can call $.hasEffect(effectname) anywhere I want to check for the presence of a particular jQuery UI effect.

Mark B