How can I get selector from jQuery object

JavascriptJqueryJquery SelectorsTree Traversal

Javascript Problem Overview


$("*").click(function(){
    $(this); // how can I get selector from $(this) ?
});

Is there an easy way to get selector from $(this)? There is a way to select an element by its selector, but what about getting the selector from element?

Javascript Solutions


Solution 1 - Javascript

Ok, so in a comment above the question asker Fidilip said that what he/she's really after is to get the path to the current element.

Here's a script that will "climb" the DOM ancestor tree and then build fairly specific selector including any id or class attributes on the item clicked.

See it working on jsFiddle: http://jsfiddle.net/Jkj2n/209/

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
    $(function() {
        $("*").on("click", function(e) {
          e.preventDefault();
          var selector = $(this)
            .parents()
            .map(function() { return this.tagName; })
            .get()
            .reverse()
            .concat([this.nodeName])
            .join(">");

          var id = $(this).attr("id");
          if (id) { 
            selector += "#"+ id;
          }

          var classNames = $(this).attr("class");
          if (classNames) {
            selector += "." + $.trim(classNames).replace(/\s/gi, ".");
          }

          alert(selector);
      });
    });
    </script>
</head>
<body>
<h1><span>I love</span> jQuery</h1>
<div>
  <p>It's the <strong>BEST THING</strong> ever</p>
  <button id="myButton">Button test</button>
</div>
<ul>
  <li>Item one
    <ul>
      <li id="sub2" >Sub one</li>
      <li id="sub2" class="subitem otherclass">Sub two</li>
    </ul>
  </li>
</ul>
</body>
</html>

For example, if you were to click the 2nd list nested list item in the HTML below, you would get the following result:

HTML>BODY>UL>LI>UL>LI#sub2.subitem.otherclass

Solution 2 - Javascript

::WARNING::
.selector has been deprecated as of version 1.7, removed as of 1.9

The jQuery object has a selector property I saw when digging in its code yesterday. Don't know if it's defined in the docs are how reliable it is (for future proofing). But it works!

$('*').selector // returns *

Edit: If you were to find the selector inside the event, that information should ideally be part of the event itself and not the element because an element could have multiple click events assigned through various selectors. A solution would be to use a wrapper to around bind(), click() etc. to add events instead of adding it directly.

jQuery.fn.addEvent = function(type, handler) {
    this.bind(type, {'selector': this.selector}, handler);
};

The selector is being passed as an object's property named selector. Access it as event.data.selector.

Let's try it on some markup (http://jsfiddle.net/DFh7z/):

<p class='info'>some text and <a>a link</a></p>​

$('p a').addEvent('click', function(event) {
    alert(event.data.selector); // p a
});


Disclaimer: Remember that just as with live() events, the selector property may be invalid if DOM traversal methods are used.

<div><a>a link</a></div>

The code below will NOT work, as live relies on the selector property which in this case is a.parent() - an invalid selector.

$('a').parent().live(function() { alert('something'); });

Our addEvent method will fire, but you too will see the wrong selector - a.parent().

Solution 3 - Javascript

In collaboration with @drzaus we've come up with the following jQuery plugin.

jQuery.getSelector

!(function ($, undefined) {
    /// adapted http://jsfiddle.net/drzaus/Hgjfh/5/

    var get_selector = function (element) {
        var pieces = [];

        for (; element && element.tagName !== undefined; element = element.parentNode) {
            if (element.className) {
                var classes = element.className.split(' ');
                for (var i in classes) {
                    if (classes.hasOwnProperty(i) && classes[i]) {
                        pieces.unshift(classes[i]);
                        pieces.unshift('.');
                    }
                }
            }
            if (element.id && !/\s/.test(element.id)) {
                pieces.unshift(element.id);
                pieces.unshift('#');
            }
            pieces.unshift(element.tagName);
            pieces.unshift(' > ');
        }

        return pieces.slice(1).join('');
    };

    $.fn.getSelector = function (only_one) {
        if (true === only_one) {
            return get_selector(this[0]);
        } else {
            return $.map(this, function (el) {
                return get_selector(el);
            });
        }
    };

})(window.jQuery);

