【问题标题】:Safe way to make behavioral CSS trigger based on Javascript availability基于 Javascript 可用性进行行为 CSS 触发器的安全方法
【发布时间】:2009-09-23 15:36:24
【问题描述】:

我一直在使用这段代码以编程方式检查 Javascript 是否可用并使用不同的行为 CSS。

如果禁用 Javascript,它只会显示正常的无序列表。

如果启用了javascript,列表将在页面加载后进行转换,然后 显示给用户(避免无序列表元素在转换之前/期间可能的重绘/闪烁)。

是否有可能 document.getElementsByTagName('body') 在页面渲染的这个阶段实际上可以返回一个空数组,或者它始终可用?

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
 <head>
  <title>Title</title>
 <style type="text/css">
  .javascript ul { display:none; }
  .no_javascript ul { display:block; }
  .transformed { background-color: yellow; }
 </style>
 </head>
 <body class="no_javascript">

<script type="text/javascript">
// Inform us that javascript is available
(function() {
    var body = document.getElementsByTagName('body');
    if ( body && body[0] ) {
        body[0].className = body[0].className.replace(/no_javascript/, "javascript");
    }
})();
</script>

 <ul>
  <li>Option 1</li>
  <li>Option 2</li>
  <li>Option 3</li>
 </ul>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">

$(document).ready(function() {
 $(".javascript ul").addClass("transformed").css('display','block');
});

</script>
 </body>
</html>

更新:How to eliminate post-render "flicker"? 似乎与我的问题重复。这是我试图正确解决的问题。

【问题讨论】:

    标签: javascript jquery html css


    【解决方案1】:

    据我所知,在 HTML 中 脚本是按顺序解析的(除非它们具有 defer 属性,但那是另一回事了)。

    如果您查看SCRIPT section in HTML4.01 specs,您会看到:

    可以在加载文档时评估脚本以动态修改文档的内容。

    还有:

    所有 SCRIPT 元素都会在文档加载时按顺序进行评估。

    还有一个示例说明以下脚本将如何影响生成的标记:

     <TITLE>Test Document</TITLE>
     <SCRIPT type="text/javascript">
         document.write("<p><b>Hello World!<\/b>")
     </SCRIPT>
    

    与此 HTML 标记具有相同的效果:

     <TITLE>Test Document</TITLE>
     <P><B>Hello World!</B></P>
    

    由于您的脚本包含在 BODY 之后并且没有 DEFER 属性,因此可以安全地假设在脚本执行期间,已经解析了 BODY 标记并且已经创建了 BODY 元素(但不是其余的树,例如从相关脚本中的标记创建的元素!)。

    当然,你真的应该使用更快、更兼容和更短的document.body,而不是document.getElementsByTagName('body')[0] :)

    事实上,我会替换整个块:

    (function() {
        var body = document.getElementsByTagName('body');
        if ( body && body[0] ) {
            body[0].className = body[0].className.replace(/no_javascript/, "javascript");
        }
    })();
    

    类似:

    document.body.className = document.body.className.replace('no_javascript', 'javascript');
    

    【讨论】:

    • 我已经在我的代码中用 document.body 替换了我的 getElementsByTagName('body')[0]。谢谢你的建议。但是代码不应该是 document.body.className = document.body.className.replace('no_javascript', 'javascript') 因为字符串在 JavaScript 中是不可变的吗? AFAIK,str.replace() 返回更改后的字符串,它不会对字符串进行就地操作。
    • @Robin 感谢您的关注!我更改了答案以修复此错误。
    【解决方案2】:

    嗯...你可以使用document.body。比较安全。

    【讨论】:

    • 根据我的经验,它一直是:)
    猜你喜欢
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 2012-10-12
    • 2017-05-09
    • 2023-02-08
    相关资源
    最近更新 更多