简体   繁体   English

jQuery / Javascript-在(文档)之前运行功能。准备好加载图像

[英]jQuery/Javascript - Run function before (document).ready for the purpose of loading an image

I am trying to get the dimensions of an image in order to resize (or size) a canvas of it's length with twice the width. 我试图获取图像的尺寸,以便调整其长度的画布的宽度(或宽度),使其宽度加倍。 (So, for a 400x800 image I want a 800x800 canvas). (因此,对于400x800的图片,我需要800x800的画布)。 What I'm trying to do right now is load the image twice, once to determine it's size and another time to display it. 我现在想做的是将图像加载两次,一次确定图像的大小,再一次显示。 My HTML w/ Javascript/JQuery looks like 我的带有Javascript / JQuery的HTML看起来像

<!DOCTYPE html>
<html>
<head>
<title>Canvas from scratch</title>
<meta charset="utf-8">

<script
    src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="jcanvas.min.js"></script>
</head>

<body>
    <canvas id="myCanvas" width="1100" height="500">
        </canvas>
    <script>

        $("<img />").attr("src", "test1image.jpg").load(function() {
            /* This is where I'd like to load the image to get its dimensions */
        });

        $(document).ready(
                function() {


                    var imgWidth, imgHeight;
                    var imageData; 

                    var image = new Image();
                    var canvas = document.getElementById("myCanvas");
                    var ctx = canvas.getContext("2d");

                    $(image).load(function() {
                        /* This is where the image is loaded and 
                           inserted into the canvas */
                        ctx.drawImage(image, 0, 0);
                    });
                    image.src = "test1image.jpg"; 

                    imageData = ctx.getImageData(0, 0,
                            image.width,
                            );

                    /* This is just part of the image manipulation, 
                       bland right now */
                    var newImgData = ctx.createImageData(imageData.width,
                            imageData.height);
                    for ( var i = 0; i < newImgData.data.length; i += 4) {
                        newImgData.data[i + 0] = 255;
                        newImgData.data[i + 1] = 0; 
                        newImgData.data[i + 2] = 0; 
                        newImgData.data[i + 3] = 255;       
                    }
                    ctx.putImageData(newImgData, imageData.width, 0);

                });
    </script>
</body>
</html>

One thing I've kept trying but noticed is not working is trying to place the function before (document).ready, but if the (document).ready call always comes first. 我一直尝试但发现无法正常工作的一件事是尝试将函数放在(document).ready之前,但是如果(document).ready调用始终位于第一位。 I can't seem to get the image to load without the canvas already being created (because it is in the (document).ready call). 我似乎无法在未创建画布的情况下加载图像(因为它位于(document).ready调用中)。 Can anyone explain what's going on? 谁能解释这是怎么回事?

Thanks. 谢谢。

Edit_1: I just tried adding Edit_1:我刚刚尝试添加

jQuery(window).load(function() {
            $("<img />").attr("src", "test1image.jpg").load(function() {
                imgWidth = this.width;
            });
        });

to the top of the script, but imgWidth is being declared as undefined in (document).ready. 到脚本顶部,但是imgWidth在(document).ready中被声明为未定义。

Edit_2: So, that actually worked really well blgt. Edit_2:所以,实际上运行得很好。 Here's the new code, and it's 100% functional. 这是新代码,并且100%可用。 The new canvas size is exactly what I wanted, based on the image dimensions and it all works... only thing I'm thinking is that there might be one too many nested functions but I'll try to work that out on my own. 新的画布大小恰好是我想要的,基于图像的大小,并且都可以使用...我唯一想的是嵌套功能太多,但是我将尝试自己解决。

<!DOCTYPE html>
<html>
<head>
<title>Canvas from scratch</title>
<meta charset="utf-8">

<script
    src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="jcanvas.min.js"></script>
</head>

<body>
    <canvas id="myCanvas" width="1100" height="500">
        </canvas>
    <script>
        $(document).ready(
                function() {
                    $("<img>").attr("src", "test1image.jpg").on('load', function() {
                        var imgWidth, imgHeight;
                        var imageData; 
                        var image = new Image();
                        var canvas = document.getElementById("myCanvas");
                        var ctx = canvas.getContext("2d");
                        ctx.canvas.width = this.width * 2;
                        ctx.canvas.height = this.height; 
                        $(image).on("load", function() {
                            /* This is where the image is loaded and 
                               inserted into the canvas */
                            ctx.drawImage(image, 0, 0);

                        });
                        image.src = "test1image.jpg"; 

                        imageData = ctx.getImageData(0, 0,
                                this.width,
                                this.height);

                        /* This is just part of the image manipulation, 
                           bland right now */
                        var newImgData = ctx.createImageData(imageData.width,
                                imageData.height);
                        for ( var i = 0; i < newImgData.data.length; i += 4) {
                            newImgData.data[i + 0] = 255;
                            newImgData.data[i + 1] = 0; 
                            newImgData.data[i + 2] = 0; 
                            newImgData.data[i + 3] = 255;       
                        }
                        ctx.putImageData(newImgData, imageData.width, 0);
                 });
                });
    </script>
</body>
</html>

This syntax: .load() is deprecated, use .on('load'... instead. Also, this won't delay execution of the function in .ready . Is there a reason you can't do the simple, stupid thing and just put a callback to that function inside the .on('load', handler) handler instead? 这种语法:不建议使用.on('load'... .load() ,而应使用.on('load'...此外,这也不会延迟.ready函数的执行。这是您无法执行简单,愚蠢的原因的原因东西,而是在.on('load', handler)处理函数中放入该函数的回调?

$(document).ready(function() {
         $("<img>").attr("src", "test1image.jpg").on('load', function() {
                // do stuff with dimensions

                var imgWidth, imgHeight;
                var imageData; 
                // ... etc.

         });
});

You're trying to shoehorn a synchronous sequence onto an asynchronous model, and basically you just don't want to do this. 您正在尝试将同步序列拖到异步模型上,基本上,您只是不想这样做。

The document ready event is supposed to fire before other assets have been loaded: http://api.jquery.com/ready/ - note it mentions exactly the case you're asking about. 文档就绪事件应该在加载其他资产之前触发: http : //api.jquery.com/ready/-请注意,它完全提到了您要询问的情况。

In cases where code relies on loaded assets (for example, if the dimensions of an image are required), the code should be placed in a handler for the load event instead. 如果代码依赖于已加载的资产(例如,如果需要图像的尺寸),则应将代码放置在用于加载事件的处理程序中。

So you should be able to just change your code to use document.load() instead of document.ready() but this will then wait until all assets are loaded. 因此,您应该能够仅将代码更改为使用document.load()而不是document.ready()但这将等待所有资产加载完毕。 If you only want to wait for that specific image to load, you should move the code from document.ready to the image's load event. 如果只想等待该特定图像加载,则应将代码从document.ready移至该图像的load事件。

EDIT: 编辑:

Your new code basically does the last option - moves the code into the image's load event, which is probably the best overall as it allows your code to run as soon as the particular image is ready. 您的新代码基本上会执行最后一个选项-将代码移入图像的load事件,这可能是最好的总体选择,因为它允许您的代码在特定图像准备好后立即运行。 You can potentially make it happen sooner by pre-loading the image in an inline script before loading your JS libraries etc. which would allow the image to start downloading in parallel to other assets, rather than waiting for the document ready event to start the image loading. 您可以通过在加载JS库等之前在嵌入式脚本中预加载图像来使图像更早实现,这将允许图像与其他资产并行开始下载,而不是等待文档就绪事件开始图像加载中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM