JQuery, aby sprawdzić zduplikowane identyfikatory w DOM

106

Piszę aplikacje w ASP.NET MVC. W przeciwieństwie do tradycyjnego ASP.NET jesteś o wiele bardziej odpowiedzialny za tworzenie wszystkich identyfikatorów na wygenerowanej stronie. ASP.NET daje nieprzyjemne, ale unikalne identyfikatory.

Chciałbym dodać szybki skrypt jQuery, aby sprawdzić mój dokument pod kątem zduplikowanych identyfikatorów. Mogą to być identyfikatory DIVS, obrazy, pola wyboru, przyciski itp.

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

Szukam narzędzia typu „ustaw i zapomnij”, które ostrzeże mnie, gdy zrobię coś nieostrożnego.

Tak, używałbym tego tylko podczas testów, a alternatywy (takie jak wtyczki firebug) również są mile widziane.

Simon_Weaver
źródło

Odpowiedzi:

214

Poniższe informacje zarejestrują ostrzeżenie w konsoli:

// 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
źródło
idealny! dzięki! już odkryłem trzy miejsca, w których mam zduplikowane identyfikatory. nieco frustruje mnie to, że większość ludzi rozwiązuje ten problem za pomocą „firebug” lub „walidatora html”. to nie jest wystarczająco dobre! chcę wyłapać nieoczekiwane duplikaty w dziwnych sytuacjach.
Simon_Weaver
4
hehe a ja włączony console.warn do wpisu (...) więc muszę je naprawić :)
Simon_Weaver
uznają to za niezwykle przydatne i wartościowe. myślę, że to powinien być standard we frameworkach - szczególnie podczas debugowania
Simon_Weaver
6
Ilość przejść DOM potrzebnych do tego, by to zadziałało, jest zadziwiająca
Josh Stodola
8
Bardzo fajne rozwiązanie, ale wymaga dodatkowych cudzysłowów, var ids = $('[id=\''+this.id+'\']');więc działa z kropkami i innymi dziwnymi rzeczami w identyfikatorach.
zidarsk8
33

Ta wersja jest nieco szybsza i możesz skopiować ją do przycisku zakładki, aby uczynić ją bookmarkletem.

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
źródło
3
Ten algorytm jest lepszy, wymaga tylko jednego przejścia do domeny zamiast jednego na dopasowany element. Powinna być zaakceptowana odpowiedź.
m_x
1
Daje fałszywe pozytywne dla formularzy, które mają dane wejściowe z nazwą = 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'); })(); byłoby lepiej.
alpo
14

Mam dużą stronę, więc skrypt działa zbyt wolno, aby zakończyć (wiele komunikatów „kontynuuj skrypt”). To działa dobrze.

(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
źródło
świetny! dzięki. często zapominam, że mam to uruchomione w środowisku produkcyjnym i naprawdę powinienem go teraz zoptymalizować - lub dodać ustawienie debugowania, aby go włączyć / wyłączyć!
Simon_Weaver
Nieustannie pracuję nad łączeniem skryptów w różnych konfiguracjach i to na pewno bardzo mi pomoże. Dzięki :)
Andy Gee
+1 dla zwykłego rozwiązania JavaScript. Po znalezieniu zduplikowanych identyfikatorów użyłem wyrażenia XPath ( $x("//*[@id='duplicated-id']")) w konsoli, aby odpytać elementy ze zduplikowanymi identyfikatorami.
kasiomolina
12

Powinieneś wypróbować walidator HTML (rozszerzenie Firefox). Z pewnością powie Ci, że strona ma zduplikowane identyfikatory i wiele więcej.

Ionuț G. Stan
źródło
8

Dlaczego po prostu nie zweryfikujesz swojego kodu HTML?

Podwójne identyfikatory nie są dozwolone i zwykle pojawia się błąd analizy.

Sód
źródło
2
jakie są dostępne opcje?
Simon_Weaver
Również w FF użyj paska narzędzi programisty sieci Web w narzędziach, które ma walidatory
IEnumerator
4
Podczas pracy z widżetami, takimi jak dialog z jQuery ui, często zdarza się, że w DOMu pojawiają się duplikaty, gdy nie są czyszczone po utworzeniu okien dialogowych.
guido
4

Jeszcze inny sposób znajdowania duplikatów, ale doda to klasę błędu, więc będzie miał czerwony tekst:

// 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
źródło
to trochę fajne! dzięki. rzeczywiście uważam, że oryginalna zaakceptowana odpowiedź jest bezcenna. złapał tak wiele rzeczy i prawdopodobnie zaoszczędził wiele godzin!
Simon_Weaver,
Fajnie, ale dlaczego po prostu nie skorzystać z funkcji konsoli i pozwolić im zająć się resztą? Rozdzielenie logiki i prezentacji itp., Itd ...
Will Morgan
3

Najlepsza odpowiedź jQuery, przepisana w 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);
    }
  });
Rafi
źródło
2

To może załatwić sprawę. Zaalarmuje wszystkie identyfikatory elementów z duplikatami.

<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
źródło
1

Podoba mi się to, ponieważ wypluwa rzeczywiste elementy do konsoli. Ułatwia zbadanie, co się dzieje.

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
źródło
Ta funkcja była niezwykle pomocna, gdy nie działał w moim przypadku sugerowany moduł sprawdzania poprawności HTML rozszerzenia Chrome, ponieważ był w stanie wykryć replikowane identyfikatory, gdy nowy kod HTML został dodany do strony.
Giselle Serate
1

Możesz użyć tego rozwiązania, które wydrukuje w konsoli listę zduplikowanych identyfikatorów, jeśli takie istnieją.

Możesz uruchomić kod bezpośrednio w konsoli (kopiuj / wklej) po załadowaniu DOM i nie wymaga dodatkowej zależności, takiej jak jQuery.

Możesz go użyć, aby szybko znaleźć możliwe błędy w znacznikach 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);

Przykład:

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

(tutaj kod jest dodawany przed zamknięciem bodytagu)

GibboK
źródło
0

Stworzyłem funkcję, w której możesz sprawdzić konkretny element wyszukujący zduplikowane identyfikatory w obrębie lub całej strony:

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
źródło