我想要求网站访问者升级他们的浏览器,而不是使用前缀

IT技术 javascript jquery css flexbox
2021-02-04 17:33:34

我正在使用 CSS flexbox重新构建一个站点

在检查浏览器兼容性时,我发现所有现代浏览器都支持 flexbox,除了 Safari 8 和 IE 10 需要供应商前缀。

在检查 Google Analytics 时,我看到过去 6 个月内 96% 的网站访问者使用完全支持 flexbox 的浏览器。剩下的 4% 使用需要前缀或不提供支持的浏览器。

由于我们谈论的是 4% 的用户,而且这个数字会越来越小,(我喜欢让我的代码尽可能干净和简单),我正在考虑不使用前缀,而是要求用户升级他们的浏览器。

我如何定位旧版浏览器,以便向用户显示要求他们更新浏览器的消息?

这是我到目前为止所拥有的:

<!--[if IE]>
    <div class="browserupgrade">
        <p>You are using an outdated browser. Please <a href="http://browsehappy.com/">
           upgrade your browser</a> to improve your experience.</p>
    </div>
<![endif]-->

这个 IE 条件注释涵盖了我的 IE 版本 6、7、8 和 9。

这些访问者将收到带有下载当前浏览器链接的警报。但是,Microsoft 从 IE10 开始停止支持条件注释

现在我需要类似的东西:

  • 浏览器 10
  • 野生动物园 7-8
  • Opera Mini < 8
  • 安卓版UC浏览器
  • Android 浏览器 < 4.4

是否有一个简单的 JS/jQuery 脚本来处理这项工作?还是另一种轻量级的方法?


解决方案

感谢所有的答案。很明显,有很多方法可以解决这个问题(Modernizr、PHP、jQuery 函数、纯 Javascript、CSS、browser-update.org 等)。其中许多方法都可以完全有效地完成这项工作。

我选择了最简单的一个:CSS(信用@LGSon)。

此 CSS 基本上涵盖所有目标浏览器,但 IE <= 7 除外。

.browserupgrade { display: block; }
_:-ms-fullscreen, :root .browserupgrade { display: none; }
:-o-prefocus, .browserupgrade { display: none; }
@supports (display: flex) { .browserupgrade { display: none; }}

有关详细信息,请参阅答案。

对于那些使用 IE <= 7 的相对较少的访问者,HTML 中的条件注释:

<!--[if lte IE 7]>
    <div style=" ... inline styles here ...">
        browser upgrade message here
    </div>
<![endif]-->
6个回答

问题编辑后修改答案

这是实现这一目标的唯一 CSS 方法。

由于CSS@supports不适用于您的目标(不需要的)浏览器:Safari 7-8、IE <= 10、Android 浏览器 < 4.4、适用于 Android 的 UC 浏览器和 Opera Mini < 8,您的“浏览器升级”消息将在这些浏览器上可见使用这个规则。

@supports (display: flex) { .browserupgrade { display: none; }}

有一些浏览器仍然支持无前缀flex但不支持@supportsIE 11 (1)和 Opera Mini 8,但幸运的是我们可以通过一些 CSS 特定规则来解决它们。

/* IE 11 */
_:-ms-fullscreen, :root .browserupgrade { display: none; }

/* Opera Mini 8 */
:-o-prefocus, .browserupgrade { display: none; }

这是显示目标浏览器升级消息的完整代码。

CSS

.browserupgrade { display: block; }

/* IE 11 */
_:-ms-fullscreen, :root .browserupgrade { display: none; }

/* Opera Mini 8 */
:-o-prefocus, .browserupgrade { display: none; }

/* all modern browsers */
@supports (display: flex) { .browserupgrade { display: none; }}

HTML

<div class="browserupgrade">
    <p>You are using an outdated browser. Please <a href="http://browsehappy.com/">
       upgrade your browser</a> to improve your experience.</p>
</div>

(1): IE 11 CSS 规则也应该适用于 IE Mobile 11,但没有一个可以测试它。


CSS@supports也可用作 API CSS.supports()这是David Walsh写得非常好的文章


此外,如果您想自动重定向这些浏览器,这里有一个小脚本,可以在 10 秒的延迟后执行此操作。

var el = document.querySelector('.browserupgrade');
if (window.getComputedStyle(el,null).getPropertyValue("display") != 'none') {
  setTimeout(function(){
    window.location = 'http://browsehappy.com/';        
  }, 10000);
}
@Michael_B 谢谢,很高兴该解决方案具有如此大的value。
2021-03-17 17:33:34
这在满足我的所有要求方面确实做得很好。一个聪明的方法。干净、简单的代码。纯 CSS。优秀的!谢谢你。
2021-03-18 17:33:34

