JQuery nesnesinden nasıl seçici alabilirim


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

Selector'ı almanın$(this) kolay bir yolu var mı ? Seçicisine göre bir öğe seçmenin bir yolu var, ancak seçiciyi öğeden almaya ne dersiniz ?


Bunun neden yararlı olacağını merak mı ediyorsunuz? Burada (anlamsal olarak) söylediğiniz, $ (this) olarak belirtilen her öğe için ... öğenin kendisi $ (this) 'dir, bu nedenle seçici gerekli değildir. Nesneye sahipsin ...
BenAlabaster

1
İç içe yerleştirilmiş öğelere sahip tıklamanın birden fazla döndüreceğinin farkında mısınız? bir vücutta div vs. yoksa bu noktada çok mu yorgunum?
Mark Schultheiss

2
Başarmaya çalıştığınız şeyin 'nihai amacını' tarif edebilmeniz yardımcı olacaktır. Bu şekilde daha iyi yardım alabilirsiniz.
jessegavin

3
Bir eleman sayısız farklı yolla seçilebilir . Ayrıca seçici! == yol. Bu bilgilerle ne yapmayı bekliyorsunuz?
deceze

2
Zaten bir JQuery öğesi bulduysanız ve çalışması için bir seçici gerektiren bir eklenti / modül / alt yordam kullanıyorsanız (muhtemelen kontrolünüz dışında) bu yararlı olabilir.
Andy

Yanıtlar:


57

Tamam, soruyu soran yukarıdaki bir yorumda, Fidilipgerçekte peşinde olduğu şeyin mevcut öğeye giden yolu bulmak olduğunu söyledi.

İşte DOM ata ağacına "tırmanacak" ve ardından tıklanan öğenin herhangi bir idveya classözniteliğini içeren oldukça özel bir seçici oluşturacak bir komut dosyası .

JsFiddle üzerinde çalışırken görün: 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>

Örneğin, aşağıdaki HTML'de 2. liste iç içe liste öğesini tıklarsanız, aşağıdaki sonucu alırsınız:

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


2
Teşekkürler! Kodunuzu birleştirme üzerinde bir değişiklik ile join(" > ");kullanacağım ... bana hemen çocukları ve dolayısıyla daha katı bir yol getirecek .
anlamsız

FANTASTIC ... Chrome uzantım için kullanacağım. Tek bir şey var, id bazen iki nokta üst üste ':' ile kullanılır ve bunu '\\:' ile değiştirebiliriz.
öneklidir

İyi çağrı @nonsensickle. Örneğimi güncelledim ve bir if ifadesini de kaldırdım.
jessegavin

Yukarıdaki kod parçası, SVG nesneleri için sınıflar döndürmez. İşte SVG için çalışan bir jsFiddle: http://jsfiddle.net/mikemsq/vbykja4x/7/ .
mikemsq

32

:: UYARI ::
.selector, 1.7 sürümü itibariyle kullanımdan kaldırıldı, 1.9'dan itibaren kaldırıldı

JQuery nesnesi, dün kodunu kazarken gördüğüm bir selector özelliğine sahip. Dokümanlarda tanımlanıp tanımlanmadığını bilmiyorum, ne kadar güvenilir olduğunu (gelecekte prova için). Ama işe yarıyor!

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

Düzenleme : Seçiciyi etkinliğin içinde bulacak olsaydınız, bu bilgi ideal olarak öğenin değil olayın kendisinin bir parçası olmalıdır, çünkü bir öğenin çeşitli seçiciler aracılığıyla atanmış birden çok tıklama etkinliği olabilir. Bir çözüm bind(), click()olayları doğrudan eklemek yerine etrafına bir sarmalayıcı vb. Eklemek olabilir.

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

Seçici, adlı bir nesnenin özelliği olarak aktarılıyor selector. Olarak erişin event.data.selector.

Bunu bazı işaretlemelerde deneyelim ( 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
});

Sorumluluk Reddi : Aynı live()olaylarda olduğu gibi , DOM geçiş yöntemleri kullanılırsa selector özelliğinin geçersiz olabileceğini unutmayın.

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

Aşağıdaki kod live, bu durumda a.parent()geçersiz bir seçici olan selector özelliğine bağlı olduğundan çalışmayacaktır .

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

bizim addEvent ateşlenecek, ancak siz de yanlış seçiciyi göreceksiniz - a.parent().


Sanırım jquery =) 'den alabileceğimiz en iyi şey bu. Belki tam çözümü daha sonra bulurum. Her neyse, bu gerçekten kullanışlı olabilir, teşekkürler! =)
Fidilip

@MarkoDumic: Kullanımdan kaldırılmış olmalı. Bağlantı artık kesildi ve bunu takiben bize sadece şunu söylüyor:No Such jQuery Method Exists
hippietrail

12
@Levitikon Artık kullanımdan kaldırıldığı için üç yaşında bir cevabı reddiyor musunuz ?! Cevabı gerçekten düzenlemeli ve bir uyarı koymalısınız
A. Wolff

22

@Drzaus ile birlikte aşağıdaki jQuery eklentisini bulduk.

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

Küçültülmüş 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)

Kullanım ve 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>

QUnit testleri ile Fiddle

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


