【问题标题】:Detect support for transition with JavaScript使用 JavaScript 检测对转换的支持
【发布时间】:2012-06-08 22:24:44
【问题描述】:

我想根据浏览器是否支持 CSS3 转换来提供不同的 javascript 文件。有没有比我下面的代码更好的方法来检测转换支持?

window.onload = function () {
    var b = document.body.style;
    if(b.MozTransition=='' || b.WebkitTransition=='' || b.OTransition=='' || b.transition=='') {
        alert('supported');
    } else {
        alert('NOT supported')
    }
}

【问题讨论】:

标签: javascript css css-transitions


【解决方案1】:

我也认为包含 Modernizr 是一种矫枉过正。下面的功能应该适用于任何功能。

function detectCSSFeature(featurename){
    var feature = false,
    domPrefixes = 'Webkit Moz ms O'.split(' '),
    elm = document.createElement('div'),
    featurenameCapital = null;

    featurename = featurename.toLowerCase();

    if( elm.style[featurename] !== undefined ) { feature = true; } 

    if( feature === false ) {
        featurenameCapital = featurename.charAt(0).toUpperCase() + featurename.substr(1);
        for( var i = 0; i < domPrefixes.length; i++ ) {
            if( elm.style[domPrefixes[i] + featurenameCapital ] !== undefined ) {
              feature = true;
              break;
            }
        }
    }
    return feature; 
}

var hasCssTransitionSupport = detectCSSFeature("transition");

灵感来自https://developer.mozilla.org/en-US/docs/CSS/Tutorials/Using_CSS_animations/Detecting_CSS_animation_support

【讨论】:

  • 因为 IE 将 elm.style[featurename] 报告为空字符串。我在第一次检查时添加了!== undefined; if(elm.style[featurename] !== undefined) { feature = true; } 现在它可以工作了。
【解决方案2】:

Modernizr 会为您检测到这一点。使用 this link 创建仅包含 CSS3 2D 和/或 3D 过渡的自定义下载版本。

运行后,您可以在 html 标签 (CSS) 上测试 csstransitions 类,或者在 JavaScript 中测试 Modernizr.csstransitions 是否为 true

更多文档:http://modernizr.com/docs/#csstransitions

【讨论】:

  • 谢谢。但我不想为此包含一个库:)
  • Modernizr 构建器允许您仅选择您想要检测的功能,从而为您提供尽可能少的代码。它经过反复测试和改进,因此确实是做这类事情的最佳方式。
  • 使用 Modernizr 构建工具可为您提供尽可能小的 Modernizr 代码,而不是整个库。 (您特别要求“更好的方法”,而不是尽可能小的代码。Modernizr 是我所知道的最好的方法。)
  • 它实际上一点也不小,测试这么简单的东西的输出代码比需要的大 50 倍。除非我需要的不仅仅是其中一项测试,否则我永远不会使用modernizer,即使那样我也会复制测试并清理代码
【解决方案3】:

这是另一个测试代码。也许这是一种矫枉过正,但该函数尝试将 CSS 属性设置为 DOM 对象,然后从中读取。

从未在大量外来浏览器上测试过此代码,但它比仅检查 CSS 属性可用性更安全。啊,是的,它可以区分 2D 变换支持和 3D 变换支持!只需传递您要测试的 CSS 属性值!

此代码的优点是它检测支持的供应商前缀(如果有)。可能的返回值:

false,当功能不受支持时,或

{
    vendor: 'moz',
    cssStyle: '-moz-transition',
    jsStyle: 'MozTransition'
}

当功能支持时

/**
 * Test for CSS3 feature support. Single-word properties only by now.
 * This function is not generic, but it works well for transition and transform at least
 */
