今天早上有个帖子问有多少人禁用JavaScript。然后我开始想知道可以使用什么技术来确定用户是否禁用了它。

有人知道一些简单的方法来检测JavaScript是否被禁用吗?我的意图是给一个警告,如果浏览器没有启用JS,站点将无法正常运行。

最终,我想把它们重定向到能够在没有JS的情况下工作的内容,但我需要这个检测作为一个占位符来开始。


当前回答

在meta noscript内部添加刷新不是一个好主意。

因为noscript标签不符合XHTML 属性值“Refresh”是非标准的,不应该使用。“刷新”将页面的控制权从用户手中夺走。使用“刷新”将导致W3C的Web内容可访问性指南失败 ——参考http://www.w3schools.com/TAGS/att_meta_http_equiv.asp。

其他回答

在主体上使用.no-js类,并基于.no-js父类创建非javascript样式。 如果javascript被禁用,你会得到所有的非javascript样式, 如果有JS支持,.no- JS类将被替换,像往常一样提供所有的样式。

 document.body.className = document.body.className.replace("no-js","js");

通过modernizr在HTML5样板http://html5boilerplate.com/中使用的技巧,但你可以使用一行javascript来替换类

Noscript标签是可以的,但是为什么在你的HTML中有额外的东西,当它可以用CSS完成时

我建议您反过来编写不引人注目的JavaScript。

使您的项目的功能为禁用JavaScript的用户工作,当您完成后,实现您的JavaScript ui增强。

https://en.wikipedia.org/wiki/Unobtrusive_JavaScript

例如,您可以使用document之类的东西。Location = 'java_page.html'将浏览器重定向到一个新的脚本加载页面。重定向失败意味着JavaScript不可用,在这种情况下,您可以求助于CGI程序或在标记之间插入适当的代码。(注意:NOSCRIPT仅在Netscape Navigator 3.0及更高版本中可用。)

信贷 http://www.intranetjournal.com/faqs/jsfaq/how12.html

当然,cookie和HTTP报头是很好的解决方案,但两者都需要显式的服务器端参与。

对于简单的网站,或者我没有后端访问,我更喜欢客户端解决方案。

--

我使用下面的代码为HTML元素本身设置一个class属性,这样我的CSS就可以处理几乎所有其他显示类型逻辑。

方法:

1)将<script>document.getElementsByTagName('html')[0]. classlist .add('js-enabled');</script>放在<html>元素之上。

警告! ! ! ! 这个方法,将覆盖所有<html>类属性,更不用说可能不是“有效”的html,但在所有浏览器中都可以工作,我已经测试过了。

*注意:由于脚本运行的时间,在<html>标记被处理之前,它最终得到一个没有节点的空classList集合,所以在脚本完成时,<html>元素将只给出您添加的类。

2)保留所有其他<html>类属性,只需将script <script>document.getElementsByTagName('html')[0]. classlist .add('js-enabled');</script>放在<html>标签后面。

在这两种情况下,如果JS被禁用,则不会对<html>类属性进行任何更改。

选择

这些年来,我使用了其他一些方法:

    <script type="text/javascript">
    <!-- 
        (function(d, a, b){ 
            let x = function(){
                // Select and swap
                let hits = d.getElementsByClassName(a);
                for( let i = hits.length - 1; i >= 0; i-- ){
                    hits[i].classList.add(b);
                    hits[i].classList.remove(a);
                }
            };
            // Initialize Second Pass...
            setTimeout(function(){ x(); },0);
            x();
        })(document, 'no-js', 'js-enabled' );
    -->
</script>

//简化为:

<script type="text/javascript">
    <!-- 
        (function(d, a, b, x, hits, i){x=function(){hits=d.getElementsByClassName(a);for(i=hits.length-1;i>=0;i--){hits[i].classList.add(b);hits[i].classList.remove(a);}};setTimeout(function(){ x(); },0);x();})(document, 'no-js', 'js-enabled' );
    -->
</script>

这将在页面中循环两次,一次在页面中它所在的位置,通常在<html>和 再次页面加载后。需要两次,因为我注入了一个头。一个CMS的tpl文件,我没有后端访问,但想为no-js片段提供样式选项。

第一步,将设置.js启用的类,允许任何全局样式生效,并阻止大多数进一步的回流。第二步,是所有后来包含的内容的总称。

推理:

主要原因是,我关心是否启用JS是为了“样式化”的目的,隐藏/显示一个表单,启用/禁用按钮或重新设置滑块、表格和其他需要JS“正确”运行的表示和布局,如果没有JS来动画或处理交互,将是无用或不可用的。

此外,你不能直接用javascript检测,如果javascript被“禁用”…只有当它是“启用”时,通过执行一些javascript,所以你要么依赖<meta http-equiv="refresh" content="2;url=/url/to/no-js/content.html" />,要么你可以依靠CSS来切换样式,如果javascript执行,切换到“启用js”模式。

在某些情况下,倒着做就足够了。使用javascript添加一个类:

// Jquery
$('body').addClass('js-enabled');

/* CSS */
.menu-mobile {display:none;}
body.js-enabled .menu-mobile {display:block;}

这可能会在任何复杂的事情上产生维护问题,但对于某些事情来说,这是一个简单的修复。而不是试图检测它什么时候没有加载,只是根据它加载的时候样式。