Javascript 检测HTML5的最佳方法<;帆布>;不支持

Javascript 检测HTML5的最佳方法<;帆布>;不支持,javascript,html,canvas,progressive-enhancement,graceful-degradation,Javascript,Html,Canvas,Progressive Enhancement,Graceful Degradation,处理浏览器不支持HTML5标签的情况的标准方法是嵌入一些回退内容,如: <canvas>Your browser doesn't support "canvas".</canvas> 您的浏览器不支持“画布”。 但页面的其余部分保持不变,这可能是不恰当的或误导性的。我想要一些检测画布不支持的方法,这样我就可以相应地显示页面的其余部分。您有什么建议?在创建画布对象时,我通常会检查getContext (function () { var canvas = doc

处理浏览器不支持HTML5标签的情况的标准方法是嵌入一些回退内容,如:

<canvas>Your browser doesn't support "canvas".</canvas>
您的浏览器不支持“画布”。

但页面的其余部分保持不变,这可能是不恰当的或误导性的。我想要一些检测画布不支持的方法,这样我就可以相应地显示页面的其余部分。您有什么建议?

在创建画布对象时,我通常会检查
getContext

(function () {
    var canvas = document.createElement('canvas'), context;
    if (!canvas.getContext) {
        // not supported
        return;
    }

    canvas.width = 800;
    canvas.height = 600;
    context = canvas.getContext('2d');
    document.body.appendChild(canvas);
}());

如果支持,则可以继续画布设置并将其添加到DOM中。这是一个简单的示例,我(个人)更喜欢它而不是优雅的降级。

在浏览器中检测画布支持有两种流行的方法:

  • 检查是否存在
    getContext
    ,Modernizer库也以类似方式使用:

    var canvasSupported = !!document.createElement("canvas").getContext;
    
  • 检查是否存在由和规范定义的
    HTMLCanvasElement
    接口。 这一方法也在本报告中得到了建议

  • 我的建议是后者的一个变体(见补充说明),原因如下:

    • 每个已知的支持画布的浏览器——包括IE9——都实现了这个接口
    • 代码所做的事情更简洁、更直观
    • getContext
      方法是,因为它涉及到创建HTML元素。 当您需要尽可能压缩性能时(例如,在像Modernizer这样的库中),这并不理想
    使用第一种方法没有明显的好处。 这两种方法都可能被欺骗,但这不太可能是偶然发生的

    附加说明 可能仍然需要检查是否可以检索2D上下文。 据报道,一些移动浏览器可以为上述两种检查返回true,但为
    .getContext('2d')
    返回
    null
    。 这就是为什么Modernizer还会检查
    .getContext('2d')
    的结果。  然而,WebIDL和HTML再次为我们提供了另一个更好的选择:

    请注意,我们可以完全跳过对canvas元素的检查,直接转到检查2D渲染支持。该接口也是HTML规范的一部分

    您必须使用
    getContext
    方法来检测WebGL支持,因为即使浏览器可能支持
    WebGLRenderingContext
    getContext()
    如果浏览器因驱动程序问题而无法与GPU交互,并且没有软件实现,也可能返回null。在这种情况下,首先检查接口允许您跳过检查
    getContext

    var cvsEl, ctx;
    if (!window.WebGLRenderingContext)
        window.location = "http://get.webgl.org";
    else {
        cvsEl = document.createElement("canvas");
        ctx = cvsEl.getContext("webgl") || cvsEl.getContext("experimental-webgl");
    
        if (!ctx) {
            // Browser supports WebGL, but cannot create the context
        }
    }
    
    ##性能比较 在Firefox 11和Opera 11中,
    getContext
    方法的性能要慢85-90%,在Chromium 18中慢55%

        

    为什么不试试?它是一个提供检测功能的JS库

    引述:

    你曾经想做什么 在CSS中为 提供酷炫的功能,如 边界半径?嗯,有了现代化 你可以做到这一点


    这里可能有一个问题-一些客户端不支持所有画布方法

    var hascanvas= (function(){
        var dc= document.createElement('canvas');
        if(!dc.getContext) return 0;
        var c= dc.getContext('2d');
        return typeof c.fillText== 'function'? 2: 1;
    })();
    
    alert(hascanvas)
    

    这是Modernizer中使用的技术,基本上是其他所有进行画布工作的库中使用的技术:

    function isCanvasSupported(){
      var elem = document.createElement('canvas');
      return !!(elem.getContext && elem.getContext('2d'));
    }
    
    由于您的问题是在不受支持时进行检测,因此我建议您这样使用:

    if (!isCanvasSupported()){ ...
    
    您可以使用脚本来检测浏览器是否支持画布

    caniuse.canvas()
    

    如果要获得画布的上下文,不妨将其用作测试:

    var canvas = document.getElementById('canvas');
    var context = (canvas.getContext?canvas.getContext('2d'):undefined);
    if(!!context){
      /*some code goes here, and you can use 'context', it is already defined*/
    }else{
      /*oof, no canvas support :(*/
    }
    

    这是第二行的一个杂散的
    ,上下文吗?@brainjam-不,我在代码末尾附近使用了这个变量。我尝试遵循“建议”(在本例中,每个函数只有1个
    var
    语句)。我们在Modernizer中使用的测试是:
    return!!document.createElement('canvas').getContext
    这绝对是最好的测试方法。Modernizer是一个有用的库,但是仅仅为了检测canvas支持而引入整个库会有点浪费。如果您还需要检测其他功能,我建议您使用。诺基亚S60和黑莓Storm是一些在您建议的2D画布上会出现误报的设备之一。不幸的是,手机变得非常棘手,供应商也不遵守规则(因此,我们最终会进行更完整(即较慢)的测试,以确保准确的结果。@Paul:这很有趣,我测试了BlackBerry Storm模拟器,所有这些模拟器都返回了
    false
    。对于您和我的示例,它们似乎都没有提供
    CanvasRenderingContext2D
    界面。 到目前为止,我还无法测试S60,但我仍然很好奇,可能很快就会这样做。这很有趣,但只要测试不超过100毫秒,不是很好吗?我想它们都比这快得多。如果你记住一个测试这个的函数,那么你只需要支付一次费用。我运行了你的基准测试,甚至是“慢”方法每秒可以执行约800000次。同样,如果结果被缓存,那么使用哪种方法的决定应该基于健壮性,而不是性能(假设健壮性存在差异)@DrewNoakes:是的,你应该总是追求速度上的兼容性。我的论点是,我驳斥Paul的兼容性主张,这是基于我自己在他评论中提到的至少一个问题浏览器上的测试。我无法测试其他浏览器,但我仍然不相信有问题。你应该总是ai我希望在不牺牲兼容性的情况下获得尽可能好的性能。我不是在说微优化,但是如果你正在运行数百个测试,并且它们都是未经优化的,那么,是的,它可以带来不同。为什么双重否定(!!)会
    try {
        document.createElement("canvas").getContext("2d");
        alert("HTML5 Canvas is supported in your browser.");
    } catch (e) {
        alert("HTML5 Canvas is not supported in your browser.");
    }
    
    caniuse.canvas()
    
    var canvas = document.getElementById('canvas');
    var context = (canvas.getContext?canvas.getContext('2d'):undefined);
    if(!!context){
      /*some code goes here, and you can use 'context', it is already defined*/
    }else{
      /*oof, no canvas support :(*/
    }