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...
精彩评论