Làm cách nào để lấy bộ chọn từ đối tượng jQuery


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

Có cách nào dễ dàng để lấy bộ chọn từ$(this) không? Có một cách để chọn một phần tử bằng bộ chọn của nó, nhưng còn việc lấy bộ chọn từ phần tử thì sao?


Chỉ tò mò tại sao điều này sẽ hữu ích? Những gì bạn đang nói ở đây (về mặt ngữ nghĩa) là đối với mọi phần tử được tham chiếu là $ (this) ... bản thân phần tử là $ (this) do đó bộ chọn không bắt buộc. Bạn đã có những đối tượng ...
BenAlabaster

1
bạn CÓ nhận ra rằng nhấp chuột với các phần tử lồng nhau sẽ trả về nhiều hơn một? div trong một cơ thể, vv hay tôi quá mệt mỏi vào thời điểm này?
Mark Schultheiss

2
Sẽ rất hữu ích nếu bạn có thể mô tả 'mục tiêu cuối cùng' của những gì bạn đang cố gắng hoàn thành. Bạn có thể nhận được sự trợ giúp tốt hơn theo cách đó.
jessegavin

3
Một phần tử có thể được chọn theo vô số cách khác nhau. Ngoài ra, đường dẫn selector! ==. Bạn mong đợi làm gì với thông tin này?
lừa dối

2
Điều này có thể hữu ích nếu bạn đã tìm thấy một phần tử JQuery và đang sử dụng plugin / mô-đun / chương trình con, yêu cầu bộ chọn hoạt động (có thể nằm ngoài tầm kiểm soát của bạn).
Andy

Câu trả lời:


57

Được rồi, vì vậy trong một nhận xét ở trên, người đặt câu hỏi đã Fidilipnói rằng điều mà anh ấy / cô ấy thực sự theo đuổi là tìm đường dẫn đến phần tử hiện tại.

Đây là một tập lệnh sẽ "leo lên" cây tổ tiên DOM và sau đó xây dựng bộ chọn khá cụ thể bao gồm bất kỳ idhoặc classthuộc tính nào trên mục được nhấp.

Xem nó hoạt động trên 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>

Ví dụ: nếu bạn nhấp vào mục danh sách lồng nhau thứ hai trong HTML bên dưới, bạn sẽ nhận được kết quả sau:

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


2
Cảm ơn! Tôi sẽ sử dụng mã của bạn với một lần sửa đổi khi tham gia ... join(" > ");, sẽ giúp tôi có được những đứa con ngay lập tức và do đó có một con đường nghiêm ngặt hơn .
nonsensickle

FANTASTIC ... tôi sẽ sử dụng nó cho tiện ích mở rộng chrome của tôi. Chỉ cần một điều, id đôi khi được sử dụng với ruột ':' tiền tố, mà chúng tôi có thể thay thế với '\\:'
Savaratkar

Tốt cuộc gọi @nonsensickle. Tôi đã cập nhật ví dụ của mình và cũng xóa câu lệnh if.
jessegavin

Đoạn mã trên không trả về các lớp cho các đối tượng SVG. Đây là jsFiddle hoạt động cho SVG: http://jsfiddle.net/mikemsq/vbykja4x/7/ .
mikemsq

32

:: CẢNH BÁO ::
.selector không được dùng nữa kể từ phiên bản 1.7, bị loại bỏ kể từ 1.9

Đối tượng jQuery có thuộc tính bộ chọn mà tôi đã thấy khi đào mã của nó ngày hôm qua. Không biết nếu nó được định nghĩa trong tài liệu thì nó đáng tin cậy đến mức nào (để kiểm chứng trong tương lai). Nhưng nó đã có tác dụng!

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

Chỉnh sửa : Nếu bạn tìm bộ chọn bên trong sự kiện, thông tin đó lý tưởng phải là một phần của chính sự kiện chứ không phải phần tử vì một phần tử có thể có nhiều sự kiện nhấp chuột được chỉ định thông qua các bộ chọn khác nhau. Một giải pháp sẽ là sử dụng một trình bao bọc xung quanh bind(), click()v.v. để thêm các sự kiện thay vì thêm trực tiếp.

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

