How to get the string passed to jquery? [duplicate] - javascript

$("*").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?

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

::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().

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>
Home
</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/

Did you try this ?
$("*").click(function(){
$(this).attr("id");
});

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

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;
}

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.

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. :)

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;
}

I've released a jQuery plugin: jQuery Selectorator, you can get selector like this.
$("*").on("click", function(){
alert($(this).getSelector().join("\n"));
return false;
});

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;
}

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?

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;
});

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 *.

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>

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);

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

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?
});

The best answer would be
var selector = '#something';
$(selector).anything(function(){
console.log(selector);
});

Related

jquery cannot get div to show using this selector

I am querying the Twitch API for a list of users in my database, to see if they are online.
I am essentially listing them all, with "display: none" and then unhiding if online:
$('.online_list').each(function (index) {
var tnick = $(this).data('tnick');
$.getJSON("https://api.twitch.tv/kraken/streams?client_id={:twitch_key}&channel="+tnick+"", function(a) {
if (a["streams"].length > 0)
{
alert(tnick);
$(this).show();
console.log(index + ": " + $( this ).text());
}
});
});
In my testing, the alert(tnick) works perfectly, so I know it's running. The problem is $(this).show(); just isn't working.
Here's example HTML:
<div class="online_list" data-tnick="test" style="display: none;">test:Twitch <span>(Online)</span></div>
<div class="online_list" data-tnick="test2" style="display: none;">test2:Twitch <span>(Online)</span></div>
this is the current scope object!
to fix your code you can do the following:
$('.online_list').each(function (index) {
var $that = $(this); // create a temp var that
var tnick = $that.data('tnick');
$.getJSON("https://api.twitch.tv/kraken/streams?client_id={:twitch_key}&channel="+tnick+"", function(a) {
if (a && a["streams"] && a["streams"].length > 0) {
alert(tnick);
$that.show(); // use that instead of this
console.log(index + ": " + $that.text());
}
});
});
Check out this resource for more information on scope & this: http://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this/
EDIT:
Also, like #djxak suggests, you can use the element parameter of the callback, that is more simple and clean in my opinion.
The #djxak suggests:
$('.online_list').each(function (index, element) {
//... (scope1 code)
$.getJSON("", function(a) {
//... (scope2 code)
$(element).show();
});
});
My approach:
$('.online_list').each(function (index) {
//... (scope1 code)
var $current = $(this);
$.getJSON("", function(a) {
//... (scope2 code)
$current.show();
});
});
Info about each function and element parameter in jQuery docs: https://api.jquery.com/each/#each-function

How to search a text which is displayed in the page content?

<script type="text/javascript">
function searchAndHighlight(searchTerm, selector) {
if (searchTerm) {
var selector = selector || "body"; //use body as selector if none provided
var searchTermRegEx = new RegExp(searchTerm, "ig");
var matches = $(selector).text().match(searchTermRegEx);
if (matches) {
$('.highlighted').removeClass('highlighted'); //Remove old search highlights
$(selector).html($(selector).html()
.replace(searchTermRegEx, "<span class='highlighted'>" + searchTerm + "</span>"));
if ($('.highlighted:first').length) { //if match found, scroll to where the first one appears
$(window).scrollTop($('.highlighted:first').position().top);
}
return true;
}
}
return false;
}
$(document).ready(function () {
$('#btnSearch').on("click", function () {
if (!searchAndHighlight($('#txtSearch').val())) {
alert("No results found");
}
});
});
</script>
In above code i have searched and highlighted the text. But issue is if i type "in" it search whole page inner html and images. Screen short is given below.
How i search the text which is displayed in the page content.
Edited
So what i have thought of is p, div and span are the elements in which you should perform the check to find the substring.
var search = ['p', 'div', 'span'];
var pattern = searchTerm;
$.each(search, function(i){
var str = search[i];
var orgText = $(str).text();
orgText = orgText.replace(pattern, function($1){
return "<span class='highlighted'>" + $1 + "</span>"
});
$(str).html(orgText);
});
});
http://www.codeproject.com/Questions/617348/How-to-search-text-from-page-with-next-and-previou
I have completed my task using this plugin.

How to get css selector for an element using javascript?

