33

I have a jQuery selector, which has a chained function.

Inside the function I want to get access to the TEXT representing the expression for the selector.

$("cat dog").function() {

    // how do I get access to the "cat dog" string from inside THIS function ?
};

I've over simplified in this code sample what I actually want to do. I'm writing a plug-in and I need access to the selector for which the wrapped set has been created. Obviously in this particular example I have access to "cat dog" becasue i wrote it. So just picture this being in a plugin.

Its a little tricky to google for this.

edit: the 'selector' property is unfortunately now deprecated. http://jquery.com/upgrade-guide/1.9/#selector-property-on-jquery-objects

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
  • Even if you can get to the initial selector, remember that you could have something like $(".cat .dog").parents("div:first").find(".parrot").each(function(){/*...*/}); where you simply don't have a simple selector. – Svante Svenson Feb 02 '09 at 10:45
  • thats a point i'm struggling with. i'm possibly wondering about traversing up the tree, but mostly just getting last element is fine. i would typically want to do something like this $('.cat').assertNonEmpty().each(function(){}); – Simon_Weaver Feb 03 '09 at 00:53
  • Any chance you could upgrade to jQuery 1.3.1 and use "selector"? – Nosredna Feb 04 '09 at 20:54
  • i'm waiting for 1.3.2 - http://stackoverflow.com/questions/498469. i have to go live tomorrow with a very small part of a new site and i don't want people to have to wait for images to load before the jQuery executes. as soon as i've confirmed 1.3.2 has no error i'll switch. thanks for the info – Simon_Weaver Feb 05 '09 at 03:59

9 Answers9

18

There is a 'selector' attribute in the jQuery object, but I'm not sure it's always available.

