Bir DOM'da yinelenen kimlikleri kontrol etmek için JQuery


106

ASP.NET MVC ile uygulamalar yazıyorum. Geleneksel ASP.NET'in aksine, oluşturulan sayfanızdaki tüm kimlikleri oluşturmaktan çok daha fazla sorumlusunuz. ASP.NET size kötü, ancak benzersiz kimlikler verir.

Belgemde yinelenen kimlikler olup olmadığını kontrol etmek için hızlı bir küçük jQuery betiği eklemek istiyorum. DIVS, resimler, onay kutuları, düğmeler vb. İçin kimlikler olabilirler.

<div id="pnlMain"> My main panel </div>
<div id="pnlMain"> Oops we accidentally used the same ID </div> 

Dikkatsiz bir şey yaptığımda beni uyaracak bir set ve unutma tipi yardımcı program arıyorum.

Evet, bunu yalnızca test sırasında kullanacağım ve alternatifler (firebug eklentileri gibi) da kabul edilir.

Yanıtlar:


214

Aşağıdakiler konsola bir uyarı kaydedecektir:

// Warning Duplicate IDs
$('[id]').each(function(){
  var ids = $('[id="'+this.id+'"]');
  if(ids.length>1 && ids[0]==this)
    console.warn('Multiple IDs #'+this.id);
});

mükemmel! Teşekkürler! yinelenen kimliklerimin olduğu üç yeri zaten keşfettim. Bu soruna çoğu insanın çözümünün 'firebug' veya 'html validator' kullanmak olması beni biraz sinirlendiriyor. yeterince iyi değil! Garip durumlarda beklenmedik kopyaları yakalamak istiyorum.
Simon_Weaver

4
hehe ve ben console.warn'ı uyarmak için değiştirdik (...) bu yüzden onları düzeltmek zorundayım :)
Simon_Weaver

bunu son derece yararlı ve değerli bulduk. Bunun çerçevelerde bir standart olması gerektiğini düşünüyorum - özellikle de hata ayıklama sırasında
Simon_Weaver

6
Bunun çalışması için gereken DOM geçişlerinin miktarı oldukça şaşırtıcı
Josh Stodola

8
Çok güzel bir çözüm ama fazladan alıntıya ihtiyaç duyuyor, var ids = $('[id=\''+this.id+'\']');bu yüzden kimliklerdeki noktalar ve diğer garip şeylerle çalışıyor.
zidarsk8

33

Bu sürüm biraz daha hızlıdır ve onu bir yer imi yapmak için bir yer imi düğmesine kopyalayabilirsiniz.

javascript:(function () {
  var ids = {};
  var found = false;
  $('[id]').each(function() {
    if (this.id && ids[this.id]) {
      found = true;
      console.warn('Duplicate ID #'+this.id);
    }
    ids[this.id] = 1;
  });
  if (!found) console.log('No duplicate IDs found');
})();

3
Bu algoritma daha iyidir, eşleşen öğe başına bir yerine yalnızca bir etki alanı geçişi gerektirir. Kabul edilen cevap olmalı.
m_x

1
Name = id ile girişi olan formlar için yanlış pozitif verir. javascript:(function () { var ids = {}; var found = false; $('[id]').each(function() { var id = this.getAttribute('id'); if (id && ids[id]) { found = true; console.warn('Duplicate ID #'+id); } ids[id] = 1; }); if (!found) console.log('No duplicate IDs found'); })(); Daha iyi olurdu.
alpo

14

Büyük bir sayfam var, bu yüzden komut dosyası bitirilemeyecek kadar yavaş çalışıyor (birden fazla "komut dosyasına devam et" mesajı). Bu iyi çalışıyor.

(function () {
    var elms = document.getElementsByTagName("*"), i, len, ids = {}, id;
    for (i = 0, len = elms.length; i < len; i += 1) {
        id = elms[i].id || null;
        if (id) {
            ids[id] =  ids.hasOwnProperty(id) ? ids[id] +=1 : 0;
        }
    }
    for (id in ids) {
        if (ids.hasOwnProperty(id)) {
            if (ids[id]) {
                console.warn("Multiple IDs #" + id);
            }
        }
    }
}());

harika! Teşekkürler. sık sık bunu üretimde çalıştırdığımı ve gerçekten şimdiye kadar optimize etmem gerektiğini ya da açmak / kapatmak için bir hata ayıklama ayarı eklemem gerektiğini unutuyorum!
Simon_Weaver

Sürekli olarak komut dosyalarını farklı konfigürasyonlarda birleştirmeye çalışıyorum ve bu kesinlikle bana çok yardımcı olacak. Teşekkürler :)
Andy Gee

Düz JavaScript çözümü için +1. Yinelenen kimlikleri bulduktan sonra, yinelenen kimliklerle $x("//*[@id='duplicated-id']")öğeleri sorgulamak için konsolda bir XPath ifadesi ( ) kullandım .
cassiomolin


8

Neden html'nizi doğrulamıyorsunuz?

Çift kimliğe izin verilmez ve normalde bir ayrıştırma hatası alırsınız.


2
bunun için hangi seçenekler var?
Simon_Weaver

Ayrıca FF'de, doğrulayıcılara sahip araçlar altındaki web geliştirici araç çubuğunu kullanın
IEnumerator

4
Jquery ui'deki diyalog gibi widget'larla çalışırken, diyalogları oluşturduktan sonra temizlik yapmadığınızda sıklıkla DOM'da yinelenen öğelerle karşılaşıyorsunuz.
guido

4

