检测不支持 HTML5 < 画布 > 的最佳方法

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

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

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

80653 次浏览

我通常在创建画布对象时检查 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 中。这是 渐进增强的一个简单示例,我(个人)更喜欢它而不是优雅降级。

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

  1. Matt 关于检查 getContext是否存在的建议,现代化图书馆也以类似的方式使用:

    var canvasSupported = !!document.createElement("canvas").getContext;
    
  2. 根据 WebIDL超文本标示语言规范的定义,检查 HTMLCanvasElement接口的存在。在 IE9团队的一篇博客文章中也推荐了这种方法。

    var canvasSupported = !!window.HTMLCanvasElement;
    

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

  • 所有已知的支持画布的浏览器-包括 IE9-都实现了这个接口;
  • 代码所做的事情更加简洁明了;
  • getContext方法是 在所有浏览器中显著减慢,因为它涉及到创建 HTML 元素。当您需要尽可能地压缩性能时(例如,在一个类似于 Modern izr 的库中) ,这并不理想。

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

附加说明

可能仍然需要检查是否可以检索到2D 上下文。据报道,一些移动浏览器可以返回真以上两个检查,但返回 null.getContext('2d')。这就是为什么 Modern izr 也检查 .getContext('2d')的结果。然而,WebIDL & HTML 再一次为我们提供了另一个更好的 再快点选项:

var canvas2DSupported = !!window.CanvasRenderingContext2D;

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

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

Simple comparison table, click to run a test in your browser

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

语录:

你有没有想过 对象的 CSS 中的 if-语句 有很多很酷的功能,比如 - 边界半径?-嗯,用现代化 你可以做到的!

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

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)

这是在 Modernizr 以及其他所有从事画布工作的图书馆所使用的技术:

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

因为你的问题是为了检测它是否支持 没有,所以我建议这样使用它:

if (!isCanvasSupported()){ ...
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.");
}

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

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 :(*/
}