警告DOM位置的代码

时间:2011-06-30 10:39:54

标签: jquery javascript

  

可能重复:
  JQuery to check for duplicate ids in a DOM

假设我有一个代码:

<div id="one">
    <div id="two"></div>
    <div id="three"></div>
</div>

<div id="four">
    <div id="two"></div>
</div>

<div id="one">
  <p id="five">
    <span id="three"></span>
  </p>
</div>

(包含不同DOM项的大型HTML代码)。

目标:

是否可以构建一个jQuery或JavaScript代码来提醒我文档中id与位置的重复。这里的位置意味着如下;

> duplicate id: 'div#two' > within `div#four`, `div#one` 
> duplicate id: 'div#one' > parent of `p#five`
> duplicate id: 'span#three' > within `p#five` and such a pattern.

注意:

我发现了一个与我类似的问题,但不完全正确。因为它与之前提出的任何问题都不重复。所以不要关闭它。

2 个答案:

答案 0 :(得分:4)

如果你想做的只是根除重复的id,你应该验证你的HTML。

http://validator.w3.org/

这将提醒您重复ID并确保您的代码格式正确。

答案 1 :(得分:3)

注意:阅读所有警告。这段代码的目的是说明问题的本质,即纯JS解决方案是不可取的。

首先,希望这说明有时候可行的​​事情并不总是可取的。有大量令人敬畏的工具可以提供更好的错误检查,例如W3C's validator或使用它的加载项/扩展程序,例如Chrome的Validity。绝对使用那些。

但无论如何,这是一个极简主义的例子。请注意,没有任何DOM引用其自己的行号,因此您必须从innerHTML获取整个documentElement属性作为字符串。您匹配该字符串的一部分,然后将其分解为匹配位置的子字符串,然后计算回车数。显然,这段代码可能会被广泛重构,但我认为这一点很明确(对于那些想要它的人来说也是jsFiddle example,虽然这些行会是fubar):

修改

我已将正则表达式更新为不匹配<div>id="a"</div>等示例。尽管如此,如果OP需要一些纯粹的JS,那么他将不得不依赖于这个或一个相当复杂的版本非常小的好处。底线是DOM节点和行号之间没有关联。您必须自己确定ID属性的位置,然后将它们追溯到它们的位置。这非常容易出错。它可能在编程实践中有所作为,但在现实世界中是非常不可取的。最好的解决方案 - 我在这里第四次重申 - 是一个扩展或加载项,它只会将您的页面发送到像W3C这样的真实验证器。

下面的代码旨在“正常工作”,因为没有好办法去做OP所要求的。

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Test</title>
  </head>
  <body>
    <div id="a"></div>
    <div id="a"></div> <!-- catches this -->
    <div id="b"></div>
    <div>id="a"</div>
    <div id="c"></div>
    <div id="c"></div> <!-- catches this -->
    <span>[id="a"]</span>
    <script>
    var re = /<[^>]+id="(.*?)"[^>]*>/g; // match id="..."
    var nl = /\n\r?/g;                  // match newlines
    var text = document.documentElement.innerHTML;
    var match;
    var ids = {};                       // for holding IDs
    var index = 0;
    while (match = re.exec(text)) {
      // Get current position in innerHTML
      index = text.indexOf(match[0], index + 1);

      // Check for a match in the IDs array
      if (match[1] in ids) {
        // Log line number based on how many newlines are matched 
        // up to current position, assuming an offset of 3 -- one
        // for the doctype, one for <html>, and one for the current
        // line
        console.log("duplicate match at line " +
          (text.substring(0, index).match(nl).length + 3));
      } else {
        // Add to ID array if no match
        ids[match[1]] = null;
      }
    }
    </script>
  </body>
</html>