Nereye gittiğini beğendim, bu yüzden bazı düzeltmeler / değişiklikler yaptım : * jQuery eklentisi jQuery yardımcı programından yararlanıyor $.map* isteğe bağlı sınırlayıcı (garip boş tagNames'i kaldırması gerekiyor) * güvenli olmak için hasOwnPropertybir foreachdöngüyü kontrol etmenize gerek yok mu?
drzaus

Yorumlarınız için teşekkürler, bu hafta sonu bir keman için uygun bir test paketi oluşturacağım ve önerilerinizi dahil etmek için çalışacağım.
Will

1
@drzaus Soruyu güncelledim. Eklediğiniz özel sınırlayıcıyı dışarıda bırakmaya karar verdim, çünkü başka herhangi bir sınırlayıcı ' > ', öğenin seçicisini döndürmemesine neden olabilir.
Will

güzel, güzel iş; daha önce qunit görmemişti. Sınırlayıcının sadece sunum için olduğunu düşündüm, ancak şimdi bunun literal seçici yolunun bir parçası olduğunu anladım.
drzaus

5

Bunu denedin mi

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

3
*Seçiciyi kullanmamaya çalışın , çok yavaş!
Ben Carey

3
Bu, yalnızca öğenin bir kimliği varsa o kadar da büyük değilse çalışır.
Glen

2

Bir jQuery eklentisi yayınladım: jQuery Selectorator , bunun gibi seçici alabilirsiniz.

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

Klonlanmış kardeşlerle ilgilenen tek yaklaşım bu, teşekkürler!
Bruno Peres

2

Bunu dene:

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

2

$ İşlevinin üzerine şu şekilde bir katman ekleyin:

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

Şimdi şöyle şeyler yapabilirsiniz

$ ( "A"). Seçici
ve daha yeni jQuery sürümlerinde bile "a" döndürür.


Bu tam olarak istediğimi yapıyor. Bunu ne kadar süredir aradığıma bakılırsa şüpheli bir şekilde işe yarıyor! Teşekkür ederim Albert.
Mark Notton

1

http://www.selectorgadget.com/ , bu kullanım durumu için özel olarak tasarlanmış bir yer imidir.

Bununla birlikte, CSS seçicilerini kendiniz öğrenmeniz gerektiği, kodla üretmeye çalışmanın sürdürülebilir olmadığı konusunda diğer birçok insanla aynı fikirdeyim. :)


1

@ Jessegavin'in düzeltmesine bazı düzeltmeler ekledim.

Öğede bir kimlik varsa bu hemen geri dönecektir. Ayrıca bir elemanın kimliği, sınıfı veya adı olmaması durumunda bir isim öznitelik kontrolü ve bir nth-çocuk seçici ekledim.

Sayfada birden fazla form olması ve benzer girişlerin olması durumunda adın kapsamına ihtiyaç duyabilir, ancak bunu henüz ele almadım.

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

Yukarıdaki çözümlerden sonra bile birden fazla öğe alıyordum, bu yüzden daha fazla pin işaretleme dom öğesi için dds1024 çalışmasını genişlettim.

örneğin DIV: nth-çocuk (1) DIV: nth-child (3) DIV: nth-child (1) ARTICLE: nth-child (1) DIV: nth-child (1) DIV: nth-child (8) DIV : nth-çocuk (2) DIV: nth-child (1) DIV: nth-child (2) DIV: nth-child (1) H4: nth-child (2)

Kod:

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

Bu size tıklanan HTML öğesinin seçici yolunu verebilir.

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

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

    alert(selectorPath);

    return false;

});

1

Bu basit jQuery eklentisini yazdım.

Bu, id veya sınıf adını kontrol eder ve mümkün olduğunca çok kesin seçici vermeye çalışır.

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

Tıklanan mevcut etiketin adını almaya mı çalışıyorsunuz?

Eğer öyleyse, bunu yapın ..

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

"Seçici" yi gerçekten alamazsınız, sizin durumunuzda "seçici" dir *.


Etiket adına ihtiyacım yok. Tıkladığım öğenin yoluna ihtiyacım var.
Fidilip

1
AH, "elemana giden yol" u bir yere götürmeye başlamak "selector" dan çok farklı. Öyleyse, öğeye ve tüm üst düğüm adlarına ihtiyacınız var?
Mark Schultheiss

Gerçek hedefinize daha çok ulaşan başka bir cevap gönderdim. Daha spesifik olması için soruyu düzenlemelisiniz.
jessegavin

0

İhtiyaç duyduğum herhangi birinin ihtiyaç duyması durumunda aynı Javascript kodu. Bu sadece yukarıda seçilen cevabın tercümesidir.

    <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

Burada okunan bazı cevapları dikkate alarak şunu önermek istiyorum:

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

Bir jQuery eklentisi oluşturmak yararlı olabilir mi?


0

Teşekkürler p1nox!

Benim sorunum, formun bir bölümünü değiştiren bir ajax çağrısına odaklanmaktı.

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

Fonksiyonunuzu bir jQuery eklentisinde özetlemem gerekiyordu:

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

Peki ya:

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

JQuery'nin kullanılan seçici metni sakladığına inanmıyorum. Sonuçta, böyle bir şey yapsaydınız bu nasıl çalışır?

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

jQuery içten seçici kurar $('div').find('a').selectorolduğunu div a. Olaylar jQuery işlevleri aracılığıyla oluşturulmamışsa, bunun yerine bir sarmalayıcıyla oluşturuluyorsa, seçicinin olay işleyicisine veri bağımsız değişkenleri olarak aktarılabileceğine inanıyorum.
Anurag

1
Bu gerçekten ciddi bir cevap mı?
Glen

-5

En iyi cevap şöyle olurdu

var selector = '#something';

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

4
Bu hiç de en iyi cevap gibi görünmüyor.
Alex
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.