为什么自关闭脚本元素不起作用?

时间:2008-09-16 06:52:39

标签: javascript html internet-explorer xhtml

浏览器无法正确识别的原因是什么:

<script src="foobar.js" /> <!-- self-closing script element -->

只有这一点得到承认:

<script src="foobar.js"></script>

这会破坏XHTML支持的概念吗?

注意:此声明至少对所有IE(6-8 beta 2)都是正确的。

12 个答案:

答案 0 :(得分:454)

XHTML 1规范说:

С.3. Element Minimization and Empty Element Content

  

给定内容模型不是EMPTY的元素的空实例(例如,空标题或段落)不使用最小化形式(例如使用<p> </p>而不是{{1} })。

XHTML DTD将脚本元素指定为:

<p />

答案 1 :(得分:225)

要添加到Brad和squadette所说的内容,自动关闭的XML语法<script />实际上 是正确的XML,但是为了在实践中工作,您的Web服务器也需要将您的文档作为格式正确的XML发送,并在HTTP Content-Type标头中使用XML模仿类似application/xhtml+xmltext/html)。

但是,发送XML mimetype会导致您的页面不被IE7解析,IE7只喜欢text/html

来自w3

  

总之,'application / xhtml + xml'   应该用于XHTML系列   文档,以及'text / html'的使用   应该限制​​为HTML兼容   XHTML 1.0文档。 '应用程序/ XML'   也可以使用'text / xml',但是   在适当的时候   'application / xhtml + xml'应该被使用   而不是那些通用的XML媒体   类型。

几个月前我对此感到困惑,唯一可行的(与FF3 +和IE7兼容)解决方案是使用旧的<script></script>语法和text/html(HTML语法+ HTML mimetype)。< / p>

如果您的服务器在其HTTP标头中发送text/html类型,即使使用其他正确形成的XHTML文档,FF3 +也将使用其HTML呈现模式,这意味着<script />将无效(这是一个更改) ,Firefox以前不太严格。)

无论在您的文档中是否有http-equiv元素元素,XML序言或文档类型,都会发生这种情况 - 一旦获得text/html标头,Firefox就会分支,从而确定HTML或XML解析器查看文档内部,HTML解析器无法理解<script />

答案 2 :(得分:150)

答案 3 :(得分:138)

其他人已回答“如何”和引用规范。经过几个小时的挖掘错误报告和邮件列表,这是“为什么没有<script/>”的真实故事。


HTML 4

HTML 4基于SGML

SGML有一些shorttags,例如<BR//<B>text</><B/text/<OL<LI>item</LI</OL>。 XML采用第一种形式,将结尾重新定义为“&gt;” (SGML很灵活),因此它变为<BR/>

但是,HTML并未重新定义,因此<SCRIPT/> should mean <SCRIPT>>
(是的,'&gt;'应该是内容的一部分,标签仍然关闭。)

显然,这与XHTML不兼容,打破许多网站(当浏览器足够成熟时to care about this),所以nobody implemented shorttags和规范advises against them

实际上,所有“工作”自结束标签都是带有可选结束标签的标签,这些标签位于技术上不符合的解析器上,实际上是无效的。 W3C came up with this hack帮助转换为XHTML HTML-compatible

<script>的结束标记为not optional

“自我结束”标记是HTML 4中的黑客,并且毫无意义。


HTML 5

HTML5有five types of tags,只有'void'和'外国'标签是allowed to be self-closing

由于<script>不是空的(可能有内容)并且不是外来的(如MathML或SVG),<script>无法自动关闭,无论如何你用它。

但为什么呢?他们不能把它当作外国人,特殊情况或其他什么东西吗?

HTML 5旨在通过HTML 4和XHTML 1的实现成为backward-compatible。 它不是基于SGML或XML;它的语法主要涉及记录和统一实现。 (这就是<br/> <hr/>valid HTML 5尽管HTML4无效的原因。)

自我关闭<script>是实施过去不同的标签之一。 它used to work in Chrome, Safariand Opera;据我所知,它从未在Internet Explorer或Firefox中运行。

当HTML 5被起草并被This was discussed breaks browser拒绝时,

compatibility。 自动关闭脚本标记的网页可能无法在旧浏览器中正确呈现(如果有的话)。 有other proposals,但它们也无法解决兼容性问题。

草稿发布后,WebKit更新了解析器以保持一致。

由于向后兼容HTML 4和XHTML 1,HTML 5中不会发生自我关闭<script>


XHTML 1 / XHTML 5

真的作为XHTML时,<script/>真正关闭,正如other answers所述。

除了the spec says

  