Minified Javascript

// http://stackoverflow.com/questions/2420970/how-can-i-get-selector-from-jquery-object/15623322#15623322
!function(e,t){var n=function(e){var n=[];for(;e&&e.tagName!==t;e=e.parentNode){if(e.className){var r=e.className.split(" ");for(var i in r){if(r.hasOwnProperty(i)&&r[i]){n.unshift(r[i]);n.unshift(".")}}}if(e.id&&!/\s/.test(e.id)){n.unshift(e.id);n.unshift("#")}n.unshift(e.tagName);n.unshift(" > ")}return n.slice(1).join("")};e.fn.getSelector=function(t){if(true===t){return n(this[0])}else{return e.map(this,function(e){return n(e)})}}}(window.jQuery)

Usage and Gotchas

<html>
    <head>...</head>
    <body>
        <div id="sidebar">
            <ul>
                <li>
                    <a href="/" id="home">Home</a>
                </li>
            </ul>
        </div>
        <div id="main">
            <h1 id="title">Welcome</h1>
        </div>

        <script type="text/javascript">

            // Simple use case
            $('#main').getSelector();           // => 'HTML > BODY > DIV#main'

            // If there are multiple matches then an array will be returned
            $('body > div').getSelector();      // => ['HTML > BODY > DIV#main', 'HTML > BODY > DIV#sidebar']

            // Passing true to the method will cause it to return the selector for the first match
            $('body > div').getSelector(true);  // => 'HTML > BODY > DIV#main'

        </script>
    </body>
</html>

Fiddle w/ QUnit tests

http://jsfiddle.net/CALY5/5/

Solution 4 - Javascript

Did you try this ?

 $("*").click(function(){
    $(this).attr("id"); 
 });

Solution 5 - Javascript

Try this:

$("*").click(function(event){
    console.log($(event.handleObj.selector));
 });

Solution 6 - Javascript

I've released a jQuery plugin: jQuery Selectorator, you can get selector like this.

$("*").on("click", function(){
  alert($(this).getSelector().join("\n"));
  return false;
});

Solution 7 - Javascript

Well, I wrote this simple jQuery plugin.

This checkes id or class name, and try to give as much exact selector as possible.

jQuery.fn.getSelector = function() {

    if ($(this).attr('id')) {
        return '#' + $(this).attr('id');
    }

    if ($(this).prop("tagName").toLowerCase() == 'body')    return 'body';

    var myOwn = $(this).attr('class');
    if (!myOwn) {
        myOwn = '>' + $(this).prop("tagName");
    } else {
        myOwn = '.' + myOwn.split(' ').join('.');
    }

    return $(this).parent().getSelector() + ' ' + myOwn;
}

Solution 8 - Javascript

Just add a layer over the $ function this way:

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

Now you can do things like

$("a").selector
and will return "a" even on newer jQuery versions.

Solution 9 - Javascript

http://www.selectorgadget.com/ is a bookmarklet designed explicitly for this use case.

That said, I agree with most other people in that you should just learn CSS selectors yourself, trying to generate them with code is not sustainable. :)

Solution 10 - Javascript

I added some fixes to @jessegavin's fix.

This will return right away if there is an ID on the element. I also added a name attribute check and a nth-child selector in case a element has no id, class, or name.

The name might need scoping in case there a multiple forms on the page and have similar inputs, but I didn't handle that yet.

function getSelector(el){
    var $el = $(el);

    var id = $el.attr("id");
    if (id) { //"should" only be one of these if theres an ID
        return "#"+ id;
    }

    var selector = $el.parents()
                .map(function() { return this.tagName; })
                .get().reverse().join(" ");

    if (selector) {
        selector += " "+ $el[0].nodeName;
    }

    var classNames = $el.attr("class");
    if (classNames) {
        selector += "." + $.trim(classNames).replace(/\s/gi, ".");
    }

    var name = $el.attr('name');
    if (name) {
        selector += "[name='" + name + "']";
    }
    if (!name){
        var index = $el.index();
        if (index) {
            index = index + 1;
            selector += ":nth-child(" + index + ")";
        }
    }
    return selector;
}

