使用canvas时,Firefox会抛出错误0x80004005

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上失败,

谢谢你的帮助.

zwo*_*wol 6

这些错误消息让那些没有经验的人感到困惑,但是有很多信息被打包进去.重要的部分是:

组件返回失败代码: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)

您还需要更改所有呼叫者以匹配.我不保证这会起作用,但这是我能想到的最合理的事情.