XHTML Documents ...可能标有互联网媒体类型“text / html”[RFC2854],因为它们与大多数HTML浏览器兼容。

那么,发生了什么?

无论指定的内容标头(称为asked Mozilla),

人员let Firefox parseXHTML将文档符合content sniffing。 这样就可以允许自动关闭脚本和内容嗅探was necessary,因为网络托管服务商还不够成熟,无法提供正确的标题; IE是good at it

如果first browser war没有以IE 6结尾,那么XHTML也可能在列表中。但它确实结束了。和IE 6 has a problem使用XHTML。 实际上IE did not support是正确的MIME类型at all,迫使所有人使用text/html用于XHTML,因为IE had major market share整整十年。

还有内容嗅探can be really bad,人们在说it should be stopped

最后,事实证明W3C didn't mean XHTML to be sniffable:文档 ,HTML和XHTML以及Content-Type规则。 可以说他们坚持“只要遵循我们的规范”和ignoring what was practicalcontinued在以后的XHTML版本中的错误。

无论如何,这个决定settled the matter适用于Firefox。 Chrome was born之前已经过了7年;没有其他重要的浏览器。因此决定了。

由于以下规范,仅指定doctype不会触发XML解析。

答案 4 :(得分:44)

Internet Explorer 8及更早版本不支持XHTML解析。即使您使用XML声明和/或XHTML doctype,旧的IE仍然将文档解析为纯HTML。在纯HTML中,不支持自动关闭语法。仅忽略尾部斜杠,您必须使用显式结束标记。

即使支持XHTML解析的浏览器(例如IE 9 and later)仍然会将文档解析为HTML,除非您使用XML内容类型提供文档。但在这种情况下,旧IE将根本不显示该文档!

答案 5 :(得分:26)

上面的人已经解释了这个问题,但有一件事可能会让事情变得清楚,尽管人们在HTML文档中一直使用<br/>,但这样的任何/都是如此一个位置基本上被忽略了,只有在尝试制作可解析为XML和HTML的东西时才使用。例如,请尝试使用<p/>foo</p>,然后获得常规段落。

答案 6 :(得分:22)

自关闭脚本标记不起作用,因为脚本标记可以包含内联代码,并且HTML不够智能,无法根据属性的存在打开或关闭该功能。

  

另一方面,HTML确实有一个很好的标签包括   对外部资源的引用:<link>标记,它可以是   自闭。它已经用于包括样式表,RSS和Atom   提要,规范URI和各种其他好东西。为什么不   的JavaScript?

如果你想让脚本标签自我封闭你不能像我说的那样做,但有一个替代方案,虽然不是一个聪明的方法。您可以使用自闭关链接标记并通过为其提供一种text / javascript和rel作为脚本链接到您的JavaScript,如下所示:

<link type="text/javascript" rel ="script" href="/path/tp/javascript" />

答案 7 :(得分:20)

与XML和XHTML不同,HTML不了解自动关闭语法。将XHTML解释为HTML的浏览器不知道/字符表示标签应该是自动关闭的;相反,他们将其解释为一个空属性,解析器仍然认为标签是“开放的”。

正如<script defer>被视为<script defer="defer"><script />被视为<script /="/">

答案 8 :(得分:18)

Internet Explorer 8及更早版本不支持XHTML application/xhtml+xml的正确MIME类型。如果您将XHTML作为text/html提供,您必须为这些旧版本的Internet Explorer执行任何操作,它将被解释为HTML 4.01。您只能将短语法与允许省略结束标记的任何元素一起使用。请参阅HTML 4.01 Specification

XML“简短形式”被解释为名为/的属性,它(因为没有等号)被解释为具有隐含值“/”。这在HTML 4.01中是严格错误的 - 不允许使用未声明的属性 - 但浏览器会忽略它。

IE9及更高版本support XHTML 5application/xhtml+xml一起投放。

答案 9 :(得分:5)

那是因为SCRIPT TAG不是VOID ELEMENT。

HTML文档中 - VOID ELEMENTS 需要&#34;结束标记&#34;一点都没有!

xhtml 中,一切都是通用的,因此它们都需要终止,例如a&#34;结束标签&#34 ;;包括br,一个简单的换行符,<br></br>或其简写 <br />

但是,脚本元素永远不是空格或参数元素,因为脚本标记在其他任何内容之前是浏览器指令,而不是数据描述声明。

主要是语义终止指令,例如,&#34;结束标记&#34;只有处理指令时才需要后续标记不能终止其语义。例如:

