JQuery, um in einem DOM nach doppelten IDs zu suchen


106

Ich schreibe Anwendungen mit ASP.NET MVC. Im Gegensatz zu herkömmlichem ASP.NET sind Sie viel mehr dafür verantwortlich, alle IDs auf Ihrer generierten Seite zu erstellen. ASP.NET würde Ihnen böse, aber eindeutige IDs geben.

Ich möchte ein kurzes kleines jQuery-Skript hinzufügen, um mein Dokument auf doppelte IDs zu überprüfen. Dies können IDs für DIVS, Bilder, Kontrollkästchen, Schaltflächen usw. sein.

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

Ich suche nach einem Set-and-Forget-Dienstprogramm, das mich nur warnt, wenn ich etwas Unachtsames tue.

Ja, ich würde dies nur während des Testens verwenden, und Alternativen (wie Firebug-Plugins) sind ebenfalls willkommen.

Antworten:


214

Folgendes protokolliert eine Warnung an der Konsole:

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

perfekt! Vielen Dank! habe bereits drei Stellen entdeckt, an denen ich doppelte IDs habe. Es frustriert mich ein wenig, dass die Lösung der meisten Leute für dieses Problem darin besteht, "Firebug" oder "HTML-Validator" zu verwenden. das ist nicht gut genug! Ich möchte die unerwarteten Duplikate in seltsamen Situationen fangen.
Simon_Weaver

4
hehe und ich haben console.warn gewechselt, um (...) zu alarmieren, also MUSS ich sie reparieren :)
Simon_Weaver

habe dies als äußerst nützlich und wertvoll empfunden. Ich denke, es sollte ein Standard in Frameworks sein - besonders während des Debuggens
Simon_Weaver

6
Die Anzahl der DOM-Durchquerungen, die erforderlich sind, damit dies funktioniert, ist ziemlich erstaunlich
Josh Stodola

8
Sehr schöne Lösung, aber es braucht zusätzliche Anführungszeichen, var ids = $('[id=\''+this.id+'\']');damit es mit Punkten und anderen seltsamen Dingen in IDs funktioniert.
Zidarsk8

33

Diese Version ist etwas schneller und Sie können sie auf eine Lesezeichenschaltfläche kopieren, um sie zu einem Lesezeichen zu machen.

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
Dieser Algorithmus ist besser und erfordert nur eine Dom-Durchquerung anstelle einer pro übereinstimmendem Element. Sollte die akzeptierte Antwort sein.
m_x

1
Es gibt falsch positive Ergebnisse für Formulare, die eine Eingabe mit name = id haben. 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'); })(); wäre besser.
Alpo

14

Ich habe eine große Seite, so dass das Skript zu langsam ausgeführt wird, um es zu beenden (mehrere "Skript fortsetzen" -Nachrichten). Das funktioniert gut.

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

großartig! Vielen Dank. Ich vergesse oft, dass dies in der Produktion läuft und sollte es jetzt wirklich optimieren - oder eine Debug-Einstellung hinzufügen, um es ein- / auszuschalten!
Simon_Weaver

Ich arbeite ständig daran, Skripte in verschiedenen Konfigurationen zu kombinieren, und das wird mir sicherlich sehr helfen. Danke :)
Andy Gee

+1 für die einfache JavaScript-Lösung. Nachdem ich die duplizierten IDs gefunden hatte, verwendete ich den Ausdruck a XPath ( $x("//*[@id='duplicated-id']")) in der Konsole, um die Elemente mit den duplizierten IDs abzufragen.
Cassiomolin


8

Warum validieren Sie nicht einfach Ihr HTML?

Doppelte IDs sind nicht zulässig, und normalerweise wird ein Analysefehler angezeigt.


2
Welche Möglichkeiten gibt es dafür?
Simon_Weaver

Verwenden Sie auch in FF die Webentwickler-Symbolleiste unter Tools mit Validatoren
IEnumerator

4
Wenn Sie mit Widgets wie Dialog von jquery ui arbeiten, kommt es häufig vor, dass Sie Dupliates im DOM haben, wenn Sie nach dem Erstellen der Dialoge nicht bereinigen.
Guido

4

Noch eine andere Möglichkeit, Duplikate zu finden, aber dies fügt eine Fehlerklasse hinzu, sodass roter Text angezeigt wird:

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

das ist irgendwie cool! Vielen Dank. Ich fand die ursprünglich akzeptierte Antwort von unschätzbarem Wert. so viele Dinge gefangen und wahrscheinlich Stunden Zeit gespart!
Simon_Weaver

Cool, aber warum nicht einfach Konsolenfunktionen verwenden und den Rest erledigen lassen? Trennung von Logik und Präsentation etc etc ...
Will Morgan

3

Die in j6 umgeschriebene Top-jQuery-Antwort:

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

Dies könnte den Trick machen. Es alarmiert alle IDs von Elementen mit Duplikaten.

<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

Ich mag das, weil es die eigentlichen Elemente auf die Konsole ausspuckt. Es macht es einfacher zu untersuchen, was los ist.

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

}}


Diese Funktion war äußerst hilfreich, wenn der vorgeschlagene HTML-Validator für die Chrome-Erweiterung für mich nicht funktionierte, da er replizierte IDs erkennen konnte, wenn der Seite neuer HTML-Code hinzugefügt wurde.
Giselle Serate

1

Sie können diese Lösung verwenden, die in der Konsole eine Liste doppelter IDs ausgibt, falls vorhanden.

Sie können den Code direkt in der Konsole ausführen (Kopieren / Einfügen), nachdem Ihr DOM geladen wurde, und erfordern keine zusätzliche Abhängigkeit wie jQuery.

Sie können es verwenden, um mögliche Fehler in Ihrem HTML-Markup schnell herauszufinden.

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

Ein Beispiel:

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

(Hier wird Code hinzugefügt, bevor das bodyTag geschlossen wird.)


0

Ich habe eine Funktion erstellt, mit der Sie ein bestimmtes Element untersuchen können, um nach doppelten IDs innerhalb oder auf der gesamten Seite zu suchen:

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