Is there any jQuery plugin or javascript code that returns a CSS-selector that uniquely selects a particular element?
I'm looking for something with similar functionality as provided by the Copy CSS Path function in Chrome's developer tools, giving me a selector that looks something like this:
#question > table > tbody > tr:nth-child(2) > td > div > h2
Answers I tried
Get unique selector of element in Jquery
Get unique selector jQuery
Just found this post, had a look at the only answer and got terrified by it's complexity and by bizarre denial from using jQuery functions. Sorry for criticism, but i really i got stunned by this callback system. Here, have it in easy to use form:
function getCSSPath(el) {
let rendered_path_parts = [];
$( el ).parents().addBack().each((i, el) => {
const $el = $( el );
let current_el_path = $el.prop('tagName').toLowerCase();
if ($el.attr('id')) {
current_el_path += '#' + $el.attr('id');
}
if ($el.attr('class')) {
current_el_path += '.' + $el.attr('class').split(' ').join('.');
}
rendered_path_parts.push( current_el_path );
})
return rendered_path_parts.join(' ');
}
$.fn.extend({
getPath: function() {
return getCSSPath(this.length === 1 ? this : this.eq(0));
}
});
getCSSPath(some_element);
some_jquery_element.getPath();
Note that rendered selector will not include element' index, so it is less descriptive than selector developer tools can make for you.
Not perfect, but written fast (for You) : )
http://jsfiddle.net/k1qs69fz/7/
Code:
function getCSSPath(el, callback){
var fullPath = '';
var cssPathFn = function (el, callback){
var elPath = '';
elPath = $(el).prop('tagName').toLowerCase();
if(typeof $(el).attr('id') !== 'undefined'){
elPath = elPath+'#'+$(el).attr('id');
}
if(typeof $(el).attr('class') !== 'undefined'){
elPath = elPath+'.'+$(el).attr('class').split(' ').join('.');
}
fullPath = elPath+' '+fullPath;
if(typeof $(el).parent().prop('tagName') !== 'undefined'){
cssPathFn($(el).parent(), callback);
}
else{
callback(fullPath);
}
};
cssPathFn(el, callback);
}
Usage:
getCSSPath($('selector'), callbackFunction);
Function is based on tag name, id and class names, indexes are not supported.
Sample usage (for HTML code on JSFiddle):
$(document).ready(function (){
getCSSPath($('#lorem-ipsum'), function (path){
console.log(path);
});
});
Sample Result:
html body div#id1.c1.c2.c3 div#id2 div.c4.c5 span span.c6 ul li a span#lorem-ipsum
Here is a pure JavaScript implementation of what the others had using Element.attributes so it should work everywhere.
I made it a snippet so you can see that document.querySelector works with the selector found.
function getCSSSelector(el){
let selector = el.tagName.toLowerCase();
const attrs = el.attributes
for (var i = 0; i < attrs.length; i++) {
let attr = attrs.item(i)
if (attr.name === 'id') selector += `#${attr.value}`;
if (attr.name === 'class') selector += attr.value.split(' ').map((c) => `.${c}`).join('');
if (attr.name === 'name') selector += `[${attr.name}=${attr.value}]`;
}
return selector
}
let el = document.querySelector('input#id.abc');
let selector = getCSSSelector(el);
console.log(selector)
document.querySelector(selector).value = selector;
<input id="id", class="abc def" name='name' style='width: 200px'>

Using OR condition in combined attribute selector

I asked this question earlier and got it solved:
AND selector jQuery
But now I would like to know how I could add an OR condition to it.
I have this statement:
$('div.job:not([data-province="'+province+'"][data-employment="'+employment+'"][data-education="'+education+'"][data-branch="'+branch+'"])').fadeOut('slow');
And now I would like to fade them out if for example data-province="'+province+'" OR data-province="" (so empty).
Jsbin:
http://jsbin.com/qomub/14/edit
Try filter() with multiple selector
$('div.job').filter('[data-province="' + province + '"], [data-province=""]').fadeOut('slow');
Based on the update
$(document).ready(function () {
var $jobs = $('.job');
var $selects = $("#province, #employment, #education, #branch").on("change", function () {
var $filtered = $jobs;
$selects.each(function () {
if (this.value) {
$filtered = $filtered.filter('[data-' + this.id + '="' + this.value + '"], [data-' + this.id + '=""]');
}
});
$filtered.show();
$jobs.not($filtered).hide();
});
});
Demo: Fiddle

How can I get selector from jQuery object

$("*").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?
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
::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().
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>
Home
</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/
Did you try this ?
$("*").click(function(){
$(this).attr("id");
});
Try this:
$("*").click(function(event){
console.log($(event.handleObj.selector));
});
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;
}
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.
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. :)
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;
}
I've released a jQuery plugin: jQuery Selectorator, you can get selector like this.
$("*").on("click", function(){
alert($(this).getSelector().join("\n"));
return false;
});
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;
}
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?
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;
});
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 *.
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>
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);
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
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?
});
The best answer would be
var selector = '#something';
$(selector).anything(function(){
console.log(selector);
});

Categories

Resources