web-dev-qa-db-fra.com

Comment obtenir un sélecteur d'objet jQuery

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

Existe-t-il un moyen facile de obtenir le sélecteur de $(this)? Il existe un moyen de sélectionner un élément par son sélecteur, mais comment obtenir le sélecteur d'un élément?

105
Fidilip

Ok, alors dans un commentaire au-dessus de la question, le demandeur Fidilip a déclaré que son objectif réel était d'obtenir le chemin d'accès à l'élément actuel.

Voici un script qui "gravira" l’arbre des ancêtres DOM, puis construira un sélecteur assez spécifique comprenant tous les attributs id ou class de l’élément cliqué.

Voir le travail sur 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>

Par exemple, si vous deviez cliquer sur l'élément de liste imbriqué de la deuxième liste dans le code HTML ci-dessous, vous obtiendriez le résultat suivant:

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

55
jessegavin

::ATTENTION::
. selector est obsolète à partir de la version 1.7, supprimé à partir de 1.9

L'objet jQuery a une propriété de sélecteur que j'ai vue lors de la fouille de son code hier. Je ne sais pas si cela est défini dans la documentation, mais quelle en est la fiabilité (pour une future mise à l'épreuve). Mais ça marche!

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

Edit : Si vous deviez trouver le sélecteur à l'intérieur de l'événement, ces informations devraient idéalement faire partie de l'événement lui-même et non de l'élément, car un élément pourrait avoir plusieurs événements de clic attribués par le biais de divers sélecteurs. Une solution serait d'utiliser un wrapper autour de bind(), click() etc. pour ajouter des événements au lieu de les ajouter directement.

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

Le sélecteur est transmis en tant que propriété d'un objet nommée selector. Accédez-y sous event.data.selector.

Essayons-le sur du balisage ( 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
});

Disclaimer : N'oubliez pas que, comme pour les événements live(), la propriété selector peut ne pas être valide si des méthodes de traversée DOM sont utilisées.

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

Le code ci-dessous NE fonctionnera PAS, car live repose sur la propriété selector, qui dans ce cas est a.parent() - un sélecteur non valide.

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

Notre méthode addEvent se déclenchera, mais vous verrez également le mauvais sélecteur - a.parent().

29
Anurag

En collaboration avec @drzaus, nous avons créé le plug-in jQuery suivant.

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

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

Usage et pièges

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

Fiddle w/tests QUnit

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

21
Will

Avez-vous essayé cela?

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

J'ai publié un plugin jQuery: jQuery Selectorator , vous pouvez obtenir un sélecteur comme celui-ci.

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

Essaye ça:

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

Ajoutez simplement une couche sur la fonction $ de cette façon:

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

Maintenant, vous pouvez faire des choses comme

$ ("a"). sélecteur
2
Albert Horta

http://www.selectorgadget.com/ est un bookmarklet conçu explicitement pour ce cas d'utilisation.

Cela dit, je suis d'accord avec la plupart des gens sur le fait que vous devriez juste apprendre vous-même les sélecteurs CSS, essayer de les générer avec du code n'est pas durable. :)

1
Paul Irish

Cela peut vous donner le chemin de sélecteur de l'élément HTML cliqué -

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

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

    alert(selectorPath);

    return false;

});
1
Vivek Kumar

J'obtenais plusieurs éléments même après les solutions ci-dessus, alors j’ai étendu le travail sur dds1024, pour encore plus d’éléments dom.

par exemple. DIV: n-enfant (1) DIV: n-enfant (3) DIV: n-enfant (1) ARTICLE: n-enfant (1) DIV: n-enfant (1) DIV: n-enfant (8) DIV: nième enfant (2) DIV: nième enfant (1) DIV: nième enfant (2) DIV: nième enfant (1) H4: nième enfant (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
Azghanvi

J'ai ajouté des corrections au correctif de @ jessegavin.

Cela reviendra immédiatement s'il y a un ID sur l'élément. J'ai également ajouté une vérification d'attribut de nom et un sélecteur de nième enfant au cas où un élément n'aurait pas d'identifiant, de classe ou de nom.

Le nom peut nécessiter une portée si plusieurs formulaires sur la page ont des entrées similaires, mais je ne l'ai pas encore gérée.

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
Dustin

Eh bien, j’ai écrit ce simple plugin jQuery.

Ceci vérifie l'identifiant ou le nom de la classe et essaie de donner le plus de sélecteur possible.

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

Essayez-vous d'obtenir le nom de la balise actuelle sur laquelle vous avez cliqué?

Si oui, fais ceci ..

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

Vous ne pouvez pas vraiment obtenir le "sélecteur", le "sélecteur" dans votre cas est *.

0
jessegavin

Compte tenu de certaines réponses lues ici, j'aimerais proposer ceci:

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

Peut-être utile pour créer un plugin jQuery?

0
p1nox

Code Javascript pour la même chose, au cas où quelqu'un en aurait besoin, comme moi. Ceci ne représente que la traduction de la réponse sélectionnée ci-dessus.

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

Merci p1nox!

Mon problème était de remettre l'accent sur un appel ajax qui modifiait une partie du formulaire.

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

Je devais juste encapsuler votre fonction dans un 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);
0
Patrick