Bộ chọn đang được chuyển dưới dạng thuộc tính của đối tượng được đặt tên selector. Truy cập nó với tư cách event.data.selector.

Hãy thử nó trên một số đánh dấu ( 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
});

Tuyên bố từ chối trách nhiệm : Hãy nhớ rằng cũng giống như với live()các sự kiện, thuộc tính bộ chọn có thể không hợp lệ nếu sử dụng các phương pháp truyền tải DOM.

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

Mã bên dưới sẽ KHÔNG hoạt động, vì live phụ thuộc vào thuộc tính bộ chọn mà trong trường hợp này là a.parent()- bộ chọn không hợp lệ.

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

addEventPhương pháp của chúng tôi sẽ kích hoạt, nhưng bạn cũng sẽ thấy bộ chọn sai - a.parent().


Mình nghĩ đây là thứ tốt nhất mà chúng ta nhận được từ jquery =). Có lẽ tôi sẽ tìm thấy giải pháp đầy đủ sau. Dù sao điều này có thể thực sự tiện dụng, thx! =)
Fidilip 10/03/10

@MarkoDumic: Chắc hẳn đã không được dùng nữa. Các liên kết tại là chết và sau đó cho chúng ta biết chỉ:No Such jQuery Method Exists
hippietrail

12
@Levitikon Bạn có thực sự phản đối một câu trả lời đã ba năm tuổi vì bây giờ nó không còn được dùng nữa không ?! Bạn thực sự nên chỉnh sửa câu trả lời và đặt một cảnh báo
A. Wolff

22

Cộng tác với @drzaus, chúng tôi đã đưa ra plugin jQuery sau.

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 được rút gọn

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

Cách sử dụng và 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>

Kiểm tra Fiddle w / QUnit

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


Tôi thích nơi bạn sẽ đến, vì vậy tôi đã thực hiện một số sửa chữa / thay đổi : * plugin jQuery sử dụng tiện ích jQuery $.map* dấu phân cách tùy chọn (cần loại bỏ tagNames trống kỳ lạ) * bạn không cần phải kiểm tra hasOwnPropertymột foreachvòng lặp để an toàn?
drzaus

Cảm ơn các ý kiến ​​đóng góp, tôi sẽ thiết lập một bộ thử nghiệm phù hợp trong thời gian ngắn vào cuối tuần này và làm việc để kết hợp các đề xuất của bạn.
Will

1
@drzaus Tôi đã cập nhật câu hỏi. Tôi quyết định loại bỏ dấu phân cách tùy chỉnh mà bạn đã thêm vì bất kỳ dấu phân tách nào khác ngoài ' > 'sẽ khiến nó không trả về bộ chọn của phần tử.
Sẽ vào

công việc tuyệt vời, tốt đẹp; chưa từng thấy qunit trước đây. tôi đã tìm ra dấu phân cách chỉ để trình bày, nhưng bây giờ tôi hiểu rằng nó là một phần của đường dẫn bộ chọn theo nghĩa đen.
drzaus

5

Bạn đã thử cái này chưa?

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

3
Cố gắng không sử dụng *bộ chọn, nó rất chậm!
Ben Carey

3
Điều này chỉ hoạt động nếu phần tử có một ID không quá tuyệt vời.
Glen

2

Tôi đã phát hành một plugin jQuery: jQuery Selectorator , bạn có thể nhận được bộ chọn như thế này.

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

Đây là cách tiếp cận duy nhất liên quan đến anh chị em nhân bản, cảm ơn!
Bruno Peres

2

Thử cái này:

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

2

Chỉ cần thêm một lớp trên hàm $ theo cách này:

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

Bây giờ bạn có thể làm những việc như

$ ("a"). bộ chọn
và sẽ trả về "a" ngay cả trên các phiên bản jQuery mới hơn.


Điều này làm chính xác những gì tôi muốn. Nó hoạt động tốt một cách đáng ngờ khi tôi đã tìm kiếm điều này trong bao lâu! Cảm ơn Albert.
Mark Notton

1

