调试 HTML

编写 HTML 很棒,但如果出现问题,你无法找出代码中的错误怎么办?本文将介绍一些工具,可以帮助你查找和修复 HTML 中的错误。

先决条件 熟悉 HTML,例如,HTML 入门HTML 文本基础创建超链接
目标 学习使用调试工具查找 HTML 中问题的基本知识。

调试并不可怕

在编写任何类型的代码时,通常一切正常,直到遇到可怕的错误的那一刻——你做错了什么,导致代码无法运行——要么完全无法运行,要么无法按照你的预期运行。例如,以下显示了尝试 编译 使用 Rust 语言编写的简单程序时报告的错误。

A console window showing the result of trying to compile a rust program with a missing quote around a string in a print statement. The error message reported is error: unterminated double quote string.

这里,错误消息相对容易理解——“未终止的双引号字符串”。如果你查看代码,你可能会发现 println!(Hello, world!"); 逻辑上可能缺少双引号。但是,随着程序变得越来越大,错误消息会迅速变得更加复杂,难以理解,即使是简单的案例对于不了解 Rust 的人来说也可能看起来有点令人生畏。

然而,调试并不一定很可怕——对任何编程语言或代码进行编写和调试感到舒适的关键是熟悉语言和工具。

HTML 和调试

HTML 的理解并不像 Rust 那样复杂。HTML 在浏览器解析并显示结果之前不会被编译成不同的形式(它被解释,而不是编译)。而且 HTML 的 元素 语法可以说比 Rust、JavaScriptPython 这样的“真正的编程语言”更容易理解。浏览器解析 HTML 的方式比运行编程语言的方式更宽松,这既是好事,也是坏事。

宽松代码

那么,我们所说的宽松是什么意思呢?通常,当你犯代码错误时,你会遇到两种主要的错误类型:

  • 语法错误:这些是代码中的拼写或标点错误,实际上会导致程序无法运行,就像上面显示的 Rust 错误一样。只要你熟悉该语言的语法并知道错误消息的含义,这些错误通常很容易修复。
  • 逻辑错误:这些错误是语法实际上正确,但代码不是你想要的那样,这意味着程序运行不正确。这些错误通常比语法错误更难修复,因为没有错误消息可以引导你找到错误的来源。

HTML 本身不会出现语法错误,因为浏览器以宽松的方式解析它,这意味着即使存在语法错误,页面也会显示。浏览器内置规则来规定如何解释编写错误的标记,因此即使结果不符合预期,你也会获得可以运行的东西。当然,这仍然是一个问题!

注意: HTML 以宽松的方式解析,因为在创建网页时,人们决定允许人们发布自己的内容比确保语法绝对正确更重要。如果一开始就更加严格,网页可能不会像今天这样流行。

主动学习:学习宽松代码

现在,是时候学习 HTML 代码的宽松性了。

  1. 首先,下载我们的 debug-example 演示 并将其保存到本地。这个演示故意包含了一些内置错误供我们探索(HTML 标记被称为格式错误,而不是格式良好)。
  2. 接下来,在浏览器中打开它。你将看到类似这样的内容:一个简单的 HTML 文档,标题为 HTML 调试示例,以及一些关于常见 HTML 错误的信息,例如未闭合的元素、嵌套错误的元素和未闭合的属性。
  3. 这看起来不太好;让我们看看源代码,看看我们是否能找出原因(只显示正文内容)
    html
    <h1>HTML debugging examples</h1>
    
    <p>What causes errors in HTML?
    
    <ul>
      <li>Unclosed elements: If an element is <strong>not closed properly,
          then its effect can spread to areas you didn't intend
    
      <li>Badly nested elements: Nesting elements properly is also very important
          for code behaving correctly. <strong>strong <em>strong emphasized?</strong>
          what is this?</em>
    
      <li>Unclosed attributes: Another common source of HTML problems. Let's
          look at an example: <a href="https://www.mozilla.org/>link to Mozilla
          homepage</a>
    </ul>
    
  4. 让我们回顾一下问题
    • 段落列表项 元素没有结束标签。从上面的图像来看,这似乎并没有对标记渲染造成太大的影响,因为很容易推断出哪个元素应该结束,哪个元素应该开始。
    • 第一个 <strong> 元素没有结束标签。这有点问题,因为我们无法轻易判断元素应该在哪里结束。事实上,其余的所有文本都被强加了强调。
    • 本节嵌套错误:<strong>strong <em>strong emphasized?</strong> what is this?</em>。由于之前的问题,我们无法轻易判断它是如何被解释的。
    • href 属性值缺少结束双引号。这似乎造成了最大的问题——链接根本没有渲染出来。
  5. 现在,让我们看看浏览器渲染的标记,而不是源代码中的标记。为此,我们可以使用浏览器开发者工具。如果你不熟悉如何使用浏览器的开发者工具,请花几分钟时间回顾 探索浏览器开发者工具
  6. 在 DOM 检查器中,你可以看到渲染后的标记是什么样的:Firefox 中的 HTML 检查器,突出显示了我们示例的段落,显示了文本“What causes errors in HTML?”在这里你可以看到段落元素已经被浏览器关闭了。
  7. 使用 DOM 检查器,让我们详细地探索代码,看看浏览器是如何尝试修复我们的 HTML 错误的(我们在 Firefox 中进行了审查;其他现代浏览器应该给出相同的结果)
    • 段落和列表项被赋予了结束标签。
    • 我们不清楚第一个 <strong> 元素应该在哪里关闭,因此浏览器用自己的强标签将每个单独的文本块包装起来,一直到文档底部!
    • 浏览器已修复不正确的嵌套,如下所示
      html
      <strong>
        strong
        <em>strong emphasized?</em>
      </strong>
      <em> what is this?</em>
      
    • 缺少双引号的链接已被完全删除。最后一个列表项看起来像这样
      html
      <li>
        <strong>
          Unclosed attributes: Another common source of HTML problems. Let's look
          at an example:
        </strong>
      </li>
      

HTML 验证

因此,从上面的例子可以看出,你真的需要确保你的 HTML 格式良好!但是怎么做呢?在像上面这样的小例子中,很容易搜索这些行并找到错误,但对于一个庞大而复杂的 HTML 文档怎么办呢?

最好的策略是首先使用 Markup Validation Service 运行你的 HTML 页面——该服务由 W3C 创建和维护,W3C 是负责维护定义 HTML、CSS 和其他 Web 技术规范的组织。这个网页将 HTML 文档作为输入,对其进行处理,并给你一个报告,告诉你 HTML 中有什么问题。

The HTML validator homepage

为了指定要验证的 HTML,你可以提供一个网页地址,上传一个 HTML 文件,或直接输入一些 HTML 代码。

主动学习:验证 HTML 文档

让我们使用我们的 示例文档 来尝试一下。

  1. 首先,在另一个浏览器选项卡中加载 Markup Validation Service,如果它还没有打开。
  2. 切换到 Validate by Direct Input 选项卡。
  3. 复制示例文档的所有代码(不仅仅是正文),并将其粘贴到 Markup Validation Service 中显示的大型文本区域中。
  4. 按下Check按钮。

这应该会给你一个错误列表和其他信息。

A list of HTML validation results from the W3C markup validation service

解释错误消息

错误消息通常很有用,但有时它们并不那么有用;通过练习,你可以学会如何解释这些消息来修复代码。让我们看一下这些错误消息,看看它们是什么意思。你会发现每条消息都带有一个行号和列号,以帮助你轻松地找到错误。

  • “暗示结束标签 li,但存在开放元素”(2 个实例):这些消息表明存在一个应该关闭的元素。结束标签是暗示的,但实际上并不存在。行/列信息指向结束标签应该真正存在的行的下一行,但这已经是一个足够好的线索,让你知道问题出在哪里。
  • “未关闭的元素 strong”:这很容易理解——一个 <strong> 元素未关闭,行/列信息直接指向它的位置。
  • “结束标签 strong 违反嵌套规则”:这指出了嵌套错误的元素,行/列信息指出了它们的位置。
  • “在属性值内遇到文件结尾。忽略标签”:这条消息有点含糊;它指的是存在一个未正确格式化的属性值,可能在文件末尾附近,因为文件末尾出现在属性值内部。浏览器无法渲染链接这一事实应该可以让我们很好地了解哪个元素存在问题。
  • “遇到文件结尾,但存在开放元素”:这有点模棱两可,但基本上指的是存在需要正确关闭的开放元素。行号指向文件的最后几行,这条错误消息带有一行代码,指出了开放元素的示例
    example: <a href="https://www.mozilla.org/>link to Mozilla homepage</a> ↩ </ul>↩ </body>↩</html>
    

    注意:缺少结束引号的属性可能会导致开放元素,因为文档的其余部分将被解释为属性的内容。

  • “未关闭的元素 ul”:这并不十分有用,因为 <ul> 元素已经正确关闭。这个错误是由于 <a> 元素未关闭而产生的,这是因为缺少结束引号。

如果你无法弄清楚每条错误消息的含义,不用担心——一个好主意是尝试一次修复几个错误。然后尝试重新验证你的 HTML,看看还剩下哪些错误。有时,修复一个早期错误也会消除其他错误消息——多个错误通常是由单个问题造成的,形成多米诺骨牌效应。

当你看到输出中出现以下横幅时,就知道所有错误都已修复

Banner that reads "The document validates according to the specified schema(s) and to additional constraints checked by the validator."

总结

到这里,我们就介绍完了 HTML 调试的基础知识。这些技能对你日后调试 CSS、JavaScript 和其他类型的代码将非常有用。这也标志着 HTML 入门模块学习文章的结束——现在你可以通过我们的评估来测试自己:第一个评估链接在下面。