jQuery 객체에서 선택기를 어떻게 얻을 수 있습니까?


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

선택기$(this)얻는 쉬운 방법이 있습니까? 선택기로 요소를 선택하는 방법이 있지만 요소에서 선택자를 가져 오는 것은 어떻습니까?


이것이 왜 유용한 지 궁금하십니까? 여기서 말하는 것은 (의미 론적으로) $ (this)로 참조되는 모든 요소에 대한 것입니다 ... 요소 자체는 $ (this)이므로 선택자가 필요하지 않습니다. 개체가 있습니다 ...
BenAlabaster

1
중첩 된 요소가있는 클릭이 둘 이상의 결과를 반환한다는 것을 알고 있습니까? div in a body, etc. 아니면이 시점에서 너무 피곤합니까?
Mark Schultheiss

2
달성하려는 '최종 목표'를 설명 할 수 있다면 도움이 될 것입니다. 그렇게하면 더 나은 도움을받을 수 있습니다.
jessegavin 2010 년

3
다양한 방법으로 요소를 선택할 수 있습니다 . 또한 선택기! == 경로. 이 정보로 무엇을 하시겠습니까?
deceze

2
이것은 이미 JQuery 요소를 찾았고 플러그인 / 모듈 / 서브 루틴을 사용하는 경우 유용 할 수 있습니다.이 경우 선택기가 작동해야합니다 (아마도 제어 할 수 없음).
Andy

답변:


57

좋아요, 질문 위의 주석에서 질문자 Fidilip는 그가 실제로 추구 하는 것은 현재 요소의 경로를 얻는 것입니다.

다음은 DOM 상위 트리를 "등반"한 다음 클릭 한 항목의 id또는 class속성을 포함하여 상당히 구체적인 선택기를 구축하는 스크립트입니다 .

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(" > ");, 나에게 직계 자식을 가져 오므로 더 엄격한 경로를 얻을 수 있습니다.
nonsensickle

환상적 ... 내 크롬 확장 프로그램에 사용할 것입니다. 우리가 대체 할 수있는 접두어로 ''그냥 한 가지, 언젠가 ID가 콜론 사용되는 '\\'
Savaratkar

@nonsensickle 좋은 전화. 예제를 업데이트하고 if 문도 제거했습니다.
jessegavin

위의 코드 조각은 SVG 개체에 대한 클래스를 반환하지 않습니다. SVG에서 작동하는 jsFiddle은 http://jsfiddle.net/mikemsq/vbykja4x/7/ 입니다.
mikemsq

32

:: 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 순회 메서드를 사용하면 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 지금은 더 이상 사용되지 않기 때문에 3 년 된 답변에 대해 정말 반대 투표하고 있습니까?! 실제로 답변을 편집하고 경고를 넣어야합니다
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);

축소 된 자바 스크립트

// 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* 선택적 구분 기호 (이상한 빈 tagNames를 제거해야 함) * 안전 hasOwnProperty을 위해 foreach루프를 확인할 필요가 없습니까?
drzaus 2013 년

의견을 보내 주셔서 감사합니다. 이번 주말에 적절한 테스트 도구 모음을 설정하고 제안 사항을 반영 할 것입니다.

1
@drzaus 질문을 업데이트했습니다. 추가 한 사용자 지정 구분 기호를 제외하기로 결정했습니다. 다른 구분 기호 ' > '로 인해 요소의 선택자를 반환하지 않습니다.

멋지고 좋은 일 전에 qunit을 본 적이 없었습니다. 구분 기호가 표시 용이라고 생각했지만 이제는 문자 선택자 경로의 일부임을 알 수 있습니다.
drzaus 2013-04-02

5

이거 해봤 어?

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

3
*선택기 를 사용하지 마십시오. 매우 느립니다!
Ben Carey

3
이것은 요소에 ID가 너무 크지 않은 경우에만 작동합니다.
Glen

2

jQuery 플러그인을 출시했습니다 : jQuery Selectorator , 이런 선택기를 얻을 수 있습니다.

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

이것은 복제 된 형제 자매를 다루는 유일한 방법입니다. 감사합니다!
Bruno Peres 2017 년

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"). selector
최신 jQuery 버전에서도 "a"를 반환합니다.


이것은 내가 원하는 것을 정확하게 수행합니다. 내가 이것을 얼마나 오랫동안 찾았는지 감안할 때 의심스럽게 잘 작동합니다! 알버트 감사합니다.
Mark Notton

1

http://www.selectorgadget.com/ 은이 사용 사례를 위해 명시 적으로 설계된 북마크릿입니다.

즉, CSS 선택자를 직접 배워야하며 코드로 생성하려는 시도는 지속 가능하지 않다는 점에서 다른 대부분의 사람들과 동의합니다. :)


1

@jessegavin의 수정 사항에 몇 가지 수정 사항을 추가했습니다.

요소에 ID가 있으면 즉시 반환됩니다. 또한 요소에 ID, 클래스 또는 이름이없는 경우 이름 속성 검사와 n 번째 자식 선택기를 추가했습니다.

페이지에 여러 양식이 있고 유사한 입력이있는 경우 이름에 범위 지정이 필요할 수 있지만 아직 처리하지 않았습니다.

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

위의 솔루션 후에도 여러 요소를 얻었으므로 더 정확한 dom 요소를 위해 dds1024 작업을 확장했습니다.

예 : 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 : n 번째 -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').selector입니다 div a. 이벤트가 jQuery 함수를 통해 생성되지 않고 대신 래퍼를 사용하는 경우 선택기가 데이터 인수로 이벤트 처리기에 전달 될 수 있다고 생각합니다.
Anurag

1
이것은 실제로 심각한 대답입니까?
글렌

-5

가장 좋은 대답은

var selector = '#something';

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

4
이것은 전혀 최선의 대답이 아닌 것 같습니다.
Alex
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.