http://www.selectorgadget.com/ là một bookmarklet được thiết kế rõ ràng cho trường hợp sử dụng này.

Điều đó nói rằng, tôi đồng ý với hầu hết mọi người rằng bạn chỉ nên tự học các bộ chọn CSS, việc cố gắng tạo chúng bằng mã là không bền vững. :)


1

Tôi đã thêm một số bản sửa lỗi vào bản sửa lỗi của @ jessegavin.

Điều này sẽ trả về ngay lập tức nếu có một ID trên phần tử. Tôi cũng đã thêm kiểm tra thuộc tính tên và bộ chọn con thứ n trong trường hợp một phần tử không có id, lớp hoặc tên.

Tên có thể cần xác định phạm vi trong trường hợp có nhiều biểu mẫu trên trang và có các đầu vào tương tự, nhưng tôi chưa xử lý điều đó.

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

Tôi đã nhận được nhiều phần tử ngay cả sau các giải pháp trên, vì vậy tôi đã mở rộng công việc dds1024, cho phần tử dom có ​​nhiều chân cắm hơn nữa.

ví dụ DIV: nth-child (1) DIV: thứ n-con (3) DIV: thứ n-con (1) ĐIỀU: thứ n-con (1) DIV: thứ n-con (1) DIV: thứ n-con (8) DIV : nth-child (2) DIV: thứ n-con (1) DIV: thứ n-con (2) DIV: thứ n-con (1) H4: thứ n-con (2)

Mã:

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

Điều này có thể giúp bạn chọn đường dẫn của phần tử HTML được nhấp vào-

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

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

    alert(selectorPath);

    return false;

});

1

Vâng, tôi đã viết plugin jQuery đơn giản này.

Thao tác này sẽ kiểm tra id hoặc tên lớp và cố gắng cung cấp bộ chọn chính xác nhất có thể.

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

Bạn đang cố gắng lấy tên của thẻ hiện tại đã được nhấp vào?

Nếu vậy, hãy làm điều này ..

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

Bạn thực sự không thể có được "bộ chọn", "bộ chọn" trong trường hợp của bạn là như vậy *.


Tôi không cần tên thẻ. Tôi chỉ cần đường dẫn đến phần tử tôi đã nhấp vào.
Fidilip

1
AH, bắt đầu đến một nơi nào đó "đường dẫn đến phần tử" khác nhiều so với "bộ chọn". VẬY bạn cần phần tử và tất cả các tên nút cha của nó?
Mark Schultheiss

Tôi đã đăng một câu trả lời khác hướng tới mục tiêu thực tế của bạn. Bạn nên chỉnh sửa câu hỏi để nó cụ thể hơn.
jessegavin

0

Mã Javascript cho giống nhau, trong trường hợp bất kỳ ai cần, vì tôi cần nó. Đây chỉ là bản dịch của câu trả lời đã chọn ở trên.

    <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

Có tính đến một số câu trả lời đọc ở đây, tôi muốn đề xuất điều này:

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

Có thể hữu ích để tạo một plugin jQuery?


0

Cảm ơn bạn p1nox!

Vấn đề của tôi là tập trung trở lại vào lệnh gọi ajax đang sửa đổi một phần của biểu mẫu.

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

Tôi chỉ cần gói gọn hàm của bạn trong một plugin 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

Làm thế nào về:

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

Tôi không tin rằng jQuery lưu trữ văn bản bộ chọn đã được sử dụng. Rốt cuộc, điều đó sẽ hoạt động như thế nào nếu bạn làm điều gì đó như thế này:

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

jQuery xây dựng nội bộ bộ chọn $('div').find('a').selectordiv a. Nếu các sự kiện không được tạo thông qua các hàm jQuery mà thay vào đó là một trình bao bọc, tôi tin rằng bộ chọn có thể được chuyển làm đối số dữ liệu cho trình xử lý sự kiện.
Anurag

1
Đây có thực sự là một câu trả lời nghiêm túc?
Glen

-5

Câu trả lời tốt nhất sẽ là

var selector = '#something';

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

4
Đây có vẻ không phải là câu trả lời hay nhất.
Alex
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.