141

处理浏览器不支持 HTML5<canvas>标签的情况的标准方法是嵌入一些后备内容,例如:

<canvas>Your browser doesn't support "canvas".</canvas>

但是页面的其余部分保持不变,这可能是不恰当的或具有误导性的。我想要一些检测画布不支持的方法,以便我可以相应地展示我的页面的其余部分。你会推荐什么?

4

8 回答 8

219

这是 Modernizr 中使用的技术,基本上所有其他可以使用画布的库:

function isCanvasSupported(){
  var elem = document.createElement('canvas');
  return !!(elem.getContext && elem.getContext('2d'));
}

由于您的问题是在支持时进行检测,因此我建议像这样使用它:

if (!isCanvasSupported()){ ...
于 2010-04-30T19:06:42.187 回答
104

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

  1. Matt 提出的检查 是否存在的建议, getContextModernizr 库也以类似的方式使用:

    var canvasSupported = !!document.createElement("canvas").getContext;
    
  2. 检查WebIDLHTML规范HTMLCanvasElement定义的接口是否存在。IE 9 团队的一篇博客文章也推荐了这种方法。

    var canvasSupported = !!window.HTMLCanvasElement;
    

我的建议是后者的变体(参见附加说明),原因如下:

  • 每个已知的支持画布的浏览器——包括 IE 9——都实现了这个接口;
  • 代码在做什么更简洁明了;
  • getContext方法在所有浏览器上都显着变慢,因为它涉及创建 HTML 元素。当您需要尽可能多地压缩性能时(例如,在像 Modernizr 这样的库中),这并不理想。

使用第一种方法没有明显的好处。这两种方法都可以被欺骗,但这不可能是偶然发生的。

补充笔记

可能仍然需要检查是否可以检索 2D 上下文。据报道,一些移动浏览器可以为上述两项检查返回 true ,但返回null. .getContext('2d')这就是 Modernizr 也检查.getContext('2d'). 然而,WebIDL 和 HTML——再次——为我们提供了另一个更好、更快的选择:

var canvas2DSupported = !!window.CanvasRenderingContext2D;

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

必须使用检测 WebGLgetContext支持的方法,因为即使浏览器可能支持,如果浏览器由于驱动程序问题而无法与 GPU 交互并且没有软件实现,则可能会返回null 。在这种情况下,首先检查接口允许您跳过检查:WebGLRenderingContextgetContext()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
    }
}

##Performance 比较该getContext方法的性能在 Firefox 11 和 Opera 11 中慢 85-90%,在 Chromium 18 中慢约 55%。

    <a href="http://jsperf.com/htmlcanvaselement-vs-getcontext-checks" rel="nofollow noreferrer">简单对比表,点击在浏览器中运行测试

于 2010-04-30T15:03:50.370 回答
13

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。这是Progressive Enhancement的一个简单示例,我(个人)更喜欢 Graceful Degradation。

于 2010-04-30T15:01:59.797 回答
6

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

引用:

你有没有想过在你的 CSS 中使用 if 语句来获得诸如边界半径之类的酷特性?好吧,有了 Modernizr,您就可以做到这一点!

于 2010-04-30T15:10:36.613 回答
5
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.");
}
于 2011-11-10T18:36:59.077 回答
1

这里可能有一个陷阱——一些客户端不支持所有的画布方法。

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)
于 2010-04-30T16:22:44.357 回答
0

您可以使用canisuse.js脚本来检测您的浏览器是否支持画布

caniuse.canvas()
于 2016-06-16T06:13:59.753 回答
0

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

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 :(*/
}
于 2019-10-07T19:36:04.283 回答