Solution 11 - Javascript

I was getting multiple elements even after above solutions, so i extended dds1024 work, for even more pin-pointing dom element.

e.g. DIV:nth-child(1) DIV:nth-child(3) DIV:nth-child(1) ARTICLE:nth-child(1) DIV:nth-child(1) DIV:nth-child(8) DIV:nth-child(2) DIV:nth-child(1) DIV:nth-child(2) DIV:nth-child(1) H4:nth-child(2)

Code:

function getSelector(el)
{
	var $el = jQuery(el);

	var selector = $el.parents(":not(html,body)")
				.map(function() { 
									var i = jQuery(this).index(); 
									i_str = ''; 
									
									if (typeof i != 'undefined') 
									{
										i = i + 1;
										i_str += ":nth-child(" + i + ")";
									}
	
									return this.tagName + i_str; 
								})
				.get().reverse().join(" ");

	if (selector) {
		selector += " "+ $el[0].nodeName;
	}
	
	var index = $el.index();
	if (typeof index != 'undefined')  {
		index = index + 1;
		selector += ":nth-child(" + index + ")";
	}
	
	return selector;
}

Solution 12 - Javascript

Taking in account some answers read here I'd like to propose this:

function getSelectorFromElement($el) {
  if (!$el || !$el.length) {
    return ;
  }

  function _getChildSelector(index) {
    if (typeof index === 'undefined') {
      return '';
    }

    index = index + 1;
    return ':nth-child(' + index + ')';
  }

  function _getIdAndClassNames($el) {
    var selector = '';

    // attach id if exists
    var elId = $el.attr('id');
    if(elId){
      selector += '#' + elId;
    }

    // attach class names if exists
    var classNames = $el.attr('class');
    if(classNames){
      selector += '.' + classNames.replace(/^\s+|\s+$/g, '').replace(/\s/gi, '.');
    }

    return selector;
  }

  // get all parents siblings index and element's tag name,
  // except html and body elements
  var selector = $el.parents(':not(html,body)')
    .map(function() {
      var parentIndex = $(this).index();

      return this.tagName + _getChildSelector(parentIndex);
    })
    .get()
    .reverse()
    .join(' ');

  if (selector) {
    // get node name from the element itself
    selector += ' ' + $el[0].nodeName +
      // get child selector from element ifself
      _getChildSelector($el.index());
  }

  selector += _getIdAndClassNames($el);

  return selector;
}

Maybe useful to create a jQuery plugin?

Solution 13 - Javascript

This can get you selector path of clicked HTML element-

 $("*").on("click", function() {

    let selectorPath = $(this).parents().map(function () {return this.tagName;}).get().reverse().join("->");

    alert(selectorPath);

    return false;

});

Solution 14 - Javascript

Are you trying to get the name of the current tag that was clicked?

If so, do this..

$("*").click(function(){
    alert($(this)[0].nodeName);
});

You can't really get the "selector", the "selector" in your case is *.

Solution 15 - Javascript

Javascript code for the same, in case any one needs, as i needed it. This just the translation only of the above selected answer.

    <script type="text/javascript">

function getAllParents(element){
	var a = element;
	var els = [];
	while (a && a.nodeName != "#document") {
	    els.unshift(a.nodeName);
	    a = a.parentNode;
	}
	return els.join(" ");
}

function getJquerySelector(element){
	
	var selector = getAllParents(element);
	/* if(selector){
		selector += " " + element.nodeName;
	} */
	var id = element.getAttribute("id");
	if(id){
		selector += "#" + id;
	}
	var classNames = element.getAttribute("class");
	if(classNames){
		selector += "." + classNames.replace(/^\s+|\s+$/g, '').replace(/\s/gi, ".");
	}
	console.log(selector);
	alert(selector);
	return selector;
}
</script>