前提

JavaScriptstyle属性返回浏览器为指定元素支持的完整 CSS 属性集合,可以使用以下代码段进行测试:

无论是否为指定元素显式设置特定属性都是如此。例如,这可以通过在 Chrome 中运行以下代码段来测试;第一行将返回,false因为 Chrome 尚不支持 unprefixedappearance属性,而第二行将返回true

但是,应该注意的是,如果使用 JavaScript 在元素上设置了不受支持的属性,则通过该style属性检查属性是否存在将返回true

因此,我们将使用document.createElement()来创建一个临时元素,这样我们就可以确保我们正在检查的所有属性都没有以这种方式设置。(感谢Gothdo的这个建议,它消除了进行任何假设的需要。)


要求

查看要定位的浏览器列表:

  • Internet Explorer 10 支持带有-ms-前缀的flexbox
  • Safari 7 & 8 支持带有-webkit-前缀的flexbox
  • 根据caniuse.com 的说法Opera Mini从第 5 版开始就支持无前缀的 flexbox,但是我无法证明它的准确性,我正在寻找人来确认。
  • UC 浏览器当前 (v9.9) 支持带有-webkit-前缀的flexbox
  • 在 v4.4 之前,Android 浏览器支持带有-webkit-前缀的flexbox

解决方案

我们可以从该列表中看到,所有要定位的浏览器都需要为 flexbox 属性添加前缀,因此我们可以简单地通过检查临时元素style集合中是否存在任何未加前缀的属性来定位它们true在上述任何浏览器中运行时,将返回以下代码段:

有了这些知识,我们现在可以创建一个有效的解决方案来向必要的浏览器显示浏览器升级消息。

if(!("flex" in document.createElement("p").style))
    document.getElementById("browserupgrade").style.display="block";
#browserupgrade{
    display:none;
    font-family:sans-serif;
}
<div id="browserupgrade">
    <p>You are using an outdated browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
</div>


笔记

旧语法

当前 flexbox 规范的一个版本使用了稍微不同的语法,其中一个区别是order属性被命名为flex-order据我所知,唯一支持该语法的浏览器是 IE10,它需要前缀,因此应成为上述解决方案的目标。但是,为了完整起见,如果有任何浏览器支持该语法而没有前缀,您可以额外检查该flex-order属性是否存在,同时还检查该order属性是否不存在,以防万一有任何浏览器支持两种版本的语法。

火狐

Firefox 在版本 22 中添加了对不带前缀的 flexbox 属性的支持,但直到版本 28 才支持flex-flowflex-wrap属性,因此要将 v22-27 添加到我们的目标中,我们应该检查是否存在这些属性之一。

浏览器 11

尽管不需要前缀,IE11 对 flexbox 的支持仍然非常有问题,所以你可能也想考虑以它为目标。有没有办法这样做使用任何Flexbox的特性,然而IE 7-11(排序)所支持的image-rendering特性通过非标准-ms-interpolation-mode特性,与后面的边缘下降支持/ V12 +,所以我们可以改为检查那个。但是,不能保证此属性不会重新添加到 Edge 的未来版本中,因此应该对其进行监控。

歌剧迷你

尽管caniuse.com声称 Opera Mini 从第 5 版开始就完全支持 flexbox 并且被广泛认为是此类信息的权威来源,但如果您仍然希望以它为目标,您可以通过检查其中一个的存在来实现它不支持的无数属性。为了保持简洁,不过,我会建议更换-ms-interpolation-mode与检查检查transform-style不支持通过Opera Mini的也不是由IE的前边缘的版本。与之前的检查一样,应监控此检查,因为您可能不想针对的未来版本的 Opera Mini 可能会继续不支持该transform-style属性。


更新

2016 年 5 月 13 日:在问题更新后添加了额外的检查以定位更多浏览器。
2016 年 5 月 16 日:根据评论中提供的反馈,对提议的解决方案进行了更详细的解释,并使其值得提供的奖励。删除了对旧 flexbox 规范的检查,因为它们是多余的。
2016 年 5 月 17 日:document.body按照 Gothdo 的建议添加了一个临时元素来运行检查,而不是使用,这导致删除了建议使用 以getElementsByTagName()获得更广泛的浏览器支持。
23/05/16:添加了对 Internet Explorer 11 和 Opera Mini 进行建议检查的注释。