testCSSSupport: function (feature, cssTestValue/* optional for transition and transform */) {
    var testDiv,
        featureCapital = feature.charAt(0).toUpperCase() + feature.substr(1),
        vendors = ['', 'webkit', 'moz', 'ms', 'o'],
        jsPrefixes = ['', 'Webkit', 'Moz', 'ms', 'O'],
        defaultTestValues = {
            transition: 'left 2s ease 1s',
            transform: 'rotateX(-180deg) translateZ(.5em) scale(0.5)'
           // This will test for 3D transform support
           // Use other values if you need to test for 2D support only
        },
        testFunctions = {
            transition: function (jsProperty, computed) {
                return computed[jsProperty + 'Delay'] === '1s' && computed[jsProperty + 'Duration'] === '2s' && computed[jsProperty + 'Property'] === 'left';
            },
            transform: function (jsProperty, computed) {
                return computed[jsProperty].substr(0, 9) === 'matrix3d(';
            }
        };

    /* test given vendor prefix */
    function isStyleSupported(feature, jsPrefixedProperty) {
        if (jsPrefixedProperty in testDiv.style) {
            var testVal = cssTestValue || defaultTestValues[feature],
                testFn = testFunctions[feature];
            if (!testVal) {
                return false;
            }       

            testDiv.style[jsPrefixedProperty] = testVal;
            var computed = window.getComputedStyle(testDiv);

            if (testFn) {
                return testFn(jsPrefixedProperty, computed);
            }
            else {
                return computed[jsPrefixedProperty] === testVal;
            }
        }
        return false;
    }

    //Assume browser without getComputedStyle is either IE8 or something even more poor
    if (!window.getComputedStyle) {
        return false;
    }

    //Create a div for tests and remove it afterwards
    if (!testDiv) {
        testDiv = document.createElement('div');
        document.body.appendChild(testDiv);
        setTimeout(function () {
            document.body.removeChild(testDiv);
            testDiv = null;
        }, 0);
    }

    var cssPrefixedProperty,
        jsPrefixedProperty;

    for (var i = 0; i < vendors.length; i++) {
        if (i === 0) {
            cssPrefixedProperty = feature;  //todo: this code now works for single-word features only!
            jsPrefixedProperty = feature;   //therefore box-sizing -> boxSizing won't work here
        }
        else {
            cssPrefixedProperty = '-' + vendors[i] + '-' + feature;
            jsPrefixedProperty = jsPrefixes[i] + featureCapital;
        }

        if (isStyleSupported(feature, jsPrefixedProperty)) {
            return {
                vendor: vendors[i],
                cssStyle: cssPrefixedProperty,
                jsStyle: jsPrefixedProperty
            };
        }
    }

    return false;
}

Github:https://github.com/easy-one/CSS3test

【讨论】:

    【解决方案4】:
    if (window.TransitionEvent){
    
    }
    

    【讨论】:

      【解决方案5】:

      使用 Modernizr 3.0 (alpha),您可以在本地生成自定义构建。这可能会解决上述“过度杀伤”问题 - 尽管我首先并不完全清楚这个问题(但我假设它的大小)。新的 api 提供了一个“构建”方法,您可以将包含您希望包含在构建中的测试的 json 传递给该方法。

      我在我的 gulp 文件中使用了类似的东西,但不需要 gulp - 一个简单的节点脚本就可以了。

      gulp.task('js:modernizr', function() {
          var modConfig = JSON.parse(fs.readFileSync('modernizr-config.json', {
                  encoding: 'utf8'
              }));
          modernizr.build(modConfig, function(res) {
              fs.writeFileSync('modernizr.js', res);
              return true;
          });
      }); 
      

      “modernizr-config.json”文件的示例是

      {
        "classPrefix": "",
        "options": [
          "addTest",
          "atRule",
          "domPrefixes",
          "hasEvent",
          "html5shiv",
          "html5printshiv",
          "load",
          "mq",
          "prefixed",
          "prefixes",
          "prefixedCSS",
          "setClasses",
          "testAllProps",
          "testProp",
          "testStyles"
        ],
        "feature-detects": [
          "css/transforms",
          "css/transforms3d",
          "css/transformstylepreserve3d",
          "css/transitions",
          "touchevents",
          "workers/webworkers",
          "history"
        ]
      }
      

      完整的配置文件包含在 Modernizr 包中。

      通过这种方法,您可以通过包安装程序利用维护良好的 Modernizr 测试套件,并根据需要轻松添加/删除测试。更少的测试,更小的文件显然。

      “setClasses”选项会将相关的测试类添加到您的 html 中,但您也可以像这样利用 3.0 异步事件:

      Modernizr.on('csstransitions', function(bool) {
          if (bool === true) // do transition stuffs
      }
      

      【讨论】:

        猜你喜欢
        • 2011-10-21
        • 2013-09-29
        • 1970-01-01
        • 2016-02-11
        • 1970-01-01
        • 2012-10-07
        • 2015-04-30
        • 1970-01-01
        • 2019-09-07
        相关资源
        最近更新 更多