如何从 jQuery 对象获取选择器

IT技术 javascript jquery jquery-selectors tree-traversal
2021-02-02 06:08:41
$("*").click(function(){
    $(this); // how can I get selector from $(this) ?
});

有没有一种简单的方法可以从中获取选择器$(this)有一种方法可以通过它的选择器选择一个元素,但是从 element 获取选择器呢?

6个回答

好的,所以在问题提问者上方的评论中,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

太棒了……我要把它用于我的 chrome 扩展。只是一件事,有时 id 与冒号 ':' 一起使用,我们可以将其替换为 '\\:'
2021-03-15 06:08:41
好电话@nonsensickle。我更新了我的例子,并删除了一个 if 语句。
2021-03-18 06:08:41
谢谢!我将使用您的代码对 join... 进行一次修改,这join(" > ");将使我获得直接的孩子,从而获得更严格的路径。
2021-03-31 06:08:41
上面的代码片段不返回 SVG 对象的类。这是一个适用于 SVG 的 jsFiddle:http : //jsfiddle.net/mikemsq/vbykja4x/7/
2021-04-06 06:08:41

::WARNING::
.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 遍历方法,选择器属性可能无效。

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

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

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

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

@Levitikon 你真的不赞成一个三年前的答案,因为它现在已经被弃用了吗?!您确实应该编辑答案并发出警告
2021-03-14 06:08:41
@MarkoDumic:肯定已经被弃用了。该链接现已失效,跟随它只会告诉我们:No Such jQuery Method Exists
2021-04-05 06:08:41
我认为这是我们从 jquery 中得到的最好的东西 =)。也许我稍后会找到完整的解决方案。无论如何,这真的很方便,谢谢!=)
2021-04-11 06:08:41

我们与@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/

感谢您的评论,本周末我将在小提琴中设置一个适当的测试套件,并努力纳入您的建议。
2021-03-17 06:08:41
很酷,不错的工作;之前没见过 qunit。我认为分隔符只是为了演示,但现在我知道它是文字选择器路径的一部分。
2021-03-20 06:08:41
我喜欢在那里你要去,所以我做了一些修正/变更:* jQuery插件jQuery的杠杆效用$.map*可选的分隔符(需要剥离怪异的空标记名)*并不需要检查hasOwnPropertyforeach循环是安全的?
2021-04-02 06:08:41
@drzaus 我已经更新了问题。我决定省略您添加的自定义分隔符,因为任何分隔符' > '都会导致它不返回元素的选择器。
2021-04-03 06:08:41

你试过这个吗?

 $("*").click(function(){
    $(this).attr("id"); 
 });
这仅在元素具有 ID 时才有效,因此不是很好。
2021-04-04 06:08:41
尽量不要使用*选择器,它很慢!
2021-04-06 06:08:41

试试这个:

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