如何进行CSS滤镜的特性检测?

17

在一些浏览器中,包括Chrome稳定版,你可以这样做:

h3 {
  -webkit-filter: grayscale(1);
  filter: grayscale(1);
}

你可能不知道,h1标签将以完全灰度的形式呈现。 历史往事总会重新上演.

无论如何 - 有人知道任何一种检测此功能的方法吗?

如果filter不起作用,我需要能够应用其他样式。


你是指 filter 内部的不同样式,还是 filter 本身? - Sepehr
@3p3r 太好了,某些浏览器只支持其中的一些吗?当然了。那么,无论需要测试什么,我想都得去做。 - Alan H.
我认为这是事实,因为我的浏览器(Chrome 19)支持“filter”,但不支持“grayscale”。 - Sepehr
3个回答

19
所谓的更新答案:
由于提问者提出了一个好问题,我正在更新答案,但这与我的先前回答没有任何关系或矛盾之处,这只是一个浏览器检测。
Alan H. 提到 IE,在其 10 版本之前,支持 filter CSS 属性,但不是我们所有人都知道的方式(我指的是 CSS3 filter)。
因此,如果我们只想要检测 CSS3 filter,我们应该使用一些 浏览器检测。如我在我的评论中所提到的。
使用 documentMode 属性,并将其与我们简单的特性检测结合起来,我们可以排除 IE 中所谓的假阳性。
function css3FilterFeatureDetect(enableWebkit) {
    //As I mentioned in my comments, the only render engine which truly supports
    //CSS3 filter is webkit. so here we fill webkit detection arg with its default
    if(enableWebkit === undefined) {
        enableWebkit = false;
    }
    //creating an element dynamically
    el = document.createElement('div');
    //adding filter-blur property to it
    el.style.cssText = (enableWebkit?'-webkit-':'') + 'filter: blur(2px)';
    //checking whether the style is computed or ignored
    //And this is not because I don't understand the !! operator
    //This is because !! is so obscure for learning purposes! :D
    test1 = (el.style.length != 0);
    //checking for false positives of IE
    //I prefer Modernizr's smart method of browser detection
    test2 = (
        document.documentMode === undefined //non-IE browsers, including ancient IEs
        || document.documentMode > 9 //IE compatibility moe
    );
    //combining test results
    return test1 && test2;
}

现代化检测源代码


if(document.body.style.webkitFilter !== undefined)

或者

if(document.body.style.filter !== undefined)

额外信息:

如果只需要简单的功能检测,请使用上面的代码。要查看支持的功能列表,请参见此处:

想在Chrome中实时演示filter,请查看此处:

还有两个资源供您参考:

当我写这篇答案时,您必须使用webkit供应商前缀才能使其正常工作。


1
太棒了!但我注意到在Chrome浏览器中,虽然定义了".filter",但它没有任何效果(与".webkitFilter"不同,后者被定义并且起作用)。你认为这是为什么? - Alan H.
1
我想我的担心是,.filter被定义但无法使用似乎非常奇怪和不可靠 - 这有点违背了特性测试的意义,如果它是错误的。 - Alan H.
@AlanH. - IE实现了一个非标准的filter CSS属性,用于不同的目的,而新标准则替换了它。也许Chrome一直支持filter是为了与IE兼容,这就解释了为什么它被定义了,但请放心,一旦标准化,它将被替换为与webkitFilter相同的东西。不幸的是,这确实使功能检测变得复杂 - 你如何以未来为导向的方式检测filter的存在,以免对IE产生误报? - AshleysBrain
@AshleysBrain 不确定我在这里的评论是否有帮助,但是如果你知道特定版本的IE(比如IE8)支持filter,但是以非标准的方式,那么为什么要寻找功能检测呢?还不如使用浏览器检测! - Sepehr
@3p3r 谢谢,不过这段代码在三元运算符所在的那行中有一个连接错误: (enableWebkit)?'-webkit-':'' + 'filter: blur(2px)'; 应该是: (enableWebkit ?'-webkit-':'') + 'filter: blur(2px)'; 另外,如果学习目的是一个问题的话,最好在el、test1和test2前加上var。 - sq2
显示剩余5条评论

2
为了借鉴@Sepehr的答案,但是稍微现代化一些并删除多余的行:

建议以下操作:

var supportsFilters = (function() {
  var filterEl = document.createElement('div');
  filterEl.style.cssText = 'filter:blur(2px)';
  return filterEl.style.length != 0 && (document.documentMode === undefined || document.documentMode > 9);
})();

2
你现在可以使用CSS内置的@support来有条件地应用样式。请注意,@support的浏览器支持是很好但不完美的。以下是一篇不错的文章,其中解释了如何使用几个示例:https://iamsteve.me/blog/entry/feature-detection-with-css 例如,你可以像这样做(查看实际效果):
@supports (filter: grayscale(1)) or (-webkit-filter: grayscale(1)) {
  h3 {
    -webkit-filter: grayscale(1);
    filter: grayscale(1);
  }
}

@supports not (filter: grayscale(1)) and not not (-webkit-filter: grayscale(1)) {
  h3 {
    color: #808080;
  }
}

2
此外,还有一个 JS 选项可供选择:Mozilla 文档 - Shikkediel
时代已经改变,这可能是现在最好的答案,所以我将我的接受答案更改为这个。话虽如此,我想支持@support但不支持CSS filter的浏览器数量一定很少...可能只有Opera Mini和一些嵌入式浏览器。 - Alan H.
关于浏览器支持,每个当前的浏览器(即不包括像MSIE这样已死的)都支持@support - Alan H.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接