JQuery เพื่อตรวจสอบรหัสที่ซ้ำกันใน DOM


106

ฉันกำลังเขียนแอปพลิเคชันด้วย ASP.NET MVC ตรงกันข้ามกับ ASP.NET แบบเดิมคุณมีความรับผิดชอบมากกว่าในการสร้าง ID ทั้งหมดในเพจที่สร้างขึ้น ASP.NET จะให้รหัสที่น่ารังเกียจ แต่ไม่ซ้ำใคร

ฉันต้องการเพิ่มสคริปต์ jQuery สั้น ๆ เพื่อตรวจสอบเอกสารของฉันเพื่อหารหัสที่ซ้ำกัน ซึ่งอาจเป็นรหัสสำหรับ DIVS รูปภาพช่องทำเครื่องหมายปุ่ม ฯลฯ

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

ฉันกำลังมองหายูทิลิตี้เซ็ตและลืมประเภทที่จะเตือนฉันเมื่อฉันทำอะไรที่ประมาท

ใช่ฉันจะใช้สิ่งนี้ในระหว่างการทดสอบเท่านั้นและยินดีต้อนรับทางเลือกอื่น (เช่นปลั๊กอิน firebug) ด้วย

คำตอบ:


214

สิ่งต่อไปนี้จะบันทึกคำเตือนไปยังคอนโซล:

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

สมบูรณ์แบบ! ขอบคุณ! ได้ค้นพบสถานที่สามแห่งที่ฉันมีรหัสซ้ำกัน มันทำให้ฉันหงุดหงิดเล็กน้อยที่คนส่วนใหญ่แก้ไขปัญหานี้คือการใช้ 'firebug' หรือ 'html validator' นั่นยังไม่ดีพอ! ฉันต้องการจับภาพซ้ำที่ไม่คาดคิดในสถานการณ์ที่แปลกประหลาด
Simon_Weaver

4
ฮิฮิและฉันเปลี่ยนคอนโซลเตือนให้แจ้งเตือน (... ) ดังนั้นฉันต้องแก้ไข :)
Simon_Weaver

พบว่าสิ่งนี้มีประโยชน์และมีคุณค่าอย่างยิ่ง ฉันคิดว่ามันควรจะเป็นมาตรฐานในเฟรมเวิร์กโดยเฉพาะอย่างยิ่งในระหว่างการดีบัก
Simon_Weaver

6
จำนวนการสำรวจ DOM ที่จำเป็นสำหรับการทำงานนี้ค่อนข้างน่าประหลาดใจ
Josh Stodola

8
ทางออกที่ดีมาก แต่ต้องใช้เครื่องหมายคำพูดพิเศษvar ids = $('[id=\''+this.id+'\']');เพื่อให้ใช้งานได้กับจุดและสิ่งแปลก ๆ อื่น ๆ ใน ID
zidarsk8

33

เวอร์ชันนี้ค่อนข้างเร็วกว่าและคุณสามารถคัดลอกไปยังปุ่มบุ๊กมาร์กเพื่อทำให้เป็น 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
อัลกอริทึมนี้ดีกว่าต้องใช้การข้ามผ่านโดเมนเดียวแทนที่จะเป็นหนึ่งรายการต่อองค์ประกอบที่ตรงกัน ควรเป็นคำตอบที่ได้รับการยอมรับ
m_x

1
มันให้ผลบวกเท็จสำหรับแบบฟอร์มที่มีอินพุตด้วย name = 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'); })(); จะดีกว่า.
alpo

14

ฉันมีเพจขนาดใหญ่ดังนั้นสคริปต์จึงทำงานช้าเกินไปที่จะจบ (ข้อความ "ดำเนินการต่อสคริปต์" หลายข้อความ) ใช้งานได้ดี

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

เยี่ยมมาก! ขอบคุณ. ฉันมักจะลืมว่าฉันกำลังทำงานอยู่ในการผลิตและตอนนี้ควรปรับให้เหมาะสม - หรือเพิ่มการตั้งค่าการดีบักเพื่อเปิด / ปิด!
Simon_Weaver