Yinelenenleri bulmanın başka bir yolu, ancak bu bir hata sınıfı ekleyeceği için kırmızı metne sahip olacaktır:

// waits for document load then highlights any duplicate element id's
$(function(){ highlight_duplicates();});

function highlight_duplicates() {
  // add errors when duplicate element id's exist
  $('[id]').each(function(){ // iterate all id's on the page
    var elements_with_specified_id = $('[id='+this.id+']');
    if(elements_with_specified_id.length>1){
      elements_with_specified_id.addClass('error');
    }
  });


  // update flash area when warning or errors are present
  var number_of_errors = $('.error').length;
  if(number_of_errors > 0)
    $('#notice').append('<p class="error">The '+number_of_errors+
      ' items below in Red have identical ids.  Please remove one of the items from its associated report!</p>');
}

bu biraz havalı! Teşekkürler. Aslında kabul edilen orijinal cevabı çok değerli buldum. çok şey yakaladı ve muhtemelen saatlerce zaman kazandırdı!
Simon_Weaver

Harika, ama neden sadece konsol işlevlerini kullanıp gerisini onlara bırakmayasınız? Mantık ve sunumun ayrılması vs ...
Will Morgan

3

ES6'da yeniden yazılan en iyi jQuery yanıtı:

  [...document.querySelectorAll('[id]')].forEach(el => {
    const dups = document.querySelectorAll(`[id="${el.id}"]`);

    if (dups.length > 1 && dups[0] === el) {
      console.error(`Duplicate IDs #${el.id}`, ...dups);
    }
  });

2

Bu hile yapabilir. Yinelenen öğelerin tüm kimliklerini uyaracaktır.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
    	<head>
    		<script type="text/javascript" src="jquery-1.3.1.min.js"></script>
    		<script type="text/javascript">
    			function findDupes()
    			{
    			  var all = $("*");
    			  for(var i = 0; i < all.length; i++)
    			  {
    			      if (all[i].id.length > 0 && $("[id='" + all[i].id + "']").length > 1) alert(all[i].id);
    			  }
    			}
    		</script>
    	</head>
    	<body onload="findDupes()">
    		<div id="s"></div>
    		<div id="f"></div>
    		<div id="g"></div>
    		<div id="h"></div>
    		<div id="d"></div>
    		<div id="j"></div>
    		<div id="k"></div>
    		<div id="l"></div>
    		<div id="d"></div>
    		<div id="e"></div>
    	</body>
    </html>


1

Bunu seviyorum çünkü gerçek öğeleri konsola aktarıyor. Neler olduğunu araştırmayı kolaylaştırır.

function CheckForDuplicateIds() {
var ids = {};
var duplicates = [];

$("[id]").each(function() {
    var thisId = $(this).attr("id");
    if (ids[thisId] == null) {
        ids[thisId] = true;
    } else {
        if (ids[thisId] == true) {
            duplicates.push(thisId);
            ids[thisId] = false;
        }
    }
});
if (duplicates.length > 0) {
    console.log("=======================================================");
    console.log("The following " + duplicates.length + " ids are used by multiple DOM elements:");
    console.log("=======================================================");
    $(duplicates).each(function() {
        console.warn("Elements with an id of " + this + ":");
        $("[id='" + this + "']").each(function() {
            console.log(this);
        });
        console.log("");
    });
} else {
    console.log("No duplicate ids were found.");
}
return "Duplicate ID check complete.";

}


Bu işlev, önerilen Chrome uzantısı HTML doğrulayıcısının benim için çalışmadığı durumlarda son derece yararlı oldu, çünkü sayfaya yeni HTML eklendiğinde çoğaltılmış kimlikleri tespit edebiliyordu.
Giselle Serate

1

Konsolda varsa yinelenen kimliklerin bir listesini yazdıracak olan bu çözümü kullanabilirsiniz.

DOM yüklendikten sonra kodu doğrudan konsolda çalıştırabilirsiniz (kopyala / yapıştır) ve jQuery gibi ek bağımlılık gerektirmez.

HTML biçimlendirmenizdeki olası hataları hızlı bir şekilde bulmak için kullanabilirsiniz.

    (function (document) {
        var elms = document.body.querySelectorAll('*[id]'),
            ids = [];
        for (var i = 0, len = elms.length; i < len; i++) {
            if (ids.indexOf(elms[i].id) === -1) {
                ids.push(elms[i].id);
            } else {
                console.log('Multiple IDs #' + elms[i].id);
            }
        }
    })(document);

Bir örnek:

https://jsbin.com/cigusegube/edit?html,console,output

(burada kod, bodyetiketi kapatmadan önce eklenir )


0

Sayfanın tamamında veya içinde yinelenen kimlikleri arayan belirli bir öğeyi inceleyebileceğiniz bir işlev oluşturdum:

function duplicatedIDs(container) {

    var $container  = container ? $(container) : $('body'),
        elements = {},
        duplicatedIDs = 0;
        totalIDs = 0;

    $container.find('[ID]').each(function(){
        var element = this;

        if(elements[element.id]){
            elements[element.id].push(element);
        } else  {
            elements[element.id] = [element];
        }
        totalIDs += 1;

    });

    for( var k in elements ){
        if(elements[k].length > 1){
            console.warn('######################################')
            console.warn('        ' + k )
            console.warn('######################################')
            console.log(elements[k]);
            console.log('---------------------------------------');
            duplicatedIDs += elements[k].length
        }
    }
    console.info('totalIDs', totalIDs);
    console.error('duplicatedIDs', duplicatedIDs);
}

duplicatedIDs('#element'); //find duplicated ids under that element
duplicatedIDs(); // entire page
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.