为什么自闭脚本标记不会触发错误?

时间:2014-09-27 15:06:26

标签: javascript html xhtml

以下代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>A</title>
    <script type="text/javascript" src="./script.js" />
    <script type="text/javascript">alert("This is skipped.");</script>
</head>
<body>    
</body>
</html>

在W3C上通过验证测试,Chrome在此页面上不显示任何Javascript错误。但是,整个文本<script type="text/javascript">alert("This is skipped.");不会被Javascript引擎解析,它只查找</script>标记,即使它是自我关闭的。但是,加载了文件“script.js”。

在Chrome,Firefox和IE 11中,这会导致同样的行为。

这是为什么?这里到底发生了什么?

2 个答案:

答案 0 :(得分:5)

您拥有的代码是有效的,因为您拥有XHTML doctype。在XHTML中,允许任何元素使用自闭语法(虽然它对大多数元素没有意义)。

如果您使用XML内容类型(例如Content-Type: application/xhtml+xml)提供文档,那么它也适用于浏览器。

由于您(大概)正在使用Content-Type: text/html为文档提供服务,因此浏览器会将其解析为HTML。

  1. 将解析第一个脚本标记(/将被忽略或视为无效属性)。
  2. 第二个脚本标记将由HTML解析器解析为JavaScript(因此它将被视为文本)
  3. 将解析第一个脚本结束标记(并从(1)中关闭脚本标记)
  4. 由于第一个脚本标记具有src属性,因此外部脚本将被加载并传递给JS解析器
  5. 内联“JavaScript”(第二个脚本标记)不会传递给JS解析器,因为脚本元素不能有外部内联脚本(所以你不会得到来自它的JS错误)。它可以作为文本添加到DOM中。
  6. 请注意,appendix C禁止使用脚本元素的自关闭语法,因为HTML解析器不会提供所需的结果。总而言之,XHTML比99%以上的时间更加麻烦,你应该坚持使用HTML代替XHTML。

答案 1 :(得分:0)

脚本元素通常以两种方式使用,要么包含脚本元素的两个标记之间的代码,要么包含 include 代码。当它包含代码时,它在技术上不需要script元素的结束标记。

将代码作为实际XHTML(application / xhtml + xml)进行测试的最快方法是创建一个带有 .xhtml 文件扩展名的文件,然后在Firefox中打开该文件。与两个Webkit forks(Chrome和Safari)和Trident(IE)不同,Gecko实际上会破坏页面而是显示XML解析错误消息,其他渲染引擎将在遇到XML解析错误时停止渲染。

关于正确处理script元素......

的一些事项
  1. 没有&#34; text / javascript&#34;这样的mime,实际上是application/javascript
  2. 微软的IE在IE9之前并不理解JavaScript,只是不提供JavaScript,除非它与这个不存在的奇怪的mime&#34; text / javascript&#34;一起提供。如果您在2014年或之后构建自己的东西,只需忽略Internet Explorer 8及更早版本,因为当您将某些产品推向市场时,它们的份额将完全可以忽略不计。
  3. 如果您正在尝试学习如何编写干净和严格的代码,请避免将脚本元素放在body元素中,它会强制您组织事物;如果出于性能原因将defer="defer"元素放入正文中,请确保使用script属性/值对。
  4. 如果你有很多脚本,只需在一个文件中使用PHP之类的服务器脚本语言include()多个文件。您必须使用Apache在*.js文件中启用PHP呈现,然后您需要输出正确的mime。
  5. JavaScript示例

    <script defer="defer" type="application/javascript">
    //<![CDATA[
    window.onload = function
    {
     alert('Hello World.');
    }
    // ]]>
    </script>
    

    我所提到的所有内容都可以在我的个人资料中看到我的网站,因为我的代码尽可能严格。当然严格的代码需要更长的时间,但我最终几乎完全没有维护,从长远来看,这节省了大量的时间。