Ryan Doherty
  • 38,580
  • 4
  • 56
  • 63
  • i couldn't seem to access it when i tried. i'll wait a little longer to see if someone else is kind enough to try it for me :) – Simon_Weaver Feb 01 '09 at 05:42
  • its new in 1.3.1 If your using 1.2.6 it wont be available – redsquare Feb 02 '09 at 12:14
  • oh great. thanks i'll check it out. i'm not switching to jQuery until theres an official 1.3.2 release due to this http://stackoverflow.com/questions/477463 (incidentally the post thats got me the most points so far!) – Simon_Weaver Feb 04 '09 at 23:22
  • is the 'selector' a documented property? if its an undocumented property, i would not rely on it. i cant find any reference to it in the jquery docs. – Chii May 20 '09 at 08:53
  • You're right, it doesn't work all the time, especially if you are dynamically creating elements and want to give a back reference to the object/element that created the child. – Richard Clayton Nov 17 '09 at 15:40
  • 4
    Now deprecated :-( http://jquery.com/upgrade-guide/1.9/#selector-property-on-jquery-objects – Simon_Weaver Feb 11 '13 at 04:57
  • @Simon_Weaver it is not deprected, it is removed in 1.9+ and the plugin for migration does not restore it either. – Mark Schultheiss Feb 13 '13 at 23:04
  • @MarkSchultheiss it seems to still work for me in 1.9.1. maybe the functionality changed slightly but it's definitely still there. in fact if you look at the source for migrate it used 'selector' in two places. i'm still quite confused! – Simon_Weaver Feb 25 '13 at 02:17
8

This is far from optimal but works in some cases. You could do the following:

jQuery.fn._init = jQuery.fn.init
jQuery.fn.init = function( selector, context ) {
    return (typeof selector === 'string') ? jQuery.fn._init(selector, context).data('selector', selector) : jQuery.fn._init( selector, context );
};

jQuery.fn.getSelector = function() {
    return jQuery(this).data('selector');
};

This will return the last selector used for the element. But it will not work on non existing elements.

<div id='foo'>Select me!</div>
<script type='text/javascript'>
 $('#foo').getSelector(); //'#foo'
 $('div[id="foo"]').getSelector(); //'div[id="foo"]'
 $('#iDoNotExist').getSelector(); // undefined
</script>

This works with jQuery 1.2.6 and 1.3.1 and possibly other versions.

Also:

<div id='foo'>Select me!</div>
<script type='text/javascript'>
 $foo = $('div#foo');
 $('#foo').getSelector(); //'#foo'
 $foo.getSelector(); //'#foo' instead of 'div#foo'
</script>

Edit
If you check immidiatly after the selector has been used you could use the following in your plugin:

jQuery.getLastSelector = function() {
    return jQuery.getLastSelector.lastSelector;
};
jQuery.fn._init = jQuery.fn.init
jQuery.fn.init = function( selector, context ) {
    if(typeof selector === 'string') {
        jQuery.getLastSelector.lastSelector = selector;
    }
    return jQuery.fn._init( selector, context );
};

Then the following would work:

<div id='foo'>Select me!</div>
<script type='text/javascript'>
 $('div#foo');
 $.getLastSelector(); //'#foo'
 $('#iDoNotExist');
 $.getLastSelector(); // #iDoNotExist'
</script>

In your plugin you could do:

jQuery.fn.myPlugin = function(){
 selector = $.getLastSelector;
 alert(selector);
 this.each( function() {
  //do plugins stuff
 }
}

$('div').myPlugin(); //alerts 'div'
$('#iDoNotExist').myPlugin(); //alerts '#iDoNotExist'

But still:

$div = $('div');
$('foo');
$div.myPlugin(); //alerts 'foo'
yckart
  • 32,460
  • 9
  • 122
  • 129
Pim Jager
  • 31,965
  • 17
  • 72
  • 98
  • ha. thats really quite clever. unfortunately i DO need (more often than not in fact) to know when the selector returned zero items. i'm trying to construct more useful error messages for my assertion plugin http://stackoverflow.com/questions/498469 – Simon – Simon_Weaver Feb 01 '09 at 20:54
  • i'm not awake enough to re-read this just now. i only just saw you'd updated this. just wanted to raise attention to anyone using this code that if they see some wierdness occuring it could be due to this problem : http://stackoverflow.com/questions/535967/ – Simon_Weaver Feb 11 '09 at 09:47
3

If you're using firebug you could console.log(this) inside the function and see if the selector string is accessible somewhere in the object. Sorry I am not familiar with the jQuery API.

Luca Matteis
  • 29,161
  • 19
  • 114
  • 169
  • i cant seem to immediately see it in there, but +1 for telling me something i didnt know. i was using IE and debugging in Visual Studio and not getting much useful by inspecting the object there – Simon_Weaver Feb 01 '09 at 05:18
  • LoL! Thx Luca for your hint. Forgot to dump the this variable in function. :) Saved my time here!! :) Thank you!! – Mr.TK Apr 25 '14 at 07:26
  • Debugging voluntarily in IE? Wow, that's kind of masochistic ;-) – Simon Steinberger Aug 31 '14 at 09:04
2

This will work if you want to access selector string in your function:

$(this).html();

This will also work if multiple selector are use,

for instance,

$('#id1,#id2').click(function(){
   alert($(this).html());
});
KV Prajapati
  • 93,659
  • 19
  • 148
  • 186
Zeeshan
  • 48
  • 1
  • 8
1

Maybe this solve your problem :

var $jqueryItems = $( ".my-selector" );
console.log( $jqueryItems.selector ); // display ".my-selector"
Bruno J. S. Lesieur
  • 3,612
  • 2
  • 21
  • 25
1

For those who want to get inside their plugins selector string given to jQuery, I am glad to have improved the great answer given by @Pim Jager:

  1. As of now (latest version 3.2.1) there are 3 arguments in jQuery.fn.init function - selector, context, root - not two;
  2. new keyword should be added to the return statement of jQuery.fn.init;
  3. Inside your plugin the selectors are returned as a string by calling $(this).getSelector();

Finally, that's what I've got to work for me like a charm:

(function($, window, document, undefined) { 
    $.fn._init = $.fn.init
    $.fn.init = function( selector, context, root ) {
        return (typeof selector === 'string') ? new $.fn._init(selector, context, root).data('selector', selector) : new $.fn._init( selector, context, root );
    };
    $.fn.getSelector = function() {
        return $(this).data('selector');
    };
    $.fn.YOUR-PLUGIN = function() {
        var selector = $(this).getSelector(); // selectors string given to jQuery 
        // other code
    }
})(jQuery, window, document);

It works with jQuery versions as far as I am concerned (from 1.7.0 to 3.2.1).

PS. Works fine even with jQuery 1.2.3 available here on stackoverflow too. So, I guess, the following is ok for all jQuery versions if you want to get a jQuery selector's expression as text inside the plugin:

// our plugin
(function($, window, document, undefined) { 
    $.fn._init = $.fn.init
    $.fn.init = function( selector, context, root ) {
        return (typeof selector === 'string') ? new $.fn._init(selector, context, root).data('selector', selector) : new $.fn._init( selector, context, root );
    };
    $.fn.getSelector = function() {
        return $(this).data('selector');
    };
    $.fn.coolPlugin = function() {
        var selector = $(this).getSelector(); 
        if(selector) console.log(selector); // outputs p #boldText
    }
})(jQuery, window, document);

// calling plugin
$(document).ready(function() {
    $("p #boldText").coolPlugin();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<p>some <b id="boldText">bold text</b></p>
curveball
  • 4,320
  • 15
  • 39
  • 49
1

Please refer to my answer on a duplicate question: Intercepting selector at initialization time

Details: Fully working with any jQuery version even after deprecation and removal of "selector" property

My solution is to intercept the selector at the time of jQuery object initialization and in the same time maintain all other jQuery functionalities transparently all this using inheritance as the following:

$ = (function (originalJQuery) 
{
    return (function () 
    {
        var newJQuery = originalJQuery.apply(this, arguments);
        newJQuery.selector = arguments.length > 0 ? arguments[0] : null;
        return newJQuery;
    });
})($);

$.fn = $.prototype = jQuery.fn;

Usage:

var myAnchors = $('p > a');
var selector = myAnchors.selector;

Should produce: "p > a"

Tried it successfully with jQuery 3.4.1

Abdulhameed
  • 322
  • 3
  • 13
0

I couldn't figure out how to get the reference to the string value of the selector provided to inside $('value_i_want_here') when bound to a function; seems like a tough problem. However, if you prefer testing in IE[x] there's always Firebug Lite which works really well utilizing console.log(var|val).

Dave Mosher
  • 336
  • 1
  • 6
-2

well, I'm still trying to figure out if you are trying to get the element name? or the id and/or class or all of it.

You can get element with this

var element =$(this).get(0);
var id = $(this).attr('id');
var class=$(this).attr('class');

not sure what happens if you have more than one class. might go into an array or something, and you could get that with the indexes.

pedalpete
  • 21,076
  • 45
  • 128
  • 239
  • @pedalpete - i want that actual text "cat dog" - as a string – Simon_Weaver Feb 01 '09 at 06:19
  • @pedalpete - i think maybe the title of this post is a little misleading, but i hoped the question itself was clearer. little ambiguous looking at it. what I want is the actual string value that the $('cat dog') selector was constructed with. – Simon_Weaver Feb 01 '09 at 06:30
  • ha. thats really quite clever. unfortunately i DO need (more often than not in fact) to know when the selector returned zero items. i'm trying to construct more useful error messages for my assertion plugin http://stackoverflow.com/questions/498469 – Simon_Weaver Feb 01 '09 at 20:48
  • sorry - i actually posted that last comment on the wrong answer. this wasnt what i was looking for – Simon_Weaver Feb 01 '09 at 20:53