如何从jQuery对象获取选择器


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

有一种简单的方法可以从中获取选择器$(this)吗?有一种通过其选择器选择元素的方法,但是如何从元素中获取选择器呢?


只是好奇为什么这会有用?您在这里所说的(语义上)是针对每个引用为$(this)的元素...元素本身是$(this),因此不需要选择器。您有对象...
BenAlabaster 2010年

1
您是否确实意识到带有嵌套元素的点击会返回多个?div等,还是在这个关头太累了?
Mark Schultheiss

2
如果您可以描述所要完成的目标的“最终目标”,将很有帮助。这样您可能会获得更好的帮助。
jessegavin 2010年

3
可以用多种不同的方式选择元素。另外,选择器!== path。您希望如何处理此信息?
deceze

2
如果您已经找到了一个JQuery元素,并且正在使用一个需要选择器才能工作的插件/模块/子例程,这可能会很有用(可能超出您的控制范围)。
安迪

Answers:


57

好的,所以在问题提问者上方的评论中 Fidilip说,他/她真正要追求的是获取当前元素的路径。

这是一个脚本,它将“爬升” DOM祖先树,然后构建相当特定的选择器,包括单击项上的任何idclass属性。

看到它在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>

例如,如果您单击下面的HTML中的第二个列表嵌套列表项,则会得到以下结果:

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


2
谢谢!我将在连接上使用您的代码进行一个修改... join(" > ");,这将使我成为直接子代,从而获得更严格的路径。
不客气2014年

太棒了...我要在我的Chrome扩展程序中使用它。只是一件事,有时ID以冒号':'
开头

好电话@nonsensickle。我更新了示例,并删除了if语句。
jessegavin

上面的代码片段不返回SVG对象的类。这是适用于SVG的jsFiddle:http : //jsfiddle.net/mikemsq/vbykja4x/7/
mikemsq

32

::警告::
.selector自1.7版起已弃用,自1.9版起已删除

jQuery对象具有选择器属性,昨天在挖掘其代码时看到了该属性。不知道文档中是否定义了它的可靠性(以供将来验证)。但这有效!

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

编辑:如果要在事件内找到选择器,则理想情况下,该信息应该是事件本身而不是元​​素的一部分,因为一个元素可以通过多个选择器分配多个单击事件。一种解决方案是使用一个包装周围bind()click()等等,而不是直接添加将它添加的事件。

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

选择器作为名为的对象属性传递selector。以身份访问event.data.selector

让我们尝试一些标记(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
});

免责声明:请记住,与live()事件一样,如果使用DOM遍历方法,那么selector属性可能无效。

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

下面的代码将不起作用,因为它live依赖于选择器属性,在这种情况下,该属性是a.parent()-无效的选择器。

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

我们的addEvent方法将触发,但您也会看到错误的选择器- a.parent()


我认为这是我们从jquery =)中获得的最好结果。也许以后我会找到完整的解决方案。无论如何,这真的很方便,谢谢!=)
Fidilip 2010年

@MarkoDumic:必须已弃用。现在该链接已失效,并且仅告诉我们:No Such jQuery Method Exists
hippietrail

12
@Levitikon您是否真的不赞成三年的答案,因为现在已弃用该答案?!您确实应该编辑答案并提出警告
A. Wolff 2014年

22

与@drzaus合作,我们提出了以下jQuery插件。

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

精简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)

用法和注意事项

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

带有QUnit测试的小提琴

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


我喜欢在那里你要去,所以我做了一些修正/变更:* jQuery插件jQuery的杠杆效用$.map*可选的分隔符(需要剥离怪异的空标记名)*并不需要检查hasOwnPropertyforeach循环是安全的?
drzaus13年

感谢您的评论,我将在本周末的小提琴中设置一个适当的测试套件,并努力吸收您的建议。
2013年

1
@drzaus我已经更新了问题。我决定省去您添加的自定义分隔符,因为除分隔符外,其他分隔符' > '都将导致它不返回元素的选择器。
2013年

很酷,很不错的工作;以前没看过qunit。我认为分隔符仅用于演示,但现在我知道它是文字选择器路径的一部分。
drzaus


2

我发布了一个jQuery插件:jQuery Selectorator,您可以像这样获得选择器。

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

这是处理克隆兄弟姐妹的唯一方法,谢谢!
布鲁诺·佩雷斯

2

试试这个:

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

2

只需在$函数上添加一层即可:

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

现在您可以做类似的事情

$(“ a”)。选择器
并且即使在较新的jQuery版本上也将返回“ a”。


这正是我想要的。考虑到我已经寻找了多久,它可疑地运作良好!谢谢阿尔伯特。
Mark Notton


1

我在@jessegavin的修复程序中添加了一些修复程序。

如果元素上有一个ID,将立即返回。我还添加了名称属性检查和第n个子选择器,以防元素没有id,class或name的情况。

如果页面上有多种形式并具有相似的输入,则该名称可能需要进行范围界定,但我尚未处理。

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

1

即使经过上述解决方案,我也获得了多个元素,因此我扩展了dds1024的工作范围,以获取更多精确的dom元素。

例如DIV:nth-​​child(1)DIV:nth-​​child(3)DIV:nth-​​child(1)文章: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)

码:

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

1

这可以为您提供单击HTML元素的选择器路径-

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

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

    alert(selectorPath);

    return false;

});

1

好吧,我写了这个简单的jQuery插件。

这会检查ID或类名,并尝试提供尽可能多的准确选择器。

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

0

您是否要获取被点击的当前标签的名称?

如果是这样,请执行此操作。

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

您实际上无法获得“选择器”,您的情况下的“选择器”为*


我不需要标签名称。我只需要单击元素的路径即可。
Fidilip 2010年

1
AH,开始到达“元素的路径”与“选择器”有很大不同。因此,您需要该元素及其所有父节点名称吗?
Mark Schultheiss

我已经发布了另一个答案,该答案更有助于您实现实际目标。您应该编辑问题,使其更具体。
jessegavin 2010年

0

如果有人需要,我需要同样的Javascript代码。这仅是以上所选答案的翻译。

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

0

考虑到此处阅读的一些答案,我想提出以下建议:

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

可能对创建jQuery插件有用吗?


0

谢谢p1nox!

我的问题是将注意力重新放在修改表单部分的ajax调用上。

$.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();
                }
});

我只需要将您的函数封装在jQuery插件中:

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


-3

怎么样:

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

我不相信jQuery会存储使用的选择器文本。毕竟,如果您执行以下操作,那将如何工作:

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

jQuery内部构建选择器$('div').find('a').selectoris div a。如果不是通过jQuery函数创建事件,而是通过包装器创建事件,那么我相信选择器可以作为数据参数传递给事件处理程序。
阿努拉格2010年

1
这实际上是一个严肃的答案吗?
格伦(Glen)

-5

最好的答案是

var selector = '#something';

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

4
这似乎根本不是最好的答案。
亚历克斯(Alex)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.