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.

Simon_Weaver
quelle

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);
});
sunsean
quelle
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');
})();
Sjoerd
quelle
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);
            }
        }
    }
}());
AutoSponge
quelle
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
12

Sie sollten HTML Validator (Firefox-Erweiterung) ausprobieren . Es wird Ihnen definitiv sagen, dass die Seite doppelte IDs hat und vieles mehr.

Ionuț G. Stan
quelle
8

Warum validieren Sie nicht einfach Ihr HTML?

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

Natrium
quelle
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>');
}
Joshaven Potter
quelle
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);
    }
  });
Rafi
quelle
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>

Syed Mohamed Aladeen
quelle
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.";

}}

Burton
quelle
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.)

GibboK
quelle
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
diegodafm
quelle