而不是使用前缀,我想问网站访问者升级他们的浏览器
我正在使用CSS flexbox重build网站。
在检查浏览器兼容性时 ,我发现所有现代浏览器都支持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。
这些访客将通过链接下载当前浏览器。 但是, 微软从IE10开始停止了对条件注释的支持 。
现在我需要类似的东西:
- IE 10
- Safari 7-8
- Opera Mini <8
- 适用于Android的UC浏览器
- Android浏览器<4.4
有一个简单的JS / jQuery脚本来处理这个工作? 还是另一种轻量级的方法
解
感谢所有的答案。 显然有很多方法可以解决这个问题(Modernizr,PHP,jQuery的function,简单的Javascript,CSS,browser-update.org等)。这些方法中的许多方法将完全有效地完成这项工作。
我去了最简单的一个:CSS(credit @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的相对较less的访问者,HTML中的条件注释:
<!--[if lte IE 7]> <div style=" ... inline styles here ..."> browser upgrade message here </div> <![endif]-->
问题编辑后修改答案
这是一个CSS实现的唯一方法。
由于CSS @supports
不适用于您的目标(不需要的)浏览器:Safari 7-8,IE <= 10,Android Browser <4.4,UC Browser for Android和Opera Mini <8,您的“browserupgrade”消息将可见对那些使用这个规则。
@supports (display: flex) { .browserupgrade { display: none; }}
有几个浏览器仍然支持非前缀的flex
但不支持@supports
,IE 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上工作,虽然没有人testing它。
CSS @supports
也可用作API, CSS.supports() 。 这是大卫·沃尔什写的一篇很好的文章 。
此外,如果有人想自动redirect这些浏览器,这是一个小的脚本,延迟10秒后,这样做。
var el = document.querySelector('.browserupgrade'); if (window.getComputedStyle(el,null).getPropertyValue("display") != 'none') { setTimeout(function(){ window.location = 'http://browsehappy.com/'; }, 10000); }
前提
JavaScript style
属性返回浏览器支持指定元素的CSS属性的完整集合,可以使用以下代码片段进行testing:
for(var x in document.body.style) console.log(x);
您可以使用modernizr.js进行特征检测 。
然后编写一些JavaScript来将用户redirect到上面的URL,如果没有find该function。
是的,我们有一个解决scheme…
首先从(点击这里 – ) https://modernizr.com/ (对于flexbox属性 )下载一个自定义的构buildModernizr,然后将最新的Jquery包括到您的页面中,添加一些样式表,然后完成!
(注意:不需要下载一个自定义的Modernizr版本,你可以直接从Modernizr CDN使用完整版本,但是只需要检查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标签中添加class =“no-js”的html页面
3.创build一个div来显示消息并隐藏它
4.将jquery和Modernizr添加到您的页面
5.显示一个div,当浏览器不支持flexbox属性
(为此目的使用'Modernizr.flexbox'属性如上面的脚本所示)
或者如果你不想使用JQuery,那么使用下面的脚本(感谢@Shaggy)
$(document).ready(function () { if(!Modernizr.flexbox)document.getElementByID("browserupgrade").style.display="block"; });
好吧,我也build议使用modernizr
(从https://modernizr.com/下载),但有一点不同。; 我认为这是事实,您的实际关注只是检测浏览器是否支持flexbox,而不是如果它是一个特定的浏览器或浏览器版本。
在您安装并加载页面之后,modernizr会将类放入<body>
标记中。 关于flexbox,它会将类.flexbox
或类.no-flexbox
放到body标签中,比如<body class="no-flexbox bgsizecover csscalc">
(实际上还有更多的类,除非你下载了一个modernizr定制的构build只适用于flexbox)。 所以你可以使用一个简单的CSSselect器来select一个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
标签:组合select器.no-flexbox .browserwarning
无论在哪里放置浏览器警告.no-flexbox .browserwarning
正常工作 – 它不一定是body
的直接子.no-flexbox .browserwarning
,但可以在任何地方。
这是肯定的 – 我已经在页面中使用过,我成功了…
编辑:
有两种可行的方法:Modernizr或Feature Queries。 Modernizr是当前稳定的解决scheme,但在所有浏览器完全支持的情况下,function查询@support
将成为用于css特征检测的最佳纯CSS解决scheme。
目前,您需要添加一些前缀来定位那些不支持function查询的浏览器,即。 看LGSon的回答。
Modernizr方法:
您可以创build一个Flexbox自定义Modernizr构build非常容易,如以前推荐: Modernizr自定义Flexbox构build 。 在您的网站中引用您的自定义的modernizr JavaScript文件,然后添加一些Html标记和Css类,如下所示:
注意:在不同的浏览器中打开代码段来检查支持。
testing:
没有flexbox支持:Internet Explorer 10
Flexbox支持:Chrome 50
/*! modernizr 3.3.1 (Custom Build) | MIT * * https://modernizr.com/download/?-flexbox-setclasses !*/ ! function(e, n, t) { function r(e, n) { return typeof e === n } function o() { var e, n, t, o, s, i, a; for (var l in C) if (C.hasOwnProperty(l)) { if (e = [], n = C[l], n.name && (e.push(n.name.toLowerCase()), n.options && n.options.aliases && n.options.aliases.length)) for (t = 0; t < n.options.aliases.length; t++) e.push(n.options.aliases[t].toLowerCase()); for (o = r(n.fn, "function") ? n.fn() : n.fn, s = 0; s < e.length; s++) i = e[s], a = i.split("."), 1 === a.length ? Modernizr[a[0]] = o : (!Modernizr[a[0]] || Modernizr[a[0]] instanceof Boolean || (Modernizr[a[0]] = new Boolean(Modernizr[a[0]])), Modernizr[a[0]][a[1]] = o), g.push((o ? "" : "no-") + a.join("-")) } } function s(e) { var n = x.className, t = Modernizr._config.classPrefix || ""; if (_ && (n = n.baseVal), Modernizr._config.enableJSClass) { var r = new RegExp("(^|\\s)" + t + "no-js(\\s|$)"); n = n.replace(r, "$1" + t + "js$2") } Modernizr._config.enableClasses && (n += " " + t + e.join(" " + t), _ ? x.className.baseVal = n : x.className = n) } function i(e, n) { return !!~("" + e).indexOf(n) } function a() { return "function" != typeof n.createElement ? n.createElement(arguments[0]) : _ ? n.createElementNS.call(n, "http://www.w3.org/2000/svg", arguments[0]) : n.createElement.apply(n, arguments) } function l(e) { return e.replace(/([az])-([az])/g, function(e, n, t) { return n + t.toUpperCase() }).replace(/^-/, "") } function f(e, n) { return function() { return e.apply(n, arguments) } } function u(e, n, t) { var o; for (var s in e) if (e[s] in n) return t === !1 ? e[s] : (o = n[e[s]], r(o, "function") ? f(o, t || n) : o); return !1 } function d(e) { return e.replace(/([AZ])/g, function(e, n) { return "-" + n.toLowerCase() }).replace(/^ms-/, "-ms-") } function p() { var e = n.body; return e || (e = a(_ ? "svg" : "body"), e.fake = !0), e } function c(e, t, r, o) { var s, i, l, f, u = "modernizr", d = a("div"), c = p(); if (parseInt(r, 10)) for (; r--;) l = a("div"), l.id = o ? o[r] : u + (r + 1), d.appendChild(l); return s = a("style"), s.type = "text/css", s.id = "s" + u, (c.fake ? c : d).appendChild(s), c.appendChild(d), s.styleSheet ? s.styleSheet.cssText = e : s.appendChild(n.createTextNode(e)), d.id = u, c.fake && (c.style.background = "", c.style.overflow = "hidden", f = x.style.overflow, x.style.overflow = "hidden", x.appendChild(c)), i = t(d, e), c.fake ? (c.parentNode.removeChild(c), x.style.overflow = f, x.offsetHeight) : d.parentNode.removeChild(d), !!i } function m(n, r) { var o = n.length; if ("CSS" in e && "supports" in e.CSS) { for (; o--;) if (e.CSS.supports(d(n[o]), r)) return !0; return !1 } if ("CSSSupportsRule" in e) { for (var s = []; o--;) s.push("(" + d(n[o]) + ":" + r + ")"); return s = s.join(" or "), c("@supports (" + s + ") { #modernizr { position: absolute; } }", function(e) { return "absolute" == getComputedStyle(e, null).position }) } return t } function h(e, n, o, s) { function f() { d && (delete z.style, delete z.modElem) } if (s = r(s, "undefined") ? !1 : s, !r(o, "undefined")) { var u = m(e, o); if (!r(u, "undefined")) return u } for (var d, p, c, h, v, y = ["modernizr", "tspan", "samp"]; !z.style && y.length;) d = !0, z.modElem = a(y.shift()), z.style = z.modElem.style; for (c = e.length, p = 0; c > p; p++) if (h = e[p], v = z.style[h], i(h, "-") && (h = l(h)), z.style[h] !== t) { if (s || r(o, "undefined")) return f(), "pfx" == n ? h : !0; try { z.style[h] = o } catch (g) {} if (z.style[h] != v) return f(), "pfx" == n ? h : !0 } return f(), !1 } function v(e, n, t, o, s) { var i = e.charAt(0).toUpperCase() + e.slice(1), a = (e + " " + b.join(i + " ") + i).split(" "); return r(n, "string") || r(n, "undefined") ? h(a, n, o, s) : (a = (e + " " + E.join(i + " ") + i).split(" "), u(a, n, t)) } function y(e, n, r) { return v(e, t, t, n, r) } var g = [], C = [], w = { _version: "3.3.1", _config: { classPrefix: "", enableClasses: !0, enableJSClass: !0, usePrefixes: !0 }, _q: [], on: function(e, n) { var t = this; setTimeout(function() { n(t[e]) }, 0) }, addTest: function(e, n, t) { C.push({ name: e, fn: n, options: t }) }, addAsyncTest: function(e) { C.push({ name: null, fn: e }) } }, Modernizr = function() {}; Modernizr.prototype = w, Modernizr = new Modernizr; var x = n.documentElement, _ = "svg" === x.nodeName.toLowerCase(), S = "Moz O ms Webkit", b = w._config.usePrefixes ? S.split(" ") : []; w._cssomPrefixes = b; var E = w._config.usePrefixes ? S.toLowerCase().split(" ") : []; w._domPrefixes = E; var P = { elem: a("modernizr") }; Modernizr._q.push(function() { delete P.elem }); var z = { style: P.elem.style }; Modernizr._q.unshift(function() { delete z.style }), w.testAllProps = v, w.testAllProps = y, Modernizr.addTest("flexbox", y("flexBasis", "1px", !0)), o(), s(g), delete w.addTest, delete w.addAsyncTest; for (var N = 0; N < Modernizr._q.length; N++) Modernizr._q[N](); e.Modernizr = Modernizr }(window, document);
.support-container { display: none; } .no-flexbox .support-container { display: block; position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background-color: #CE3426; padding: 100px; } .support-container__update-browser { color: #ffffff; font-size: 2em; } .support-container__can-i-use { font-size: 1.2em; font-style: italic; color: #dddddd; } .support-container__update-browser a, .support-container__can-i-use a { background-color: #ffffff; text-decoration: underline; padding: 0 3px; border-radius: 4px; border-bottom: 2px solid rgba(0, 0, 0, 0.3); }
<div class="support-container"> <div id="browserupgrade" class="support-container__update-browser"> <p>Dear user, you are using an outdated browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p> </div> <div class="support-container__can-i-use"> <p> For more browser support info click <a href="http://caniuse.com/#feat=flexbox">here</a> . </p> </div> </div>
在前端您可以使用modernizr库,并检测浏览器是否支持您正在使用的现代function。
另一件事是做直接从后端redirect到一个特殊的页面。 如果您使用PHP作为后端,您可以使用get_browser函数来检测用户代理,然后加载普通页面,或者如果浏览器是不受支持的浏览器之一,则打开一个页面,build议用户进行升级。
您也可以在样式表中插入前缀。 检查浏览器样式属性实际上是否支持已经存在的样式属性,或者稍后dynamic插入。 它主要用于animation,虽然可以修改,以在浏览器中testing任何css
样式属性。 如果props
已经存在于stylesheet
,供应商前缀被插入到stylesheet
。 如果后来dynamic插入道具,则也会插入供应商前缀或将其附加到这些道具上。
例如,为animation
添加前缀,背景backface-visibility
, border-radius
, box-shadow
, transform
, transform-style
, transition
; 还要在@keyframes
设置前缀
(function prefix() { // var el = $(selector).get(0), ieg, $("body").get(0), $("#animated").get(0) var prefixes = {"MozAnimation": "-moz-","webkitAnimation": "-webkit-" ,"msAnimation": "-ms-","oAnimation": "-o-"}; var props = ["animation", "backface-visibility", "border-radius" , "box-shadow", "transform", "transform-style", "transition"]; $.each(prefixes, function(key, val) { $("style") .attr({"data-prefix": val,"class": String(val).replace(/-/g, "")}); return !(key in el.style); }); $.each(props, function(index, value) { var cssPrefix = $("style").attr("data-prefix"); if (value in el.style === false) { $.fn.pfx = function(prop, pfxprop, q) { return $("style").html($("style").text() .replace(new RegExp(prop, "g"), q + $("style").attr("data-prefix") + pfxprop)) }; $("style").pfx("@keyframes", "keyframes", "@") .pfx(value, value, ""); }; }); }());
更彻底的方法。
您可以为每个感兴趣的浏览器获取用户代理string,并创build要排除的所有浏览器的数组。
- 用户代理string列表
使用navigator.userAgent
获取访问者的用户代理,并使用jQuery inArray()
检查它是否在您的不支持的浏览器数组中
对于使用浏览器匹配的访问者,可能会引发一个简单的javascript警报。
以下是获取浏览器相关信息的示例(示例源: w3schools.com )
var txt = ""; txt += "<p>User-agent header: " + navigator.userAgent + "</p>"; txt += "<p>Browser CodeName: " + navigator.appCodeName + "</p>"; txt += "<p>Browser Name: " + navigator.appName + "</p>"; txt += "<p>Browser Version: " + navigator.appVersion + "</p>"; txt += "<p>Cookies Enabled: " + navigator.cookieEnabled + "</p>"; txt += "<p>Browser Language: " + navigator.language + "</p>"; txt += "<p>Browser Online: " + navigator.onLine + "</p>"; txt += "<p>Platform: " + navigator.platform + "</p>"; document.getElementById("demo").innerHTML = txt;
<div id="demo"></div>
你可以使用UAParser.js 。 它可以给你的浏览器名称,版本,操作系统等,这里是一个例子 。
甚至还有一个jQuery插件 。
var parser = new UAParser(); var browser = parser.getBrowser(); // leave only the major version and minor in order to compare // eg 12.2.4 > 12.2 var secondDot = browser.version.indexOf(".", browser.version.indexOf(".") + 1); browser.version = parseFloat(browser.version.substr(0, secondDot)); // debugging $("#browserName").html(browser.name); $("#browserVersion").html(browser.version); if (["IE", "Safari", "Opera Mobi", "UCBrowser", "Android Browser"].indexOf(browser.name) != -1) { if (browser.name == "IE" && browser.version <= 10) { $("#browserupgrade").show(); } if (browser.name == "Safari" && browser.version <= 10) { $("#browserupgrade").show(); } if (browser.name == "UCBrowser") { $("#browserupgrade").show(); } if (browser.name == "Android Browser" && browser.version <= 4.4) { $("#browserupgrade").show(); } }
请参阅: https : //browser-update.org/
<script> var $buoop = {c:2}; function $buo_f(){ var e = document.createElement("script"); e.src = "update.min.js"; document.body.appendChild(e); }; try {document.addEventListener("DOMContentLoaded", $buo_f,false)} catch(e){window.attachEvent("onload", $buo_f)} </script>
还是另一种轻量级的方法
如果你通过nginx提供你的页面,那么有一个非常有用的指令ancient_browser
。
您需要设置您不希望支持的浏览器列表:
ancient_browser msie 9.0;
然后将其redirect到特殊的浏览器升级页面:
if ($ancient_browser) { rewrite ^ /install-chrome.html; }
这样你就不会污染已经存在的页面,也不需要为不需要的用户加载额外的CSS。
您可以使用以下function获取浏览器名称和版本:
function get_browser() { var ua = navigator.userAgent, tem, M = ua .match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if (/trident/i.test(M[1])) { tem = /\brv[ :]+(\d+)/g.exec(ua) || []; return 'IE ' + (tem[1] || ''); } if (M[1] === 'Chrome') { tem = ua.match(/\bOPR\/(\d+)/) if (tem != null) { return 'Opera ' + tem[1]; } } M = M[2] ? [ M[1], M[2] ] : [ navigator.appName, navigator.appVersion, '-?' ]; if ((tem = ua.match(/version\/(\d+)/i)) != null) { M.splice(1, 1, tem[1]); } return M[0]; } function get_browser_version() { var ua = navigator.userAgent, tem, M = ua .match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if (/trident/i.test(M[1])) { tem = /\brv[ :]+(\d+)/g.exec(ua) || []; return 'IE ' + (tem[1] || ''); } if (M[1] === 'Chrome') { tem = ua.match(/\bOPR\/(\d+)/) if (tem != null) { return 'Opera ' + tem[1]; } } M = M[2] ? [ M[1], M[2] ] : [ navigator.appName, navigator.appVersion, '-?' ]; if ((tem = ua.match(/version\/(\d+)/i)) != null) { M.splice(1, 1, tem[1]); } return M[1]; }
并且您可以使用以下代码来提醒用户更新浏览器。
jQuery(document).ready(function() { var browser = get_browser(); var browser_version = get_browser_version(); if (browser == "Chrome" && browser_version <= 30) { alert("Your browser is below the minimum required version. Please update your browser for this site to function properly"); } if (browser == "Firefox" && browser_version <= 25) { alert("Your browser is below the minimum required version. Please update your browser for this site to function properly"); } if (browser == "MSIE" && browser_version <= 8) { alert("Your browser is below the minimum required version. Please update your browser for this site to function properly"); } });
This one line will check for ie10 and return true if ie10 or false otherwise .
var ie10 = /MSIE 10/i.test(navigator.userAgent) && /MSIE 10/i.test(navigator.vendor);
Did my studies here : https://blogs.msdn.microsoft.com/ie/2011/04/15/the-ie10-user-agent-string/
use case
选项1
if(ie10){ //Do something }
更新:
Microsoft browsers use @cc_on which will allow you to initiate conditional comments through script .
Option 2 :
<script> /*@cc_on @if (@_jscript_version == 10){ document.write("You are using IE10"); } @*/ </script>
FYI . Only EI 10 and below do not support flexbox css . Proof here : http://caniuse.com/#feat=flexbox
希望这可以帮助
尝试这个:
navigator.browser = (function() { var ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if (/trident/i.test(M[1])) { tem = /\brv[ :]+(\d+)/g.exec(ua) || []; return 'IE '+(tem[1] || ''); } if (M[1]=== 'Chrome') { tem = ua.match(/\b(OPR|Edge)\/(\d+)/); if (tem != null) return tem.slice(1).join(' ').replace('OPR', 'Opera'); } M = M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?']; if ((tem = ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]); return M.join(' '); })();
But you are trying to reinvent the wheel, with Modernizr you can do:
if (Modernizr.flexbox) { // Modern Flexbox supported } else { // Flexbox syntax not supported }