陷入javascript封闭范围,直到我的大脑转向炒鸡蛋

时间:2012-03-06 14:23:38

标签: javascript image canvas scope closures

编辑:我发现除了第一次(硬)加载之外,每个页面加载都能正常工作。这是一个'奇怪的提示让它工作',因为它不使用onload。 E.g。

这适用于载荷2 ... n:

case String:
        var img = new Image();
        img.onload = function() {
            //context.drawImage(img,0,0);
        };
        img.src = detail;
        context.drawImage(img,0,0);

这不适用于任何负载1 ... n:

case String:
        var img = new Image();
        img.onload = function() {
            context.drawImage(img,0,0);
        };
        img.src = detail;
        //context.drawImage(img,0,0);

我不太高兴我错过了最重要的负载(第一个),但至少有一些进展。

有人可以指导我解释这里发生了什么吗?我真的很困惑。我希望每次都能加载图像并绘制到画布上。这是不切实际的期望吗?

我在Ubuntu上使用FF 7.0.1,我的用户代理是:Mozilla / 5.0(X11; Linux i686; rv:7.0.1)Gecko / 20100101 Firefox / 7.0.1

编辑:在评论中尝试所有方法后仍然失败。我会继续思考它。我认为它与画布不再可访问有关(即使变量正确解析并且在FF调试器中没有抛出错误)。

我正在编写一个用于渲染到画布的js框架,以提供一个简单的API来编写GUI,使用比使用Canvas API更少的代码和更漂亮的代码。它只是一个围绕画布的包装。但即使我喜欢js,我现在也不是js专家。无论如何。

闭包中的以下代码可以执行并访问img变量的范围,可以在图像加载范围内引发一个警告表单,可以更改img css样式属性,但不会在画布上下文中执行drawImage上下文变量。

在闭包之前,context.fillRect会正常工作,但在闭包内却没有。我认为还有一些基本的东西我还没有学过,因为我之前用封闭代码编写了类似的onload,而且一切正常。希望今天是我学到新东西的那一天。

RenderProvider.prototype.drawImage = function(srcElement,context,state,detail) {
    if(detail == undefined || detail == null) {
        alert("Image is not present. Ignoring.");
        return;
    }   
    switch(detail.constructor) { 
        case String:
                alert("Image is from String");
                var img = new Image();
                img.src = detail;//'t.jpg';//'Star-Field.gif';//http://www.google.com/favicon.ico';
                img.onload = function (e) { 
                    alert('Drawing ' + img + ' to ' + context);
                    alert('Context dim ' + context.canvas.width + ',' + context.canvas.height );
                    context.drawImage(img,20,20);
                    return true;
                };          
                img.src = detail;//'t.jpg';//'Star-Field.gif';//'http://www.google.com/favicon.ico';
                break;

3 个答案:

答案 0 :(得分:1)

我制作了一个jsfiddle,如果您想玩它,它就会有效。

var img = new Image();
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
img.src = 'http://www.google.com/favicon.ico';
img.onload = function() {
    context.drawImage(this, 20, 20); 
}​

请注意,我在回调函数中使用this而不是imgimg也有效,但使用this更为常见。此外,您可以在回调函数定义之后使用img.src = ...,但它仍然有效。

答案 1 :(得分:1)

这个函数在哪里被定义?如果要在脚本标记的代码中定义此函数,则在解析代码时,canvas元素(和上下文)将不存在,并且无法传入。

另请注意,闭包之后才会执行闭包。

答案 2 :(得分:0)

你需要等待window.onload事件以及图像onload事件,正如Phil H建议的那样。你在做吗?我在那里测试了你的第一个样本,但是等了window.onload,它适用于第一次加载。第二个不起作用。我不知道为什么。