Javascript 如何识别HTML元素ID';是什么在重复?

Javascript 如何识别HTML元素ID';是什么在重复?,javascript,html,Javascript,Html,我刚刚发现了一个很难解决的主要错误,经过大量工作后才发现这是因为两个HTML元素具有相同的ID属性 是否有一个命令可以在整个DOM中显示双ID 更新: 在阅读了所有评论之后,我在一个相对较大的网站(html5 studio)上测试了不同的方法,下面是结果 如果您有比这两种更好的方法,请发表评论。 两个答案返回相同的结果,但看起来querySelectorAll确实更快: 查询选择全部 function getDuplicateIdsUsingQuerySelector(){ const i

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

是否有一个命令可以在整个DOM中显示双ID


更新:


在阅读了所有评论之后,我在一个相对较大的网站(html5 studio)上测试了不同的方法,下面是结果

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

两个答案返回相同的结果,但看起来
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)
}
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毫秒

Regex

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))
}
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。

document.queryselectoral('[id=“dupid”]')
将提供多个结果

[编辑]

我用另一种方法制作了这个JSFIDLE,如果您不知道应该使用什么ID,那么可以找到所有重复项

是否有一个命令可以在整个DOM中显示双ID

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

$("[id='idValue']").length
如果该值不止一个,则您有一个副本

一旦发现存在重复项,就需要检查各个元素的层次结构

$("[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;
    }
});
现在
duplicateID
是包含重复ID的数组。对其进行迭代以检查其DOM层次结构,以便可以在整个DOM中发现它

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

如果您使用的是Chrome,您可以通过打开控制台->审核并选中最佳实践复选框来运行审核。如果有任何双id,它们将显示在那里。

这将为您提供一个包含多次出现的所有id的数组

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

constduplicateID=Object.entries(Array.from(document.queryselectoral(“[id]”),({id})=>id)
.reduce((allIDs,id)=>(allIDs[id]=(allIDs[id]| | 0)+1,allIDs),{}))
.filter(([id,引用]=>引用>1)
.map(([id])=>id);
console.log(重复ID)


理想情况下,您不应该有多个具有相同id的元素。我知道您的问题是检测是否存在具有相同id的元素。IMHO,无论您如何尝试,这可能都是一个短期解决方案。您需要解决问题的根源,即没有两个元素具有相同的id。

在阅读了所有评论后,我在一个相对较大的网站(html5 studio)上测试了不同的方法,下面是结果

两个答案返回相同的结果,但看起来
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)
}
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毫秒

Regex

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))
}
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.5毫秒。

他很可能希望在不知道实际id值的情况下获得所有
id
副本。我将测试这是否比我找到的正则表达式更快。@VitalikZaidman正则表达式总是比基于DOM操作的方法慢。然而,这不应该是一个问题,因为ID无论如何都应该是唯一的,因此理想情况下两者都应该占用大约0毫秒的时间。无论如何,这两种方法都有O(n)的复杂性,所以它们的效率是相等的。这对我来说是个问题,因为这段代码将作为自动测试的一部分运行,并且会一次又一次地运行,因此每个ms matters for meThis都将作为我们网站的自动测试的一部分运行。很明显,这段代码不会修复重复的ID,它只会检测到它们。太棒了!我想这就是你正在尝试的——避免两个元素相同的ID。