被困在javascript关闭范围的边缘地带,直到我的大脑转向炒鸡蛋

Stuck in javascript closure scope limbo til my brains turn to scrambled eggs

本文关键字:我的 鸡蛋 javascript 范围 边缘      更新时间:2023-09-26

EDIT:我刚刚发现除了第一次(硬)加载之外,每个页面加载都可以使用一些东西。这是一个"让它工作的奇怪提示",因为它不使用onload。例如

这适用于负载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 Debugger中没有抛出错误)。

我正在编写一个用于渲染到canvas的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;

我做了一个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 = ...,它仍然有效。

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

还要注意的是,在封闭闭包的块运行之后,才会执行闭包。

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