Wie kann ich einen Selektor vom jQuery-Objekt erhalten?


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

Gibt es eine einfache Möglichkeit, einen Selektor$(this) zu erhalten ? Es gibt eine Möglichkeit, ein Element anhand seines Selektors auszuwählen, aber wie sieht es aus , wenn der Selektor vom Element abgerufen wird ?


Nur neugierig, warum das nützlich wäre? Was Sie hier (semantisch) sagen, gilt für jedes Element, das als $ (this) bezeichnet wird ... das Element selbst ist $ (this), daher ist der Selektor nicht erforderlich. Sie haben das Objekt ...
BenAlabaster

1
Sie wissen, dass der Klick mit verschachtelten Elementen mehr als eins zurückgibt? Div in einem Körper usw. oder bin ich zu diesem Zeitpunkt zu müde?
Mark Schultheiss

2
Es wäre hilfreich, wenn Sie das „Endziel“ dessen beschreiben könnten, was Sie erreichen möchten. Auf diese Weise erhalten Sie möglicherweise bessere Hilfe.
Jessegavin

3
Ein Element kann auf vielfältige Weise ausgewählt werden. Auch Selektor! == Pfad. Was erwarten Sie mit diesen Informationen?
Täuschung

2
Dies kann nützlich sein, wenn Sie bereits ein JQuery-Element gefunden haben und ein Plugin / Modul / Unterprogramm verwenden, für dessen Funktion ein Selektor erforderlich ist (möglicherweise außerhalb Ihrer Kontrolle).
Andy

Antworten:


57

Ok, also Fidilipsagte der Fragesteller in einem Kommentar oben , dass er / sie wirklich danach strebt , den Weg zum aktuellen Element zu finden.

Hier ist ein Skript, das den DOM-Ahnenbaum "klettert" und dann einen ziemlich spezifischen Selektor erstellt, einschließlich eines idoder classmehrerer Attribute für das angeklickte Element.

Sehen Sie, wie es auf jsFiddle funktioniert: 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>

Wenn Sie beispielsweise auf das zweite Listenelement mit verschachtelter Liste im folgenden HTML-Code klicken, erhalten Sie das folgende Ergebnis:

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


2
Vielen Dank! Ich werde Ihren Code mit einer Änderung auf dem Join verwenden ... join(" > ");, wird mir die unmittelbaren Kinder und damit einen strengeren Pfad geben.
unsinnig

FANTASTISCH ... werde es für meine Chrome-Erweiterung verwenden. Nur eine Sache, manchmal wird id mit dem vorangestellten Doppelpunkt ':' verwendet, den wir durch '\\:' ersetzen können
Savaratkar

Guter Anruf @nonsensickle. Ich habe mein Beispiel aktualisiert und auch eine if-Anweisung entfernt.
Jessegavin

Das obige Codefragment gibt keine Klassen für SVG-Objekte zurück. Hier ist eine jsFiddle, die für SVG funktioniert: http://jsfiddle.net/mikemsq/vbykja4x/7/ .
Mikemsq

32

::
WARNUNG :: .selector ist ab Version 1.7 veraltet und ab Version 1.9 entfernt

Das jQuery-Objekt hat eine Selector-Eigenschaft, die ich gestern beim Eingraben seines Codes gesehen habe. Ich weiß nicht, ob es in den Dokumenten definiert ist, wie zuverlässig es ist (für die Zukunftssicherung). Aber es funktioniert!

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

Bearbeiten : Wenn Sie den Selektor innerhalb des Ereignisses finden, sollten diese Informationen idealerweise Teil des Ereignisses selbst und nicht des Elements sein, da einem Element mehrere Klickereignisse über verschiedene Selektoren zugewiesen werden können. Eine Lösung wäre, einen Wrapper zu verwenden bind(), click()um Ereignisse usw. hinzuzufügen, anstatt sie direkt hinzuzufügen.

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

Der Selektor wird als Eigenschaft eines Objekts mit dem Namen übergeben selector. Greifen Sie als zu event.data.selector.

Versuchen wir es mit einem 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
});

Haftungsausschluss : Beachten Sie, dass live()die Selector-Eigenschaft genau wie bei Ereignissen ungültig sein kann, wenn DOM-Traversal-Methoden verwendet werden.

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

Der folgende Code funktioniert NICHT, da er livevon der Selector-Eigenschaft abhängt, die in diesem Fall a.parent()ein ungültiger Selector ist.

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

Unsere addEventMethode wird ausgelöst, aber auch Sie werden den falschen Selektor sehen - a.parent().


Ich denke, das ist das Beste, was wir von jquery bekommen können =). Vielleicht finde ich später die vollständige Lösung. Auf jeden Fall kann das sehr praktisch sein, danke! =)
Fidilip

@ MarkoDumic: Muss veraltet gewesen sein. Der Link ist jetzt tot und der folgende sagt uns nur:No Such jQuery Method Exists
Hippietrail

12
@Levitikon Stimmen Sie eine drei Jahre alte Antwort wirklich ab, weil sie jetzt veraltet ist?! Sie sollten in der Tat die Antwort bearbeiten und eine Warnung
A. Wolff

22

In Zusammenarbeit mit @drzaus haben wir das folgende jQuery-Plugin entwickelt.

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

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

Verwendung und Fallstricke

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

Geige mit QUnit-Tests

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


Mir hat gefallen, wohin Sie wollten, also habe ich einige Korrekturen / Änderungen vorgenommen : * Das jQuery-Plugin nutzt das Dienstprogramm jQuery $.map* Optionales Trennzeichen (muss seltsame leere Tag-Namen entfernen) * Müssen Sie nicht hasOwnPropertyin einer foreachSchleife einchecken , um sicher zu sein?
Drzaus