<H1>语义不能被后续<P>终止,因为它没有足够的自己的语义来覆盖并因此终止先前的H1指令集。虽然它可以将分解为一个新的段落行,但它不够强大&#34;覆盖当前字体大小&amp;样式行高倾倒流,即从H1泄漏(因为P没有它)。

这是&#34; /&#34;已经发明了(终止)信令。

类似< />的通用无描述终止标记,对于遇到的级联中的任何一次丢失都是足够的,例如:<H1>Title< />但不是总是这样,因为我们也希望能够&#34;嵌套&#34 ;,流的多个中间标记:在包裹/落入另一个级联之前分裂成种子。因此,诸如< />之类的通用终结符将无法确定要终止的属性的目标。例如:<b> 粗体 <i> 粗体斜体 < /> 斜体 </>正常。毫无疑问,我们的意图无法正确,并且很可能将其解释为粗体粗体 - 粗体粗体正常。

这就是包装器即容器诞生的概念的方式。 (这些概念是如此相似以至于无法辨别,有时同一个元素可能同时具有这两个概念。<H1>同时是包装器和容器。而<B>只是一个语义包装器。我们需要一个普通的,没有语义的容器。当然,DIV元素的发明也来了。

DIV元素实际上是2BR-Container。当然,CSS的出现使得整个情况比其他情况更糟糕,并且间接引起了许多重大后果的巨大混乱!

因为使用CSS,你可以很容易地覆盖新发明的DIV的BR行为之后的原生前后,它通常被称为“不做任何容器”#34;。哪个,自然是错的! DIV是块元素,并且在结束信令之前和之后将原生地断开流的线。不久,WEB开始遭受DIV-itis页面的困扰。他们中的大多数仍然是。

CSS的出现能够完全覆盖并完全重新定义任何HTML标记的本机行为,以某种方式设法混淆和模糊HTML存在的整个含义......

突然间,所有HTML标签看起来都像是过时的,它们被污损,剥夺了它们原有的意义,身份和目的。不知何故,你会得到他们不再需要的印象。说:单个容器包装标签足以满足所有数据的呈现。只需添加所需的属性即可。为什么不使用有意义的标签;随时创建标签名称,让CSS烦恼其余部分。

这就是xhtml的诞生方式,当然也是一种生硬的方式,是新来者付出的代价,以及对什么是什么以及什么是该死的目的的歪曲。 W3C从万维网走到了什么错了,同志们?!!

HTML的目的是将有意义的数据流式传输给人类收件人。

提供信息。

正式部分只是为了帮助清晰地传递信息。 xhtml没有对这些信息给予最轻微的考虑。 - 对此,信息绝对无关紧要。

最重要的是知道并且能够理解 xhtml不仅仅是某些扩展HTML的版本,xhtml是一个完全不同的野兽;理由;因此将它们分开是明智的。

答案 10 :(得分:2)

真正的XHTML&#39;,&#39;虚拟XHTML&#39;和HTML以及服务器发送的MIME类型的重要性为already described here well。如果你想立即试用,这里有一个简单的可编辑片段,带有实时预览,包括适用于浏览器的自闭脚本标签:

&#13;
&#13;
div { display: flex; }
div + div {flex-direction: column; }
&#13;
<div>Mime type: <label><input type="radio" onchange="t.onkeyup()" id="x" checked  name="mime"> application/xhtml+xml</label>
<label><input type="radio" onchange="t.onkeyup()" name="mime"> text/html</label></div>
<div><textarea id="t" rows="4" 
onkeyup="i.src='data:'+(x.checked?'application/xhtml+xml':'text/html')+','+encodeURIComponent(t.value)"
><?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
[<!ENTITY x "true XHTML">]>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
  <p>
    <span id="greet" swapto="Hello">Hell, NO :(</span> &x;.
    <script src="data:text/javascript,(g=document.getElementById('greet')).innerText=g.getAttribute('swapto')" />
    Nice to meet you!
    <!-- 
      Previous text node and all further content falls into SCRIPT element content in text/html mode, so is not rendered. Because no end script tag is found, no script runs in text/html
    -->
  </p>
</body>
</html></textarea>

<iframe id="i" height="80"></iframe>

<script>t.onkeyup()</script>
</div>
&#13;
&#13;
&#13;

您应该在textarea下方看到Hello, true XHTML. Nice to meet you!

对于无法使用的浏览器,您可以复制textarea的内容并将其另存为.xhtml(或.xht)扩展名(thanks Alek for this hint)的文件。

答案 11 :(得分:0)

最简单的答案是,因为该标记被表示为强制标记

  

标签省略无,开始标签和结束标签都是必需的。

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script