Reputation: 2326
I'm a little confused regarding the .on() method. Let me try and explain:
I need to use .on() in the format of: $(document).on('click', 'selector', function (e) {});
instead of $('selector').on('click', function(e) {});
so that it applies to existing elements as well as dynamically loaded ones too.
I've created a simplified example of my issue here:
$(document).ready(function () {
var obj = $('.testing');
// Doesn't work
$(document).on('click', obj, function (e) {
e.preventDefault();
alert($(this).text());
});
// Works, but won't work for new elements
obj.on('click', function (e) {
e.preventDefault();
alert($(this).text());
});
});
When I have the selector already set in a variable with a jQuery instance already wrapped around it var obj = $('.testing')
it is in the correct format for the 2nd example, but not for the 1st one due to it already being wrapped as a jQuery instance. Going from '.selector'
to $('.selector')
is easy, but is there a way to go from $('.selector')
to '.selector'
?
My Question is, is there any way to un-wrap the jQuery instance so that I can parse the just the selector rather than it already being wrapped via jQuery?
I've created a JSFiddle here: http://jsfiddle.net/MzwK8/
Any pointers or help would be greatly appreciated.
Edit Sorry, I should have said that in my example I've simplified it a lot, but the selector is already being parsed to a plugin as a jQuery instance like $('.selector').plugin()
. I should have mentioned that I don't have the capacity to change the var obj = $('.testing');
line
Upvotes: 1
Views: 102
Reputation: 816364
I think getting the selector string is the wrong approach to the overall problem, and here is why:
I understand that you want $('.foo').plugin()
to work with both, existing and future .foo
elements, correct?
However, what happens if there are no existing .foo
elements? The plugin function would not even be executed and so the event delegation wouldn't be set up. That means the plugin would only work for future .foo
elements if and only if there already existing ones. That's a rather confusing behavior from a user perspective.
I think, in your use case it makes more sense to create a static plugin, which just accepts a selector string:
$.plugin = function(selector) { ... };
$.plugin('div.bar');
Many answers mention obj.selector
, however the documentation marks this property as deprecated and removed. Their suggestion is:
Plugins that need to use a selector string within their plugin can require it as a parameter of the method. For example, a "foo" plugin could be written as
$.fn.foo = function( selector, options ) { /* plugin code goes here */ };
and the person using the plugin would write
$( "div.bar" ).foo( "div.bar", {dog: "bark"} );
with the
"div.bar"
selector repeated as the first argument of.foo()
."
So that's what you should do in your plugin: Require the selector as argument to the plugin method.
Upvotes: 2
Reputation: 1835
This will make your first function work:
$(document).ready(function () {
var obj = $('.testing')[0].className;
$(document).on('click', "."+obj, function (e) {
e.preventDefault();
alert($(this).text());
});
});
Upvotes: 0
Reputation: 49919
If you want to retreive the original selector you can do this:
var obj = $('.testing');
console.log( obj.selector); // will log .testing
Upvotes: 1
Reputation: 700262
The second parameter should be a selector, not a jQuery object:
$(document).on('click', '.testing', function (e) {
e.preventDefault();
alert($(this).text());
});
If possible you should bind the event on the existing element closest to the elements that you will be adding. That way it doesn't have to test the selector for every click that happens in the page.
Upvotes: 3