#05: DOM 就绪全解析

我们已经谈了很多关于选择器的内容。jQuery 选择器,比如 $(“h1”),会选择页面上所有的 <h1> 元素。但是,当它不起作用的时候怎么办呢?这里有一个选择器会失败的例子

<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">

  <title>Learning jQuery</title>

  <script src="js/jquery-2.0.3.js"></script>
  <script>
    $("h1").css("color", "red");
  </script>
</head>

<body>
  
  <h1>Hello, World!</h1>

</body>

</html>

那个 <h1> 元素会变成红色吗?不会。为什么呢?原因是在 jQuery 代码运行时,还没有找到 <h1> 元素。它还没有进入 DOM。这是因为 HTML 是从上到下读取的。想象一下浏览器一行一行地读取,直到读取到包含 jQuery 选择器的行,它只知道这一行和它上面的所有内容。所以没有找到 <h1> 元素,也没有发生颜色改变。

我们如何解决这个问题呢?最好的方法是在页面底部,也就是 </body> 标签之前加载 JavaScript 文件。JavaScript 文件在下载和运行时会“阻塞”页面渲染,所以无论如何都会让页面加载速度更快。但是,这也有一个好处,就是我们的 jQuery 选择器会找到它们应该找到的所有内容。

在底部加载脚本看起来像这样

<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Learning jQuery</title>
</head>

<body>
  
  <h1>Hello, World!</h1>

  <script src="js/jquery-2.0.3.js"></script>
  <script>
    $("h1").css("color", "red");
  </script>

</body>

</html>

但是有时脚本会在头部加载。有很多理由,大多数都是不好的理由,但是让我们不要在没有细节的情况下过于武断 =)。

即使我们被迫在头部加载脚本,我们仍然可以用一种相当令人满意的方式来解决找不到元素的问题。我们通过 jQuery 的“DOM 就绪”函数来实现。简单来说,就是文档完成并准备被操作时。它看起来像这样

$(document).ready(function() {

});

还有一个更短的版本,它做的事情完全一样

$(function() {

});

将你的代码放在这样的函数中,可以确保它在文档就绪之前不会运行。实际上,它使用了一段相当巧妙的代码来实现这一点,当然,跨浏览器实现起来很困难。它很酷的一点是速度很快。它与等待整个窗口加载不同,因为整个窗口加载很慢,因为它要等到所有资源都下载完成才会触发。DOM 就绪要快得多。如果你确实需要等待资源完成(例如,你需要测量图像大小),你可以像这样等待它

$(window).load(function() {

});

使用 DOM 就绪来修复我们之前的头部 JavaScript 问题,代码看起来像这样

<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">

  <title>Learning jQuery</title>

  <script src="js/jquery-2.0.3.js"></script>
  <script>
  $(function() {
    $("h1").css("color", "red");
  });
  </script>
</head>

<body>
  
  <h1>Hello, World!</h1>

</body>

</html>