我如何发现重复自己的HTML元素ID?

时间:2017-10-18 08:13:50

标签: javascript html html5

我刚刚遇到一个很难解决的主要错误,经过大量的工作后发现它是因为两个HTML元素具有相同的ID属性。

是否有命令在整个DOM中发现双重ID?

更新

阅读完所有评论之后,我在一个相对较大的网站(http://www.powtoon.com html5工作室)中测试了不同的方法,结果如下。

  

如果您有更好的方法,请发表评论。

两个答案都返回了相同的结果,但看起来querySelectorAll确实更快:

QuerySelectorAll

function getDuplicateIdsUsingQuerySelector(){
  const idsOccurances = Array.from(document.querySelectorAll('[id]'))
    .map(elem => elem.id)
    .reduce((allIDs, id) => {
      allIDs[id] = (allIDs[id] || 0) + 1
      return allIDs
    }, {})
  return Object.entries(idsOccurances)
    .filter(([id, occurances]) => occurances > 1)
    .map(([id]) => id)
}

平均每次通话1.5毫秒。

正则表达式

function getDuplicateIdsUsingRegEx(){
  const idRegex = / id=".*?"/ig
  const ids = document.body.innerHTML.match(idRegex)
  const idsOccurances = ids.reduce((allIDs, id) => {
    allIDs[id] = (allIDs[id] || 0) + 1
    return allIDs
  }, {})

  return Object.entries(idsOccurances)
    .filter(([id, occurrences]) => occurrences > 1)
    .map(([id]) => id.slice(4, -1))
}

每个通话平均5.5ms。

6 个答案:

答案 0 :(得分:6)

document.querySelectorAll('[id="dupid"]')会给你多个结果

[编辑]

如果你不知道期望的ID,我用另一种找到所有重复的方式制作了这个jsfiddle。

https://jsfiddle.net/edc4h5k2/

function checkAllIds() {
    var counts = {};
  var duplicates = new Set();
  function addCount(id) {
    if (counts[id]) {
        counts[id] += 1;
      duplicates.add(id);
    } else {
        counts[id] = 1;
    }
  }
  document.querySelectorAll("[id]").forEach(function(elem) {
    addCount(elem.id);
  })
  return Array.from(duplicates);
}

答案 1 :(得分:3)

  

是否有命令在整个DOM中发现双重ID?

简单地说,把它放在你的控制台中

$("[id='idValue']").length

如果值大于1,那么你有一个副本!

有一次,你发现有重复的事实,那么你需要检查各个元素的层次结构

$("[id='idValue']").each( function(){
  //traverse parents till body to see the dom structure to locate those duplicates
});

如果您事先不知道id值,请先创建重复ID数组

var allIds = {};
var duplicateIds = [];
$( "[id]" ).each( function(){
    var idValue = $(this).attr("id");
    if ( allIds[ idValue ] )
    {
        duplicateIds.push ( idValue ); 
    }
    else
    {
        allIds[ idValue ]  = true;
    }
});

现在duplicateIds是包含重复ID的数组。迭代相同以检查其DOM层次结构,以便您可以在整个DOM中发现它。

duplicateIds.forEach( function( idValue ){
   var $elementWithDuplicateId = $( "#" + idValue );
   //logic to traverse parents 
});

答案 2 :(得分:2)

如果您使用的是Chrome,则可以通过打开控制台>审核执行审核,然后选中最佳实践复选框。如果有任何双重ID,它们就会出现在那里。

答案 3 :(得分:1)

这将为您提供多次出现的所有ID的数组。

首先选择所有具有ID的元素,然后提取它们的ID,然后将所有内容简化为计算出现次数的对象。在该对象中,条目被转换为一个数组,该数组被过滤为仅包含多次出现的数组,然后只提取ID名称。



<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
<div id="a"></div>
<div id="e"></div>
<div id="f"></div>
<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
<div id="a"></div>
&#13;
Array
&#13;
&#13;
&#13;

以下是使用SetsMaps的替代方案,以及const duplicateIDs = Array.from(Array.from(document.querySelectorAll("[id]"), ({id}) => id) .reduce((allIDs, id) => { if(allIDs.map.has(id)){ allIDs.dupes.add(id); } else{ allIDs.map.set(id, 1); } return allIDs; }, { map: new Map(), dupes: new Set() }).dupes); console.log(duplicateIDs);方法之间较少数量的中间数组:

&#13;
&#13;
<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
<div id="a"></div>
<div id="e"></div>
<div id="f"></div>
<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
<div id="a"></div>
&#13;
br
&#13;
&#13;
&#13;

答案 4 :(得分:0)

理想情况下,您不应该有多个具有相同ID的元素。我知道你的问题是关于检测是否有相同id的元素。恕我直言,无论你在尝试什么,这可能是一个短期的解决方案。您需要修复问题的根,即没有两个元素应具有相同的ID。

答案 5 :(得分:0)

阅读完所有评论之后,我在一个相对较大的网站(http://www.powtoon.com html5工作室)中测试了不同的方法,结果如下。

两个答案都返回了相同的结果,但看起来querySelectorAll确实更快:

<强> QuerySelectorAll

function getDuplicateIdsUsingQuerySelector(){
  const idsOccurances = Array.from(document.querySelectorAll('[id]'))
    .map(elem => elem.id)
    .reduce((allIDs, id) => {
      allIDs[id] = (allIDs[id] || 0) + 1
      return allIDs
    }, {})
  return Object.entries(idsOccurances)
    .filter(([id, occurances]) => occurances > 1)
    .map(([id]) => id)
}

平均每次通话1.5毫秒。

<强>正则表达式

function getDuplicateIdsUsingRegEx(){
  const idRegex = / id=".*?"/ig
  const ids = document.body.innerHTML.match(idRegex)
  const idsOccurances = ids.reduce((allIDs, id) => {
    allIDs[id] = (allIDs[id] || 0) + 1
    return allIDs
  }, {})

  return Object.entries(idsOccurances)
    .filter(([id, occurrences]) => occurrences > 1)
    .map(([id]) => id.slice(4, -1))
}

每个通话平均5.5ms。