it-swarm.cn

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

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

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

只有这一点得到承认:

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

这是否打破了XHTML支持的概念?

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

1235
dimarzionist

XHTML 1规范说:

С.3。元素最小化和空元素内容

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

XHTML DTD 将脚本元素指定为:

<!-- script statements, which may include CDATA sections -->
<!ELEMENT script (#PCDATA)>
452
squadette

要添加到Brad和squadette所说的内容,自动关闭的XML语法<script />实际上正确的XML,但是为了在实践中工作,您的Web服务器还需要将您的文档作为正确形成的XML与XML一起发送mimetype如HTTP Content-Type标头中的application/xhtml+xml(和not作为text/html)。

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

w3

总之,'application/xhtml + xml'应该用于XHTML Family文档,'text/html'的使用应该仅限于HTML兼容的XHTML 1.0文档。也可以使用'application/xml'和'text/xml',但是在适当的时候,应该使用'application/xhtml + xml'而不是那些通用的XML媒体类型。

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

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

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

224
joelhardi

如果有人好奇,最终的原因是HTML最初是SGML的方言,这是XML的奇怪的哥哥。在SGML-land中,可以在DTD中将元素指定为自闭(例如BR,HR,INPUT),隐式可关闭(例如P,LI,TD)或明确可关闭(例如,TABLE,DIV,SCRIPT)。 XML当然没有这个概念。

现代浏览器使用的标签汤解析器是从这种传统中演化而来的,尽管它们的解析模型不再是纯粹的SGML。当然,除非您使用XML mime类型发送,否则您精心设计的XHTML将被视为编写得很糟糕的SGML风格的标签汤。这也是为什么......

<p><div>hello</div></p>

...被浏览器解释为:

<p></p><div>hello</div><p></p>

...这是一个可爱的晦涩bug的秘诀,当你尝试对DOM进行编码时,它会让你陷入困境。

149
greim

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

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

44
JacquesB

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

26
Marijn

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

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

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

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

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

就像<script defer>被视为<script defer="defer">一样,<script />被视为<script /="/">

19
rpetrich

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

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

IE9及更高版本 支持XHTML 5application/xhtml+xml一起提供。

18
Mike Dimmick

那是因为SCRIPT TAG不是一个VOID ELEMENT。

HTML文档中 - VOID ELEMENTS 不要 需要一个“结束标记”!

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

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

原则上,语义终止指令(例如,“结束标签”)仅用于处理指令,其语义不能被后续标签终止。例如:

<H1>语义不能被后面的<P>终止,因为它没有足够的自己的语义来覆盖,因此终止了前面的H1指令集。虽然它能够将 stream 打破成一个新的段落行,但它不够“强大”来覆盖当前的字体大小和样式line-height 倾倒流 ,即泄漏来自H1(因为P没有它)。

这就是发明“/”(终止)信令的方式和原因。

一般的 no-description 终止标签如< />,对于遇到的级联的任何单一下降都是足够的,例如:<H1>Title< />但情况并非总是如此,因为我们也希望能够“嵌套”,流的多个中间标记:在包裹/落入另一个级联之前分成多个种子。因此,诸如< />之类的通用终结符将无法确定要终止的属性的目标。例如:<b> bold <i> bold-italic < /> italic </>normal。毫无疑问,我们的意图无法正确,并且很可能将其解释为 bold bold-itallic bold normal。

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

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

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

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

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

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

HTML的目的是有意义的数据流传输给人类接收者。

提供信息。

正式部分仅用于帮助清晰地传递信息。 xhtml没有对信息做出丝毫考虑。 - 对它而言,信息绝对无关紧要。

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

5
Bekim Bacaj

“真正的XHTML”,“虚假XHTML”和HTML之间的区别以及服务器发送的MIME类型的重要性已经 已经在这里很好地描述了 。如果你想立即试用,这里有一个简单的可编辑片段,带有实时预览,包括适用于浏览器的自闭脚本标签:

div { display: flex; }
div + div {flex-direction: column; }
<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>

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

对于无法使用的浏览器,您可以复制textarea的内容并将其保存为带有.xhtml(或.xht)扩展名的文件( 感谢Alek提供此提示 )。

2
myf