使用noscript嵌入额外的样式

28
我有一个符合XHTML strict规范的网页,其中有一个由JavaScript控制的透明度为0的div。脚本通过mouseover事件将其设置为不透明并显示。当没有启用JavaScript时,该div保持不可见。但这会导致内容无法访问。我不想让div始终可见,然后再通过脚本将其变为透明,因为该div位于文档底部,每次加载页面时都会产生明显的闪烁。
我尝试使用noscript标签嵌入额外的样式表,仅供没有启用JavaScript的用户使用,但这违反了XHTML strict规范验证。是否有其他方法可以在noscript块中包含额外的样式信息并符合XHTML验证?
ED: 通过一个简单的测试用例,我得到了一个验证错误:document type does not allow element "style" here. 这是在一个空的XHTML Strict文档中,一个style元素在noscript元素内。noscript在body内。

遇到相同问题的人可能应该看一下这个问题 - Clément
7个回答

78

在HTML5中,头部的noscript是有效的。在此之前它是无效的。我刚刚测试了一下,在当前版本的Firefox、Safari、Chrome、Opera和IE中都可以正常工作。

<!doctype html>
<html>
    <head>
        <noscript>
            <style>body{background:red}</style>
        </noscript>
    </head>
    <body>
        <p>is this red? it should <script>document.writeln("not");</script> be. <noscript>indeed.</noscript></p>
    </body>
</html>

迄今为止最好的解决方案。 - Nicky

16
为了解决验证问题:noscript 只允许在 body 元素中使用,style 只允许在 head 中使用。因此,后者不允许在前者内部使用。
关于一般问题:您需要通过CSS + JavaScript将
元素默认设置为可见,然后隐藏它。这就是“逐步增强”模型。我注意到您说您“不想这样做是因为会出现闪烁”,但我不确定具体是什么原因导致了这个问题-很可能您可以修复它,所以也许您应该把这个作为一个问题发布出来。

13
是的,HTML5 明确允许head中使用noscript - mrec
针对使用WebForms的人们的一个警告,即使现在noscript可以与head中的样式一起使用。任何来自updatepanel的postback(如果响应包含此标记)都将应用所述样式,无论JS是否被允许。解决方法是不要在postback的head中呈现它。 - CrudaLilium

12

关于我的答案的说明

我写这篇文章是因为意识到它来自2008年。

由于我遇到了类似的问题,所以我想继续以当前的答案进行回答。

我的实际答案

像Boby Jack说的那样,在正文中不允许使用style标签。我自己也做过与你(Joshua)相同的事情,但是Jack的“渐进增强”使我没有非抽象解决方案,但后来我发现了一种在此线程上找不到答案的解决方案。

所有这取决于您的样式结构。

我的建议是在头部的最开始明确使用像modernizr这样的工具,并采用Paul Irish的HTML5Boilerplate建议。

长话短说

  1. Html标记有一个带有no-jsclass属性
  2. Head标记包含第一个modernizr javascript作为第一个脚本
  3. CSS在适当的位置具有元素(.hide-me),其带有display:none
  4. 然后是.no-js .hide-me { display:block }

详细内容

请参见Paul Irish的HTML5boilerplate,并根据需要进行XHTML调整 :)

1. Html有一个带有.no-js的class属性

<!doctype html>
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
<!--[if IE 7]>    <html class="no-js ie7 oldie" lang="en"> <![endif]-->
<!--[if IE 8]>    <html class="no-js ie8 oldie" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->

引用自html5boilerplate.com

2. 头部标签将包含第一个现代化的JavaScript文件

执行Modernizr将使用支持的内容构建html属性。

将会构建出类似于以下的内容:

<html class=" js flexbox canvas canvastext webgl no-touch geolocation postmessage websqldatabase indexeddb hashchange history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients cssreflections csstransforms csstransforms3d csstransitions fontface generatedcontent video audio localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths" lang="en">

注意:这是来自Google Chrome中的modernizr测试。

第一个是js,但如果Modernizr没有运行(没有JavaScript),则no-js将保留在那里。

3.CSS在正确的位置使用了具有display:none属性的元素(.hide-me)

...你知道剩下的 :)


无法与XHTML 1.0(既不是Transitional,也不是Strict)一起使用。原因:“class”不是<html>标签中允许的属性。 我的意思是它在浏览器中会正常显示,但您将无法通过XHTML验证(例如validator.w3.org)。 - izogfif
确实,它不符合XHTML 1.0的规范。但是如果您在未指定“application/xhtml+xml”之前发送内容而不发送头文件[请参见W3C](http://www.w3.org/TR/xhtml-media-types/#ref-rfc3236),它也会使其无效。是吧 :) 但是,我仍然认为违反<html/>标签的规则比过去的方式要便宜。 - renoirb

11

head 中使用 script 块,并使用 document.write 添加一个 style 元素:

<head>
...
 <script type="text/javascript">
 //<![CDATA[
  document.write('<style type="text/css">.noscript{display:none}</style>');
 //]]>
 </script>
...
</head>

2
小心使用document.write() - https://dev59.com/l3RA5IYBdhLWcg3w2xwI - And Finally
我知道这是2008年的内容,但伙计,整个重点就在于不使用 JavaScript 来完成这个任务 lmao。 - briann

2

2016年更新:

根据w3school的说明:

HTML 4.01和HTML5之间的区别

在HTML 4.01中,<noscript>标签只能用于<body>元素内。

在HTML5中,<noscript>标签可以用于<head><body>中。

HTML和XHTML之间的区别

XHTML不支持<noscript>标签。

我的扩展菜单(列表等)解决方案:

我将它放在头部像这样:

<header>
    <noscript>
        <link rel="stylesheet" href="assets/css/x_no_script.css">
    </noscript>
</header>

x_no_script.css 文件中,我设置了我想要的选择器。
max-height: 9999px;
overflow: visible;

通过这种方式,当JavaScript被禁用或不存在时,我的菜单将得到扩展。


0
如果使用XHTML,诀窍是使用两个CSS文件。一个全局的和一个js-one,为启用JavaScript的浏览器调整全局的CSS文件。

style.css:

.hidden {
  visibility:hidden;
}

style-js.css:

.hidden {
  visibility:visible;
}

test.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
  <title>Test page</title>
  <link href='css/style.css' rel='stylesheet' type='text/css' />
  <script type="text/javascript">
  //<![CDATA[
    //document.write("<link href='css/style-js.css' rel='styleSheet' type='text/css' />"); 
    //is not legal in XHTML, we do the long way:
    var l=document.createElementNS("http://www.w3.org/1999/xhtml","link");
    l.setAttribute("rel", "stylesheet");
    l.setAttribute("type", "text/css");
    l.setAttribute("href", "/css/style-js.css");
    document.getElementsByTagName("head")[0].appendChild(l);
  //]]>
  </script>
</head>
<body>
  <div class="hidden">
    <p>Only displayed at JavaScript enabled browsers</p>
  </div>
</body>
</html>

tutorials.de提出的主要思路。Estelle Weyl的博客关于XHTML有效性的提示。CodingForums关于createElementNS的提示。


document.write 不是有效的 XHTML。 - Chris_F
谢谢你的提示。我改进了代码。希望现在它是有效的。不幸的是,HTML验证器(http://users.skynet.be/mgueury/mozilla/)不检查JavaScript代码。 - koppor

0
你遇到了什么验证错误?<noscript>在XHTML中是允许的,但它是块级元素,所以请确保它不在<p><span>等标签内。

XHTML 1.0:<noscript> 只允许在 body 中使用,<script> 只允许在 head 中使用。 - koppor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接