Yahel
Yahel

Reputation: 37305

Is it possible to access the DOM element 'this' in a non-function parameter argument in a jQuery plugin?

I have a potentially strange question about this and jQuery plugins

As I understand it, the following is a very basic jQuery plugin:

$.fn.clickclone = function(param){
    return this.click(function(){  
        param.apply(this);  
    });
}; 

(pretending that's a plugin that somehow extends click().)

So, if I pass a function as an argument, it does what it needs to do and properly accesses this as a DOM node. Easy.

That's all clear to me.

What's not clear is, is there any way I could pass a non-function argument to the plugin and have it properly access this from the arguments? ie, could I configure the plugin to do something like this:

$("#foo").pluginname(["foo", $(this).text() ]);

Such that for:

<a href="/bar" id="foo">Bar</a>

It would properly pass an array to the plugin, with the second item in the array returning the value Bar?

I'm doing this, basically, to provide syntactic sugar for my plugin, where you can pass an array as a shortcut (in addition to using a normal callback function as the main functionality). Except, doing that, I lose access to use of this. Hence my dilemma.

EDIT: This is evil, but, it seems like one work around is to pass the argument as a string and then eval it. Not a workable solution for me, but, it illustrates what I'd like to be able to do:

$.fn.clickclone = function(param){
    return this.click(function(){ 
        if(typeof param === "function"){ 
            param.apply(this);
        }
        else if(typeof param[1] === "string"){
             console.dir("This is evil: " + eval(param[1]));
        }  
    });
}; 

Upvotes: 4

Views: 124

Answers (1)

Domenic
Domenic

Reputation: 112837

There's no general way to do this without a function, since, in the purely mathematical sense, you are asking for a function of the input (that is, a function of this): something that depends on this in a certain way.

You could perhaps hack it with strings, like so, but you lose the flexibility of functions:

$.fn.alertMe = function (methodToAlert) {
    alert(this[methodToAlert]());
};

// usage:
$("#foo").alertMe("text");
$("#foo").alertMe("width");

And if you find using a function acceptable but the this syntax confusing, you can simply do the following:

$.fn.alertMe = function (alertGetter) {
    alert(alertGetter($(this));
};

// usage:
$("#foo").alertMe(function (x$) { return x$.text(); });
$("#foo").alertMe(function (x$) { return x$.width(); });

And for completeness I guess I should mention you could probably get away with an eval-based solution, looking something like $("#foo").alertMe("$(this).text()"), but eval is evil and I will neither write up nor condone such a solution. EDIT: oh, I see you have done so in an edit to your original post. Good job corrupting future generations ;)

Upvotes: 2

Related Questions