Vielen Dank für die Kommentare. Ich werde dieses Wochenende eine richtige Testsuite einrichten und daran arbeiten, Ihre Vorschläge einzubeziehen.
Will

1
@drzaus Ich habe die Frage aktualisiert. Ich habe beschlossen, das von Ihnen hinzugefügte benutzerdefinierte Trennzeichen wegzulassen, da jedes andere Trennzeichen ' > 'dazu führen würde, dass der Selektor des Elements nicht zurückgegeben wird.
Will

coole, schöne Arbeit; hatte Qunit noch nie gesehen. Ich dachte, das Trennzeichen sei nur zur Präsentation gedacht, aber jetzt verstehe ich, dass es Teil des wörtlichen Auswahlpfads ist.
Drzaus

5

Hast du das versucht?

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

3
Versuchen Sie, den *Selektor nicht zu benutzen , er ist sehr langsam!
Ben Carey

3
Dies funktioniert nur, wenn das Element eine ID hat, also nicht so toll.
Glen

2

Ich habe ein jQuery-Plugin veröffentlicht: jQuery Selectorator , Sie können Selector wie folgt erhalten.

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

Dies ist der einzige Ansatz, der sich mit geklonten Geschwistern befasst, danke!
Bruno Peres

2

Versuche dies:

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

2

Fügen Sie einfach eine Ebene über der $ -Funktion hinzu:

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

Jetzt können Sie Dinge wie tun

$ ("a"). Selektor
und gibt auch bei neueren jQuery-Versionen "a" zurück.


Das macht genau das, was ich wollte. Es funktioniert verdächtig gut, wenn man bedenkt, wie lange ich danach gesucht habe! Danke Albert.
Mark Notton

1

http://www.selectorgadget.com/ ist ein Lesezeichen, das explizit für diesen Anwendungsfall entwickelt wurde.

Trotzdem stimme ich den meisten anderen Menschen darin zu, dass Sie CSS-Selektoren nur selbst lernen sollten. Der Versuch, sie mit Code zu generieren, ist nicht nachhaltig. :) :)


1

Ich habe @ jessegavins Fix einige Korrekturen hinzugefügt.

Dies wird sofort zurückgegeben, wenn das Element eine ID enthält. Ich habe auch eine Namensattributprüfung und einen n-ten untergeordneten Selektor hinzugefügt, falls ein Element keine ID, Klasse oder keinen Namen hat.

Der Name muss möglicherweise überprüft werden, falls mehrere Formulare auf der Seite vorhanden sind und ähnliche Eingaben vorliegen, aber das habe ich noch nicht behandelt.

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

Ich habe sogar nach den oben genannten Lösungen mehrere Elemente erhalten, daher habe ich die Arbeit mit dds1024 erweitert, um ein noch genaueres dom-Element zu erhalten.

zB DIV: n-tes Kind (1) DIV: n-tes Kind (3) DIV: n-tes Kind (1) ARTIKEL: n-tes Kind (1) DIV: n-tes Kind (1) DIV: n-tes Kind (8) DIV : n-tes Kind (2) DIV: n-tes Kind (1) DIV: n-tes Kind (2) DIV: n-tes Kind (1) H4: n-tes Kind (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;
}

1

Dies kann Ihnen den Auswahlpfad des angeklickten HTML-Elements anzeigen.

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

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

    alert(selectorPath);

    return false;

});

1

Nun, ich habe dieses einfache jQuery-Plugin geschrieben.

Dies überprüft die ID oder den Klassennamen und versucht, so genau wie möglich zu wählen.

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

Versuchen Sie, den Namen des aktuellen Tags abzurufen, auf das geklickt wurde?

Wenn ja, mach das ..

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

Sie können den "Selektor" nicht wirklich bekommen, der "Selektor" in Ihrem Fall ist *.


Ich brauche den Tag-Namen nicht. Ich brauche nur einen Pfad zu dem Element, auf das ich geklickt habe.
Fidilip

1
AH, irgendwohin zu gelangen, ist viel anders als "Selektor". Also brauchen Sie das Element und alle übergeordneten Knotennamen?
Mark Schultheiss

Ich habe eine weitere Antwort veröffentlicht, die Ihrem tatsächlichen Ziel näher kommt. Sie sollten die Frage so bearbeiten, dass sie spezifischer ist.
Jessegavin

0

Javascript-Code für das gleiche, falls jemand es braucht, wie ich es brauchte. Dies ist nur die Übersetzung nur der oben ausgewählten Antwort.

    <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

Unter Berücksichtigung einiger hier gelesener Antworten möchte ich Folgendes vorschlagen:

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

Vielleicht nützlich, um ein jQuery-Plugin zu erstellen?


0

Danke p1nox!

Mein Problem bestand darin, mich wieder auf einen Ajax-Aufruf zu konzentrieren, der einen Teil des Formulars veränderte.

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

Ich musste nur Ihre Funktion in ein jQuery-Plugin kapseln:

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

Wie wäre es mit:

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

Ich glaube nicht, dass jQuery den verwendeten Auswahltext speichert. Wie würde das funktionieren, wenn Sie so etwas tun würden:

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

jQuery erstellt intern den Selektor $('div').find('a').selectoris div a. Wenn die Ereignisse nicht über die jQuery-Funktionen, sondern über einen Wrapper erstellt werden, kann der Selektor meines Erachtens als Datenargumente an den Ereignishandler übergeben werden.
Anurag

1
Ist das eigentlich eine ernsthafte Antwort?
Glen

-5

Die beste Antwort wäre

var selector = '#something';

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

4
Dies scheint überhaupt nicht die beste Antwort zu sein.
Alex
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.