处理浏览器不支持 HTML5 <canvas>
标记的情况的标准方法是嵌入一些后备内容,例如:
<canvas>Your browser doesn't support "canvas".</canvas>
但是页面的其余部分保持不变,这可能是不恰当的或具有误导性的。我想要一些检测画布不支持的方法,以便我可以相应地展示我的页面的其余部分。你会推荐什么?
这是 Modernizr 中使用的技术,基本上所有其他可以使用画布的库:
function isCanvasSupported(){
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
}
由于您的问题是在不支持时进行检测,因此我建议像这样使用它:
if (!isCanvasSupported()){ ...
在浏览器中检测画布支持有两种流行的方法:
Matt 建议检查 getContext 是否存在,Modernizr 库也以类似的方式使用: var canvasSupported = !!document.createElement("canvas").getContext;检查 WebIDL 和 HTML 规范定义的 HTMLCanvasElement 接口是否存在。 IE 9 团队的一篇博文也推荐了这种方法。 var canvasSupported = !!window.HTMLCanvasElement;
我的建议是后者的变体(请参阅附加说明),原因如下:
每个已知的支持画布的浏览器——包括 IE 9——都实现了这个接口;
代码在做什么更简洁明了;
getContext 方法在所有浏览器中的速度都慢得多,因为它涉及创建 HTML 元素。当您需要尽可能多地压缩性能时(例如,在像 Modernizr 这样的库中),这并不理想。
使用第一种方法没有明显的好处。这两种方法都可以被欺骗,但这不可能是偶然发生的。
补充说明
可能仍然需要检查是否可以检索 2D 上下文。据报道,一些移动浏览器可以为上述两项检查返回 true,但为 .getContext('2d')
返回 null
。这就是 Modernizr 还检查 .getContext('2d')
的结果的原因。然而,WebIDL & HTML - 再次 - 为我们提供了另一个更好的 faster 选项:
var canvas2DSupported = !!window.CanvasRenderingContext2D;
请注意,我们可以完全跳过检查画布元素,直接检查 2D 渲染支持。 CanvasRenderingContext2D
接口也是 HTML 规范的一部分。
您必须使用 getContext
方法检测 WebGL 支持,因为即使浏览器可能支持 WebGLRenderingContext
,getContext()
也可能返回 null em> 如果浏览器由于驱动程序问题而无法与 GPU 交互并且没有软件实现。在这种情况下,首先检查接口允许您跳过检查 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%。
https://i.stack.imgur.com/adEMj.png
false
,似乎它们不提供 CanvasRenderingContext2D
接口。到目前为止,我还无法测试 S60,但我仍然很好奇并且可能很快就会这样做。
我通常在创建画布对象时检查 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 的一个简单示例,我(个人)更喜欢优雅降级。
, context
吗?
var
语句)。
为什么不试试 modernizr ?它是一个提供检测能力的 JS 库。
引用:
你有没有想过在你的 CSS 中使用 if 语句来获得诸如边界半径之类的酷特性?好吧,有了 Modernizr,您就可以做到这一点!
return !!document.createElement('canvas').getContext
这绝对是最好的测试方法。
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.");
}
这里可能有一个陷阱——一些客户端不支持所有的画布方法。
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)
如果要获取画布的上下文,不妨将其用作测试:
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 :(*/
}
elem.getContext == undefined
。!undefined = true
和!true = false
,所以这让我们返回一个布尔值,而不是未定义或上下文。var i = 0
。 i 计算结果为 false,但 typeof i 返回“数字”。 typeof !!i 返回“布尔值”。undefined ? true : false
(虽然有点长)。toDataURL
。 Opera Mini 仅支持使用 no text API support 进行基本的画布渲染。 Opera Mini 可以排除this way,仅供参考。