jquery chaining in IE
I have a jquery plugin that i call as such :
$(function() {
$('.link_class').jquery_plugin()
})
with many anchor tags in the body
<a href="http:...." class="link_class">link 1 </a>
<a href="http:...." class="link_class">link 2 </a>
<a href="http:...." class="link_class">link 3 </a>
the jquery plugin is setup this way :
$.fn.jquery_plugin = function(options) {
if ($(this).is('a' ) ) {
this.each(function() {
$(this).bind('click', function(){
options.content = options.content || $(this).attr('href');
return javascript_plugin (options), false;
})
})
}
};
javascript_plugin = function (options) {
return alert(options.content);
};
my problem is that when I use IE which ever link I click on first will dictate with content is displayed in the alert. hence if i click on link开发者_如何学运维 2 first the href from link 2 will be displayed no matter which link i click on there after... any ideas as to what I might be doing wrong? thanks
I'm not 100% sure about the context of each of the 'this' references, and whether they refer to the 'this' that is implicit in the local function invocation or to the 'this' in the enclosing function, but that is probably related to the explanation.
Either way, there is a slight flaw in your code, which would only manifest itself if one of you assigned 'linkClass' to an element that isn't an 'a'. To fix this, do the check for 'a' inside the loop, as the 'is' method will return true if any of the items in the jquery collection matches the criteria and, when this is done outside the loop, will cause all of the elements to have a click handler bound to them, regardless of whether they are an 'a' or not...
$.fn.jquery_plugin = function(options) {
this.each(function() {
if ($(this).is('a' ) ) {
$(this).bind('click', function(){
options.content = options.content || $(this).attr('href');
return javascript_plugin (options), false;
})
})
}
return this;
};
javascript_plugin = function (options) {
return alert(options.content);
};
Alternatively, simply include the 'a' in the selector used in the invocation of your plugin...
$(function() {
$('a.link_class').jquery_plugin()
})
...and remove the need for the 'a' check in the plugin...
$.fn.jquery_plugin = function(options) {
this.each(function() {
$(this).bind('click', function(){
options.content = options.content || $(this).attr('href');
return javascript_plugin (options), false;
})
}
return this;
};
The big question for me, is whether the last 'this' refers to the DOM element being clicked on, or the element for the current iteration of the 'each' loop. It should be the former.
EDIT:
I now see the problem - the fact that 'options' is only being set to the value of the element's href if it is currently empty. After this, it is left alone, and retains the previously set value. Try creating a local variable instead...
$.fn.jquery_plugin = function(defaultOptions) {
this.each(function() {
$(this).bind('click', function(){
var options = createAnOptionsInstance(); //do what it says
options.content = defaultOptions.content || $(this).attr('href');
return javascript_plugin (options), false;
})
}
return this;
};
Your original code doesn't show any option being passed in to the plugin, so you probably need some extra checks for this.
Overall you're looking at changes like this:
$.fn.jquery_plugin = function(options) {
options = options || {};
return this.filter('a').bind('click', function() {
var content = options.content || $(this).attr('href');
return javascript_plugin ({ 'content': content });
}).end();
};
javascript_plugin = function (options) {
return alert(options.content);
};
You can try it here, there were a few issues, we'll go in code order:
options
would be undefined like your example call, need to account for this when accessingoptions.content
.- The
.is('a')
check needs to be per element (otherwise it's checking any element of the set, so instead do a.filter('a')
before.bind()
. - You need to return the set to keep chaining, this now does that (notice the
.end()
so we don't return the.filter()
version of the set). - Last, don't modify the original options object, that's why you were getting the first-link behavior.
精彩评论