Reputation: 11291
I'm writing a jQuery plugin, but I'm having a problem:
My HTML element
<a id="trac"></a>
My JS that calls the plugin
$('#trac').myplugin();
My plugin
$.fn.myplugin = function(){
var $root;
return this.each(function(){
$root = $(this);
$root.live('click',function(){
console.log('here');
});
});
}
It happens that "here" is never displayed. But if I use...
$('#trac').live('click',function(){
console.log('here');
});
..."here" is displayed. I don't understand why it is happening because $root and $('#trac') are exactly the same jQuery object.
How can I fix it?
Thanks!
Upvotes: 5
Views: 1240
Reputation: 34178
I like the other answer as a "direct" answer to the question but to show some alternate to what you are doing for others I think you can simplfy the plugin as:
<div id="mystuff">hi</div>
<div id='answer'>empty</div>
$.fn.myplugin = function() {
this.live('click', function() {
$('#answer').text('here');
});
}
$('#mystuff').myplugin();
as shown in this example: http://jsfiddle.net/FgUEB/, thus the "this" gets the selector and you can then attach the "live click" - without the complexity of the .each - which, IF you do it the way you have it (with the selector fixed of course) will put the event on the elements multiple times if it has several - which is implied by the .each you have in your example.
jQuery.fn.newMethod = function(){
return this.each(function(){
alert(typeof this);
});
};
The reference this keyword within the inner function (in the alert) refers to the current HTML element. Since it is NOT a jQuery object it won't have access to the jQuery methods (although, you can wrap it in the jQuery object to get those methods back as jQuery(this).
jQuery.fn.newMethod = function(){
return this.each(function(){
jQuery(this).css({'background-color':'red'});//each inner element
});
};
Upvotes: 0
Reputation: 413757
The ".live()" function needs a selector, and in your plugin you're not giving it one. The jQuery object you build ($(this)
) is a valid object but there's no selector string involved.
You could directly bind the handler:
$root.click(function() { ... });
To elaborate: you say, "... because $root and $('#trac') are exactly the same." The problem is that that is not really true. When you build a jQuery object with a selector string, the object keeps that selector string around. There's no string when you build "$root" from "$(this)". The ".live()" function operates by creating a handler on the <body>
element and then testing the target of each event that bubbles up against that selector.
Upvotes: 8