elx*_*rdi 3 javascript firefox jquery canvas
当我在Firefox上使用canvas时,有时会出现类似这样的错误:
错误:未捕获的异常:[Exception ..."组件返回失败代码:0x80004005(NS_ERROR_FAILURE)[nsIDOMCanvasRenderingContext2D.lineWidth]"nsresult:"0x80004005(NS_ERROR_FAILURE)"location:"JS frame :: media/js/canvas/Rectangle.js :: ::第34行"数据:否]
当我在for循环中使用超过5个canvas元素时,就会发生这种情况.创建它们的功能是:
function addCanvas(id) {
var canvas = document.getElementById(id);
if (canvas == null) {
$('#content').append(
'<canvas id="' + id + '" width="' + workAreaWidth +'" height="'
+ workAreaHeight + '"></canvas>'
);
canvas = document.getElementById(id).getContext('2d');
} else {
canvas = canvas.getContext('2d');
canvas.setTransform(1, 0, 0, 1, 0, 0);
canvas.clearRect(0, 0, workAreaWidth, workAreaHeight);
}
return canvas;
}
Run Code Online (Sandbox Code Playgroud)
for循环是另一个函数.
会发生的是并非所有画布元素都会更新.我猜是异常的原因.
我无法发布它完全失败的地方的代码,导致它在许多地方随机失败,总是出现相同的错误.
Firefox版本为9.0,但也发生在8.0.1上.我没有在以前的版本中测试它.我的操作系统是Mac Snow Leopard.我想这会有所帮助.它不会在Chrome或Safari上失败,
谢谢你的帮助.
这些错误消息让那些没有经验的人感到困惑,但是有很多信息被打包进去.重要的部分是:
组件返回失败代码:0x80004005(NS_ERROR_FAILURE)[nsIDOMCanvasRenderingContext2D.lineWidth]
忽略十六进制数:这告诉您访问者nsIDOMRenderingContext2D.lineWidth返回了一般失败代码(NS_ERROR_FAILURE)而不是行宽. nsIDOMRenderingContext2D是C++类的内部名称,它实现了从getContext("2d")canvas元素上获取的对象.
location:"JS frame :: media/js/canvas/Rectangle.js :: :: line 34"
从JavaScript到失败的C++方法的调用是在第34行media/js/canvas/Rectangle.js.那是你的代码.但是,这不是您引用的代码,但也许我们可以通过查看失败的访问器的代码来找出问题所在:http://mxr.mozilla.org/mozilla-central/source/content/canvas /src/nsCanvasRenderingContext2D.cpp#3180
nsresult
nsCanvasRenderingContext2D::GetLineWidth(float *width)
{
if (!EnsureSurface())
return NS_ERROR_FAILURE;
gfxFloat d = mThebes->CurrentLineWidth();
*width = static_cast<float>(d);
return NS_OK;
}
Run Code Online (Sandbox Code Playgroud)
好的,所以失败的唯一方法就是EnsureSurface失败. 这是在http://mxr.mozilla.org/mozilla-central/source/content/canvas/src/nsCanvasRenderingContext2D.cpp#1154中定义的,我不会在这里引用它,因为它很大并且有一大堆它可能失败的方式.但是,它看起来像你的一个canvas元素要么没有正确定义,要么没有机会初始化自己(即你需要允许事件循环运行).
编辑:具体建议:更改您引用的功能如下:
function addCanvas(id, continuation) {
if (document.getElementById(id) === null) {
$('#content').append(
'<canvas id="' + id + '" width="' + workAreaWidth +'" height="'
+ workAreaHeight + '"></canvas>'
);
}
setTimeout(function() {
var canvas = document.getElementById(id).getContext('2d');
canvas.setTransform(1, 0, 0, 1, 0, 0);
canvas.clearRect(0, 0, workAreaWidth, workAreaHeight);
continuation(canvas);
}, 0);
}
Run Code Online (Sandbox Code Playgroud)
您还需要更改所有呼叫者以匹配.我不保证这会起作用,但这是我能想到的最合理的事情.