ฉันทำงานอย่างต่อเนื่องในการรวมสคริปต์ในการกำหนดค่าต่างๆและสิ่งนี้จะช่วยฉันได้มากอย่างแน่นอน ขอบคุณ :)
Andy Gee

+1 สำหรับโซลูชัน JavaScript ธรรมดา หลังจากค้นหารหัสที่ซ้ำกันแล้วฉันใช้นิพจน์ XPath ( $x("//*[@id='duplicated-id']")) ในคอนโซลเพื่อค้นหาองค์ประกอบที่มีรหัสที่ซ้ำกัน
Cassiomolin


8

ทำไมคุณไม่ตรวจสอบความถูกต้องของ html ของคุณ

ไม่อนุญาตให้ใช้รหัสคู่และโดยปกติคุณจะได้รับข้อผิดพลาดในการแยกวิเคราะห์


2
ตัวเลือกนี้มีอะไรบ้าง?
Simon_Weaver

นอกจากนี้ใน FF ให้ใช้แถบเครื่องมือนักพัฒนาเว็บภายใต้เครื่องมือที่มีตัวตรวจสอบความถูกต้อง
IEnumerator

4
เมื่อทำงานกับวิดเจ็ตเช่นไดอะล็อกจาก jquery ui มักเกิดขึ้นบ่อยครั้งที่คุณลงเอยด้วยการซ้ำกันใน DOM เมื่อไม่ได้ล้างข้อมูลหลังจากสร้างไดอะล็อก
guido

4

อีกวิธีหนึ่งในการค้นหารายการที่ซ้ำกัน แต่จะเพิ่มคลาสของข้อผิดพลาดดังนั้นจึงมีข้อความสีแดง:

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

เจ๋งมาก! ขอบคุณ. ฉันพบว่าคำตอบเดิมที่ยอมรับนั้นมีค่ามาก จับหลายสิ่งหลายอย่างและประหยัดเวลาได้หลายชั่วโมง!
Simon_Weaver

เจ๋ง แต่ทำไมไม่ใช้แค่ฟังก์ชั่นคอนโซลแล้วปล่อยให้มันทำส่วนที่เหลือล่ะ? การแยกตรรกะและการนำเสนอ ฯลฯ ...
Will Morgan

3

คำตอบ jQuery ด้านบนเขียนใหม่ใน 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

วิธีนี้อาจใช้เคล็ดลับได้โดยจะแจ้งเตือนรหัสขององค์ประกอบทั้งหมดที่มีรายการซ้ำกัน

<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

ฉันชอบสิ่งนี้เพราะมันคายองค์ประกอบที่แท้จริงออกมาสู่คอนโซล ช่วยให้ตรวจสอบสิ่งที่เกิดขึ้นได้ง่ายขึ้น

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

}


ฟังก์ชันนี้มีประโยชน์อย่างยิ่งเมื่อเครื่องมือตรวจสอบ HTML ของส่วนขยาย Chrome ที่แนะนำใช้งานไม่ได้สำหรับฉันเนื่องจากสามารถตรวจจับรหัสที่จำลองแบบได้เมื่อมีการเพิ่ม HTML ใหม่ลงในหน้า
Giselle Serate

1

คุณสามารถใช้โซลูชันนี้ซึ่งจะพิมพ์รายการรหัสที่ซ้ำกันในคอนโซลหากมีอยู่

คุณสามารถรันโค้ดได้โดยตรงในคอนโซล (คัดลอก / วาง) หลังจากที่คุณโหลด DOM และไม่ต้องการการพึ่งพาเพิ่มเติมเช่น jQuery

คุณสามารถใช้เพื่อค้นหาข้อผิดพลาดที่เป็นไปได้อย่างรวดเร็วในมาร์กอัป 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);

ตัวอย่าง:

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

(ที่นี่โค้ดจะถูกเพิ่มก่อนปิดbodyแท็ก)


0

ฉันได้สร้างฟังก์ชันที่คุณสามารถตรวจสอบองค์ประกอบเฉพาะที่ค้นหารหัสที่ซ้ำกันภายในหรือทั้งหน้า:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.