【问题标题】:How would I detect CSS Transition support on :before pseudo-elements with javascript?如何在 :before 使用 javascript 的伪元素上检测 CSS 转换支持?
【发布时间】:2012-10-07 00:29:25
【问题描述】:

我正在尝试将CSS Transitions:before 选择器一起使用,目前唯一支持此功能的浏览器是Firefox。我可以毫无问题地创建jQuery fallback,但我不确定如何使用这样的伪元素进行特征检测。

Here's a JSBin which shows the HTML and CSS that I'm working with.

(... and here's a similar SO question, but about using regular elements.)

更新:哇,连IE10的平台预览版都支持这个了,那个webkit是怎么回事?!

编辑:解决方案移至下面的答案)

【问题讨论】:

  • 我也很想知道这是否可行,可惜只有 Firefox 支持它。
  • 其实看起来是pretty well supported。不过,可怕的互联网爆炸者名副其实。哎呀,链接错误,已修复。
  • @Asad 请参阅 caniuse.com/#feat=css-transitions 已知问题 #2:目前不支持除 Firefox 之外的任何浏览器的 ::before 和 ::after 伪元素
  • 你应该回答并接受它,非常有帮助,谢谢:)

标签: javascript css-transitions pseudo-element browser-feature-detection


【解决方案1】:

我知道建议指出您应该使用后备而不是 polyfill,但只是在你我之间,使用无条件 polyfill 对于像 CSS3 这样的前沿技术来说并不是那么糟糕。

如果你必须知道功能状态,你可以使用Modernizr但如果你正在使用一个库,你最好使用Selectivizr并获得完整的CSS跨浏览器支持。

啊哈! Here 是来自 github 上 Modernizr 的一个非常好的小提琴。基本上,它检查伪元素的计算样式值是否在比过渡持续时间短的时间跨度内从其原始值更改。当然,问题在于使用 setTimeouts 的不可靠性(同步问题),以及您需要推迟一切直到 setTimeout 测试完成的事实。检查你的控制台,看看浏览器是否有伪元素转换。

【讨论】:

  • Asad,Modernizr 目前可以检测伪元素和 CSS 过渡,但它目前无法检测伪元素是否支持 CSS 过渡(请参阅上面我对您的评论中的链接)。
【解决方案2】:

公平地说,即将推出的 IE10 确实支持生成内容的过渡(我在 Windows 8 Enterprise 试用版中测试过)。

实际上,我确信没有必要检测这种类型的东西。过渡只是轻微的改进,而不是关键功能。因此,在更高级的浏览器中使用过渡效果,而在不太高级的浏览器中不使用过渡效果是完全可以的。

但是如果你需要检测它,考虑到这不能直接可靠地检测到,你可以通过测试标准全局 JS 对象的存在来使用浏览器引擎检测。例如,因为我们知道 IE10 支持转换生成的内容,所以我们可以在 filter IE9 and older IEsdocument.all && !window.atob 条件下完全适应未来。 Opera 可以通过测试window.opera 的存在来检测,所以当Opera 修复这个问题时,我们可以使用window.opera && !someGlobalObjectAddedInFixedOpera 条件来检测旧版本。 WebKit 可能会以类似的方式被检测到。

【讨论】:

  • 我上面的解决方案有效吗?我正在测试-ms- 前缀,所以它也应该检查它。如果是这样,这应该是 true jsbin.com/eliwum/2 另外:特征检测是测试此类错误的唯一可靠方法。与我合作的设计师特别要求这种类型的动画,所以这并不是微不足道的。
  • 其实我只是在我安装的IE10 Platform Preview中测试过,上面的代码检测到它的支持就好了。
【解决方案3】:

感谢@Asad 挖掘了一些handy code,我能够想出nice solution 这是jQuery 版本:

$(function() {
  var isTransitionSupported = (function (pseudo, transProp, transPropStart, transPropEnd) {
    var id = pseudo + transProp + '-' + (new Date()).valueOf(),
        prefixes = ['o', 'ms', 'moz', 'webkit'],
        prop = "transition: " + transProp + " 99s linear;",
        allprops = (function () {
          var props = "";
          for (var l = prefixes.length; l--;) {
            props += "-" + prefixes[l] + "-" + prop;
          }
          return props + prop;
        }()),
        $css = $("<style>" +
                 "#" + id + "{position:absolute;left:-999em;}" + 
                 "#" + id + ":" + pseudo + "{display:block;content:'M';" + transProp + ":" + transPropStart + ";}" + 
                 "#" + id + ".t:" + pseudo + "{" + allprops + transProp + ":" + transPropEnd + ";}" + 
                 "</style>"),
        $bct = $('<div id="' + id + '" />');

      $css.appendTo("head");
      $bct.appendTo("body");

      try {
        // get style value before any changes
        window.getComputedStyle($bct[0], ':' + pseudo).getPropertyValue(transProp);

        $bct.addClass("t");

        // test style after changes
        return (window.getComputedStyle($bct[0], ':' + pseudo).getPropertyValue(transProp) !== transPropEnd);
      } catch (e) {}
      return false;
    }("before", "width", "0px", "1000px"));
});

Here's a version that doesn't use jQuery:

var isTransitionSupported = (function (pseudo, transProp, transPropStart, transPropEnd) {
    var ticks = (new Date()).valueOf(),
        id = pseudo + transProp + '-' + ticks,
        prefixes = ['o', 'ms', 'moz', 'webkit'],
        prop = "transition: " + transProp + " 99s linear;",
        allprops = (function () {
            var props = "";
            for (var l = prefixes.length; l--;) {
                props += "-" + prefixes[l] + "-" + prop;
            }
            return props + prop;
        }()),
        body = document.body || document.createElement('body'),
        node = document.createElement('div'),
        css = "<style>" +
                    "#" + id + "{position:absolute;left:-999em;}" + 
                    "#" + id + ":" + pseudo + "{display:block;content:'M';" + transProp + ":" + transPropStart + ";}" + 
                    "#" + id + ".t" + ticks + ":" + pseudo + "{" + allprops + transProp + ":" + transPropEnd + ";}" + 
                    "</style>",
        bct = document.createElement('div'),
        isSupported = false;

    bct.id = id;
    node.innerHTML += css;
    node.appendChild(bct);
    body.appendChild(node);

    try {
        // get style value before any changes
        window.getComputedStyle(bct, ':' + pseudo).getPropertyValue(transProp);

        bct.className += "t" + ticks;

        // test style after changes
        isSupported = (window.getComputedStyle(bct, ':' + pseudo).getPropertyValue(transProp) !== transPropEnd);
    } catch (e) {}

    node.parentNode.removeChild(node);

    return isSupported;
}("before", "width", "0px", "1000px"));

document.documentElement.className += ' ' + (isTransitionSupported ? '' : 'no-') + "pseudo-trans";

这里是all that code in a gist on github,如果有人想分叉和改进它。

【讨论】:

    猜你喜欢
    • 2012-01-27
    • 2017-01-22
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 2014-11-06
    • 2011-10-21
    • 2013-10-26
    • 2015-01-04
    相关资源
    最近更新 更多