很好的答案,但我建议使用document.createElement("div")而不是document.body- 这将确保元素没有应用任何样式。
2021-03-25 17:33:34
很好的答案,我将自己与我自己的 CSS 一起使用,我 +1,我决定分享我得到的赏金,250 给你一个
2021-03-26 17:33:34
好想法,@Gothdo,谢谢。我会立即更新我的答案。createElement()document.body相比,您知道浏览器对什么的支持getElementsByTagName()吗?
2021-04-07 17:33:34
Caniuse 说它“在所有浏览器中得到有效支持(自 IE6+、Firefox 2+、Chrome 1+ 等)”。
2021-04-10 17:33:34
远不支持getElementsByTagName()但可以接受的牺牲,因为所有浏览器都希望以支持为目标createElement()
2021-04-11 17:33:34

您可以使用Modernizr.js进行特征检测

如果没有找到该功能,然后编写一些 JavaScript 将用户重定向到上面的 URL。

是的,我们有一个解决方案......

首先从(单击此处-)https://modernizr.com/ (用于flexbox 属性下载自定义构建 Modernizr,然后将最新的Jquery包含到您的页面中,添加一些样式表,您就完成了!

(注意:没有必要下载自定义构建 Modernizr,您可以直接从Modernizr CDN使用整个完整构建,但因为您只需要检查 Flexbox 属性;这就是我告诉您下载自定义构建的原因)

检查这个小提琴flexbox 支持小提琴

你的整个 html 页面(带有 css, jquery )将是这样的......

<!doctype html>
<html class="no-js" lang="en">
<head>
    <meta charset="utf-8">
    <title>BroswerCheck</title>
    <style type="text/css">
        #browserupgrade{
            display:none;
            text-align:center;
            background:#F1070B;
            color:#FFFFFF;
            font-family:Segoe, "Segoe UI", Verdana, sans-serif;
            font-size:15px;
            padding:10px;}

        #browserupgrade a{
            color:#FFFFFF;
            background:#000000;
            text-decoration:none;
            padding:5px 15px;
            border-radius:25px;}
    </style>
    <script src="modernizr.js"></script>
</head>

<body>
    <div id="browserupgrade">
        <p>You are using an outdated browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
    </div>

    <script src="jquery-2.1.1.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            if (!Modernizr.flexbox) { $("#browserupgrade").show(); }
        });
    </script>
</body>
</html>

你的步骤将是,

1. 下载自定义 Modernizr 来检测 flexbox 属性

2.创建一个html页面,在html标签中添加class="no-js"

3.创建一个显示消息的div并隐藏它

4. 将 jquery 和 Modernizr 添加到您的页面

5.当浏览器不支持flexbox-property时显示一个div

(为此目的使用 'Modernizr.flexbox' 属性,如上面的脚本所示)

或者,如果您不想使用 Jquery,请使用以下脚本(感谢@Shaggy)作为,

$(document).ready(function () { 
    if(!Modernizr.flexbox)document.getElementByID("browserupgrade").style.display="‌​block";
});
这里不需要 jQuery,尤其是当问题指定需要轻量级解决方案时。我建议改用普通的 JS;简单地说:if(!Modernizr.flexbox)document.getElementByID("browserupgrade").style.display="block"
2021-03-24 17:33:34
雅...它没有必要...但我已经使用 .show 类的 jquery 而不是使用默认的 javascript 属性...你对 jquery 的解决方案是好的..
2021-04-06 17:33:34

好的,我也建议使用modernizr(从https://modernizr.com/下载),但有点不同。我认为你真正关心的只是检测浏览器是否支持 flexbox,而不是它是否是特定的浏览器或浏览器版本。

安装并加载页面后,modernizr 会将类放入<body>标签中。关于 flexbox,它会将类.flexbox或类.no-flexbox放入 body 标记中,例如<body class="no-flexbox bgsizecover csscalc">(实际上还有更多类,除非您下载仅适用于 flexbox 的 Modernizr 自定义构建)。因此,您可以为 CSS 规则使用一个简单的组合选择器,该规则选择一个 DIV 块,您可以在其中写入关于过时浏览器的警告。例子:

在 HTML 中,编写如下内容:

<div class="browserwarning">Your browser is outdated and cannot display this page properly! Please install an up-to-date browser, which you can get from <a href="http://www.example.com">here</a>.</div>

在 CSS 样式表中,添加以下内容:

.browserwarning {
  display: none;
}
.no-flexbox .browserwarning {
  display: block;
  font-size: 24px;
  color: red;
  background-color: yellow;
}

这将首先隐藏此消息(通过第一条规则),然后(第二条规则)仅在无法处理 flexbox 的浏览器中显示它,因此在加载页面时通过Modernizr 将该.no-flexbox类放入body标记中:组合选择器.no-flexbox .browserwarning工作无论如何 浏览器警告放置在正文中哪个位置 - 它不必是 的直接子代body,但可以在其中的任何位置。

这肯定有效 - 我已经在我成功完成的页面中使用了它......