开发者

What's happening in this JQuery code?

Sorry for this very basic JQuery question. I created 'mytest' jquery function like this:

jQuery.fn.mytest = function () {
    alert($(this).attr('id'))
}

Now if I call it like this everything is perfect:

$("#someid").mytest();

It alerts "someid". But if I do something like this:

$("#someid, #anotherid, #moreids").mytest();

this function onl开发者_运维百科y alerts "someid". Of course "anotherid" and "moreids" exist.

Why mytest() is not working and what is the right code for this function?


Your code is adding a "plugin" to jQuery that makes your function available on jQuery instances. The reason you're only seeing one ID in your function is that you're using attr, which only retrieves the first element's attribute. (Also, you really don't need attr to get an id value.)

Your function should look something like this (live copy):

jQuery.fn.mytest = function () {
    var ids = jQuery.map(this, function(elm) {
        return elm.id;
    });
    alert(ids.join(","));
};

...to show the id values (if any) of each element in the currently-matched set.

Or you could do it with a simple loop rather than with jQuery.map (live copy):

jQuery.fn.mytest = function () {
    var ids, index, elm;

    ids = [];
    for (index = 0; index < this.length; ++index) {
        elm = this[index];
        if (elm.id) {
            ids.push(elm.id);
        }
    }
    alert(ids.join(","));
};

Also, note that within a jQuery plug-in function, this is the current jQuery instance, so you don't need (or want) to pass it through $() to create a jQuery wrapper around the element (you do that in event handlers, not plug-ins). So when I do this.length in the second example above, I'm using the length property of the jQuery instance that we're currently operating on. When I index into this using bracketed notation (elm = this[index];), I'm indexing into the jQuery instance's matched set of elements (like the get method, but more directly).


This is due to .attr():

Get the value of an attribute for the first element in the set of matched elements. (my emphasis)

The resolution:

The .attr() method gets the attribute value for only the first element in the matched set. To get the value for each element individually, use a looping construct such as jQuery's .each() or .map() method.

E.g.,

jQuery.fn.mytest = function () {
    var ids = [];
    $(this).each(function() {
        ids.push($(this).attr('id'));
    });

    alert(ids);
}

(Untested, see also Utilizing the awesome power of jQuery to access properties of an element.)

Disclaimer
This is really what .map() is for. Read the above as a demo of the idea, not the implementation of said idea :)


You need to use

jQuery.fn.mytest = function () {
    return this.each(function(){
       alert(this.id);
    });
}

Have a read of http://docs.jquery.com/Plugins/Authoring which describes what you need to know when you try to create plugins.

Using return this.each(..) enables chaining of your plugin so you can do $('#something, #somethingelse').mytest().hide();


You are selecting multiple elements so...you also need to loop through that elements to alert every single id. Now you only get the first id. So it should be like:

jQuery.fn.mytest = function () { 
    return $(this).each(function(){ 
       alert($(this).attr('id')); 
    }); 
} 

Not tested...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