我刚刚遇到一个很难解决的主要错误,经过大量的工作后发现它是因为两个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。
答案 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;
以下是使用Set
s和Map
s的替代方案,以及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);
方法之间较少数量的中间数组:
<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;
答案 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。