JQuery per verificare la presenza di ID duplicati in un DOM


106

Sto scrivendo applicazioni con ASP.NET MVC. In contrasto con ASP.NET tradizionale, sei molto più responsabile della creazione di tutti gli ID nella pagina generata. ASP.NET ti darebbe ID cattivi ma unici.

Vorrei aggiungere un piccolo script jQuery veloce per controllare il mio documento per gli ID duplicati. Possono essere ID per DIVS, immagini, caselle di controllo, pulsanti, ecc.

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

Sto cercando un'utilità di tipo set e dimentica che mi avvisa quando faccio qualcosa di sbadato.

Sì, lo userei solo durante i test e anche le alternative (come i plugin firebug) sono benvenute.

Risposte:


214

Quanto segue registrerà un avviso sulla console:

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

Perfetto! Grazie! ho già scoperto tre posti in cui ho ID duplicati. mi frustra leggermente il fatto che la maggior parte delle persone per risolvere questo problema sia usare "firebug" o "html validator". non è abbastanza buono! Voglio catturare i duplicati inaspettati in situazioni strane.
Simon_Weaver

4
hehe e io abbiamo cambiato console.warn per avvisare (...) quindi
DEVO

l'ho trovato estremamente utile e prezioso. Penso che dovrebbe essere uno standard nei framework, specialmente durante il debug
Simon_Weaver,

6
La quantità di attraversamenti DOM necessari per funzionare è piuttosto sorprendente
Josh Stodola

8
Soluzione molto bella ma richiede virgolette extra in var ids = $('[id=\''+this.id+'\']');modo che funzioni con punti e altre cose strane negli ID.
zidarsk8

33

Questa versione è un po 'più veloce e puoi copiarla in un pulsante di segnalibro per renderlo un bookmarklet.

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
Questo algoritmo è migliore, richiede solo un attraversamento dom invece di uno per elemento abbinato. Dovrebbe essere la risposta accettata.
m_x

1
Fornisce un falso positivo per i moduli che hanno input con nome = id. 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'); })(); sarebbe meglio.
alpo

14

Ho una pagina grande, quindi lo script viene eseguito troppo lentamente per terminare (più messaggi "continua script"). Funziona bene.

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

grande! Grazie. spesso dimentico di averlo in esecuzione in produzione e dovrei davvero ottimizzarlo ormai - o aggiungere un'impostazione di debug per attivarlo / disattivarlo!
Simon_Weaver

Lavoro costantemente per combinare script in diverse configurazioni e questo mi aiuterà sicuramente molto. Grazie :)
Andy Gee

+1 per la semplice soluzione JavaScript. Dopo aver trovato gli ID duplicati, ho utilizzato l'espressione XPath ( $x("//*[@id='duplicated-id']")) nella console per interrogare gli elementi con gli ID duplicati.
cassiomolin


8

Perché non convalidi semplicemente il tuo html?

I doppi ID non sono consentiti e normalmente verrà visualizzato un errore di analisi.


2
quali opzioni ci sono per questo?
Simon_Weaver

Anche in FF, usa la barra degli strumenti per sviluppatori web sotto gli strumenti che ha validatori
IEnumerator

4
Quando si lavora con widget come dialog da jquery ui, capita spesso di ritrovarsi con dupliate nel DOM quando non si pulisce dopo aver creato le finestre di dialogo.
guido

4

Ancora un altro modo per individuare i duplicati, ma questo aggiungerà una classe di errore in modo che abbia il testo rosso:

// 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>');
}

questo è piuttosto bello! Grazie. In realtà ho trovato inestimabile la risposta originale accettata. catturato così tante cose e risparmiato probabilmente ore di tempo!
Simon_Weaver

Fantastico, ma perché non usare semplicemente le funzioni della console e lasciare che facciano il resto? Separazione di logica e presentazione ecc ecc ...
Will Morgan

3

La migliore risposta jQuery, riscritta in ES6:

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

Questo potrebbe fare il trucco Avviserà tutti gli ID degli elementi con duplicati.

<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

Mi piace perché sputa gli elementi reali alla console. Rende più facile indagare su cosa sta succedendo.

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.";

}


Questa funzione è stata estremamente utile laddove il validatore HTML dell'estensione di Chrome suggerito non funzionava per me, perché era in grado di rilevare gli ID replicati quando il nuovo HTML veniva aggiunto alla pagina.
Giselle Serate

1

È possibile utilizzare questa soluzione che stamperà nella console un elenco di ID duplicati, se presenti.

Puoi eseguire il codice direttamente nella console (copia / incolla) dopo aver caricato il DOM e non richiede dipendenze aggiuntive come jQuery.

Potresti usarlo per scoprire rapidamente possibili errori nel tuo markup HTML.

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

Un esempio:

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

(qui il codice viene aggiunto prima di chiudere il bodytag)


0

Ho creato una funzione in cui puoi ispezionare un elemento specifico alla ricerca di ID duplicati all'interno o nell'intera pagina:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.