Solution 16 - Javascript

Thank you p1nox!

My problem was to put focus back on an ajax call that was modifying part of the form.

$.ajax({  url :	"ajax_invite_load.php",
		async :	true,
		 type : 'POST',
		 data :	...
	 dataType :	'html',
	  success :	function(html, statut) {
					var focus = $(document.activeElement).getSelector();
					$td_left.html(html);
					$(focus).focus();
				}
});

I just needed to encapsulate your function in a jQuery plugin:

    !(function ($, undefined) {

    $.fn.getSelector = function () {
	  if (!this || !this.length) {
		return ;
	  }

	  function _getChildSelector(index) {
		if (typeof index === 'undefined') {
		  return '';
		}

		index = index + 1;
		return ':nth-child(' + index + ')';
	  }

	  function _getIdAndClassNames($el) {
		var selector = '';

		// attach id if exists
		var elId = $el.attr('id');
		if(elId){
		  selector += '#' + elId;
		}

		// attach class names if exists
		var classNames = $el.attr('class');
		if(classNames){
		  selector += '.' + classNames.replace(/^\s+|\s+$/g, '').replace(/\s/gi, '.');
		}

		return selector;
	  }

	  // get all parents siblings index and element's tag name,
	  // except html and body elements
	  var selector = this.parents(':not(html,body)')
		.map(function() {
		  var parentIndex = $(this).index();

		  return this.tagName + _getChildSelector(parentIndex);
		})
		.get()
		.reverse()
		.join(' ');

	  if (selector) {
		// get node name from the element itself
		selector += ' ' + this[0].nodeName +
		  // get child selector from element ifself
		  _getChildSelector(this.index());
	  }

	  selector += _getIdAndClassNames(this);

	  return selector;
	}

})(window.jQuery);

Solution 17 - Javascript

This won't show you the DOM path, but it will output a string representation of what you see in eg chrome debugger, when viewing an object.

$('.mybtn').click( function(event){
	console.log("%s", this);	// output: "button.mybtn"
});

https://developer.chrome.com/devtools/docs/console-api#consolelogobject-object

Solution 18 - Javascript

How about:

var selector = "*"
$(selector).click(function() {
    alert(selector);
});

I don't believe jQuery store the selector text that was used. After all, how would that work if you did something like this:

$("div").find("a").click(function() {
    // what would expect the 'selector' to be here?
});

Solution 19 - Javascript

The best answer would be

var selector = '#something';

$(selector).anything(function(){
  console.log(selector);
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFidilipView Question on Stackoverflow
Solution 1 - JavascriptjessegavinView Answer on Stackoverflow
Solution 2 - JavascriptAnuragView Answer on Stackoverflow
Solution 3 - JavascriptWillView Answer on Stackoverflow
Solution 4 - JavascriptabhilashvView Answer on Stackoverflow
Solution 5 - JavascriptAmazingDayTodayView Answer on Stackoverflow
Solution 6 - JavascriptngsView Answer on Stackoverflow
Solution 7 - JavascriptCodemoleView Answer on Stackoverflow
Solution 8 - JavascriptAlbert HortaView Answer on Stackoverflow
Solution 9 - JavascriptPaul IrishView Answer on Stackoverflow
Solution 10 - JavascriptDustinView Answer on Stackoverflow
Solution 11 - JavascriptAzghanviView Answer on Stackoverflow
Solution 12 - Javascriptp1noxView Answer on Stackoverflow
Solution 13 - JavascriptVivek KumarView Answer on Stackoverflow
Solution 14 - JavascriptjessegavinView Answer on Stackoverflow
Solution 15 - JavascriptjaipsterView Answer on Stackoverflow
Solution 16 - JavascriptPatrickView Answer on Stackoverflow
Solution 17 - JavascriptNick HumphreyView Answer on Stackoverflow
Solution 18 - JavascriptDean HardingView Answer on Stackoverflow
Solution 19 - JavascriptAnnyView Answer on Stackoverflow