如何使用HTML检测浏览器是否支持该功能

185 阅读6分钟

目录

  1. 检测Javascript中的功能支持
  2. 使用@supports检测CSS支持情况
  3. 使用Modernizr来检测功能支持

有时你想支持大量的浏览器,同时还能使用较新的浏览器提供的功能。其他时候,不同的浏览器可能会提供不同的方式来做同一件事。在这两种情况下,你需要检测哪些功能被某些浏览器所支持,并进行相应的调整。通过检查一个功能是否被支持,并为每种情况执行不同的代码块,你可以使你的网站更具适应性,并接触到更多的浏览器(和使用浏览器的人)。

在Javascript中检测功能支持

要检测一个功能的可用性,你可以简单地打出浏览器提供功能的变量。如果该功能不可用,该变量将变成未定义。

这里有一个示范。如果你输入navigator.geolocation ,它将在不支持地理位置的浏览器上给出未定义的值,并在其他浏览器上提供一个对象来使用地理位置API。为了处理这两种情况,你的代码可能看起来像

if (navigator.geolocation) {
  // supports geolocation 
}
else {
  // doesn’t support geolocation
}

建议使用in 关键字来检查可用性,因为它也适用于严格模式。因此,上面的if-clause将改为

if(‘geolocation’ in navigator)

而最终的代码将是 :

if ('geolocation' in navigator) {
  // geolocation is supported, so use it
}
else {
  // Geolocation not supported, do something else
}

这样做是因为任何变量名在我们继续定义它之前都是默认未定义的。不仅仅是程序员在定义变量,浏览器也会事先定义一些变量,并通过这些变量提供它们的功能。比如说,随便想一个功能名称--我想到了'timeMachine'。如果你在javascript控制台中输入timeMachine ,它将返回undefined 。然而,一些来自未来的浏览器可能决定实现一个时间机器的功能,并通过变量timeMachine 。在那个浏览器中,变量timeMachine 将不再是undefined ,因为它已经决定要定义它。同样,能够提供地理位置功能的浏览器决定通过navigator.geolocation 来提供这个选项,而在旧的浏览器中,这个选项仍然是undefined

检查HTML元素的属性

特性在某些情况下适用于HTML元素。这发生在flexbox的情况下,它将只适用于HTML元素,或canvas,它也依赖于<canvas> 元素。要检测这种情况下的特性支持,你首先需要在代码中创建并访问html元素。要创建元素,请使用document.createElement 。下面是创建一个div的方法,并检查它是否支持justify-content属性。注意Javascript是如何切换到驼峰大小写的,justify-content 变成justifyContent

let div = document.createElement(‘div’)
if (div.style.justifyContent) {  // justify-content becomes justifyContent in javascript
}
else{
  // feature is not supported. Do something else
}

检查canvas的情况只是略有不同。对于支持canvas的浏览器,canvas元素会有一些特殊的方法,比如getContext 。在其他浏览器中,它将表现得像一个默认元素(是的,你可以创建自己的html标签),并且不会有getContext属性的设置。因为默认元素没有方法getContext ,所以只需检查是否存在该方法,就可以检查canvas是否只是这个浏览器的另一个默认元素,还是更多的东西:

let canvas = document.createElement(‘canvas’);
if (canvas.getContext) {
  // canvas is not just another random tag
  // because random tags don't have a getContext property
}
else{
}

使用@supports检测CSS支持

你也可以直接在CSS语法中使用@supports来检查CSS支持。这项技术所能做到的一切,在上面列出的Javascript技术中也能做到,但使用@supports可以帮助你将样式问题保留在CSS文件中,并帮助你写出更干净、结构化的代码。

@supports需要一个特征声明,在括号中,你可以添加你想应用的样式,如果该特征被支持的话。下面是一个例子,检测对display:flex 的支持,并在支持的情况下为.flexBox 元素添加一些样式。

@supports (display: flex) {
  .flexBox{
    display : flex;
    flex-direction : column;
  }
}

同样地,对于不支持flex的情况,你可以写成

@supports not (display: flex) {
  .flexBox {
    /** Fallback when flexbox not supported */
  }
}

如果你希望所有的规则都被支持,你也可以用and 来组合不同的样式,如果你希望至少支持一个规则,也可以用or 。这里是检查是否支持flex和backdrop-filter的语法。

@supports (backdrop-filter: blur) and (display: flex) {
}

这里是检查是否支持这两者中的至少一个的语法:

@supports (backdrop-filter: blur) or (display: flex) {
}

使用Modernizr来检测功能支持

你可以使用Modernizr库来检测功能支持,而不是针对不同的情况手动使用上述不同的方法,你也可以使用一个单一的方法来检测功能支持。

要做到这一点,首先从modernizr.com/下载Modernizr。在撰写本文时,该网站要求你挑选你想检测的功能,然后为你生成一个自定义JS文件。在挑选出你的功能后,下载这个自定义JS文件。

现在,通过一个脚本标签将.js文件添加到你的HTML中。请确保在其他使用Modernizr的脚本标签之前添加它。现在,编辑你的HTML,给根HTML元素添加一个no-js的类,像这样:

<!doctype html>
<html class='no-js'>
  <head>
    <!-- more stuff in here -->
    <script src='modernizr-custom.js'></script>
  </head>
  <body>
  </body>
</html>

现在,如果你在浏览器中检查你的html元素,你会看到Modernizr已经在html元素中插入了一些其他的类。

现在你可以直接以这些类为目标,在某一特征可用的情况下应用样式。例如,如果Flexbox不可用,html元素将有一个no-flexbox类,如果它支持现代flexbox,它将有一个flexbox类。在你的CSS代码中,你可以用以下方式处理没有flexbox的情况。

.flexbox .myBox{
  display : flex;
}
.no-flexbox .myBox{
  display : grid ;                   /* use grid on .myBox when flexbox isn’t available
}

你也可以通过连锁多个类来获得与@supports相同的效果and

.no-flexbox.grid div{
 // change the div styles when grid is available but flexbox is not
}

在javascript中使用Modernizr

在javascript中,Modernizr提供了一个Modernizr对象,其中包含作为键的特征,以及作为值的true/false,表示该特征是否被支持。例如,要使用Javascript检查是否支持flexbox,你可以只检查Modernizr.flexbox的值。你的代码可能看起来如下

if (Modernizr.flexbox) {
  // do something if flexbox is supported 	
}

通过OpenGenus的这篇文章,你一定对如何使用HTML检测浏览器是否支持该功能有了完整的认识。