firefox插件-Javascript检测到零个锚点



我正在使用此代码
var anchors = document.getElementsByTagName("a");以检测HTML文档中的锚。有很多这样的标签。但alert(anchors.length)报告为0。这看起来很奇怪。你知道问题出在哪里吗?

我在firefox扩展中使用此代码

var Highlighter = {
 ...
highlightLinks: function() {
 var anchors = document.getElementsByTagName("a");
 ...
}

window.addEventListener("DOMContentLoaded", function(e) { Highlighter.highlightLinks(); }, false);

感谢

试着像这样等待dom:

window.onload = function () {
   var anchor = document.getElementsByTagName('a');
   alert(anchor.length);
}

在Firefox扩展中,如果通过覆盖将代码添加到浏览器,则document是浏览器文档(browser.xul),而不是网页文档。您可以通过content.document获取网页。

当您使用类似getElementsByTagName的函数时,它们会按原样搜索DOM树,并(在这种情况下)返回NodeList。如果您立即检查length属性,它会告诉您当时有多少个锚点。如果这个代码在文档的head部分,那么这个数字很可能为零。

如果你把代码放在文档的末尾,当所有的锚都在那里时,你应该会看到不同的结果。

(旁注:NodeList实例是活动的,所以即使你在顶部抓取它,如果你稍后在创建所有锚后检查它,它们也应该在那里。但最好避免长时间引用NodeList实例,因为它们是活动的意味着浏览器必须保持它们的最新状态,这可能会成为性能问题。)

这里有一个过早检查的例子:

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Too early</title>
<style>
  body {
    font-family: sans-serif;
  }
  p {
    margin: 0px;
  }
</style>
<script>
  alert("Too early: " + document.getElementsByTagName('a').length);
</script>
</head>
<body>
  <a href="http://google.com">Google</a>
  <a href="http://jsbin.com">JSBin</a>
  <a href="http://stackoverflow.com">StackOverflow</a>
</body>
</html>

实时复制

以及检查文档何时满载(唯一的变化是script标签在哪里):

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Too early</title>
<style>
  body {
    font-family: sans-serif;
  }
  p {
    margin: 0px;
  }
</style>
</head>
<body>
  <a href="http://google.com">Google</a>
  <a href="http://jsbin.com">JSBin</a>
  <a href="http://stackoverflow.com">StackOverflow</a>
<script>
  alert("Fully loaded: " + document.getElementsByTagName('a').length);
</script>
</body>
</html>

实时复制

可以将脚本放得更高,然后等待运行。一种常见的方法是使用window.onload,但请注意,该事件在页面加载序列中发生得非常晚,之后所有图像和其他资源都已完全下载。有时这是你想要的,但更多的时候你想早点做事情。大多数库都提供了之前发生的"就绪"或"DOM加载"事件,但是否要使用它们将取决于您正在做什么。谷歌的闭包库甚至没有提供一个(他们认为不应该,他们认为最好把脚本放在最后;见下面的链接)。

您在评论中询问了将脚本放入head标记中是否是最佳实践。这是一个常见的神话。事实上,将脚本放在head部分会使浏览器在向用户显示任何内容之前处理(下载、解释)脚本,从而降低页面的明显加载时间。即使使用window.onload,浏览器仍然必须下载并解释您的脚本,然后等待load事件触发才能运行它。请参阅我添加的链接,除非有充分的理由提前加载脚本(也有一些),否则最佳做法是在body标记的末尾加载脚本。

更多:

  • YUI加速网站的最佳实践(将脚本放在列表底部)
  • DOM准备就绪时谷歌开启

有时,您至少需要一些脚本,最关键的是,如果您需要挂接一些默认的处理程序,用户可能会在页面显示给他们之后,但在浏览器完成检索脚本、解释脚本和挂接事件处理程序之前点击这些程序!这就是"用户点击太早"的问题。你如何处理这个问题取决于你的页面和你的倾向。处理它的主要方法是:

  1. 确保在没有JavaScript的情况下一切正常,然后在加载JavaScript时提供更好的界面。这被称为"渐进增强",其主要原因不是用户点击太早的问题,而是为了支持那些由于各种原因根本没有启用JavaScript的用户。但好的是,它也有助于解决这个问题
  2. 使用文档顶部的一小段内联脚本(而不是一个单独的文件)连接一个文档范围的点击处理程序,该脚本会排队(或只是拒绝)点击。到目前为止,我的偏好是将它们排队(包括您已经完成的用户的某种指示符),然后在加载JavaScript时处理它们。用户不喜欢点击什么都不做。请注意,在用户禁用JavaScript的情况下,这可以很好地与渐进增强相结合
  3. 在您的JavaScript运行之前,没有任何重要的内容可供用户交互。对禁用JavaScript的人不友好,但也有理由。这和渐进增强之间的界限是模糊的,基本上,如果页面在没有JavaScript的情况下仍然基本上可以工作,那就是渐进增强,如果没有,那就是这个无名的较小选项
  4. 请确保页面加载速度如此之快,脚本加载速度也如此之快。但要注意慢速连接和快速用户。;-)

很可能您需要将<script>标记作为<body>中的最后一个标记,或者您可以在所有内容都加载后运行它们:<body onload="runStuff()">window.onload = function() { ... }$(document).ready(function() { ... });等。

有可能的情况是,您在<head>中出现的<script>元素中有代码,并且不做任何延迟执行的事情(例如将其放入调用onload的函数中)。

这意味着脚本会立即运行,此时DOM已经构建了一半,并且在脚本完成执行之前,主体中不存在任何内容。

最新更新