简体   繁体   中英

Setting a global variable from within a nested private function

Hello and thanks in advance for your help with this conundrum!

I'm having trouble setting globalMaxW from within the $.imgpreload() function.

console.log(globalMaxW); returns 0 when called after the $.imgpreload() function whereas, when called inside of the $.imgpreload() function returns the correct image width.

How can I set the global variable globalMaxW from within that nested function?

Thank you!

var globalMaxW = 0; 

function infoWidth() {

    $('.swipe-wrap img').each(function(){
        var $me = $(this),
            mysrc = $me.attr('src');

        var newimg = new Image();

        newimg.src = mysrc;

        $.imgpreload($me, function(){
            if(newimg.width > globalMaxW) {
                globalMaxW = newimg.width;
            }           
        });

        console.log(globalMaxW);
    });



    $('#info p').css({'width' : globalMaxW});
}

Your console.log(globalMaxW) occurs before the below code finishes executing, and yes it does equal to zero at that time:

 $.imgpreload($me, function(){
            if(newimg.width > globalMaxW) {
                globalMaxW = newimg.width;
            }           
        });

Since the function is asynchronous, it starts running "imgpreload" and immediately continues without waiting for it to finish. globalMaxW will be set, but after console.log()...

I assume that this is the jquery.imgpreload plugin. imgpreload is async, so your globalMaxW is set but only after call back function that you pass as a second parameter invoked and this happens only after image is fetched in an async manner. I understand that you want to set css property only after all of the images are preloaded. So you can use a collection of jquery deferred objects to accomplish this.

In the code below, jQuery $.Deferred object will be created and pushed into an array for each of the imgpreload call. You can see that deferred is resolved once imgpreload invoked the call back.

At the bottom $.when function basically invokes done call back once every $.Deferred in the promises collection is resolved.

function infoWidth() {
    var promises = [];

    $('.swipe-wrap img').each(function(){
        var $me = $(this),
            mysrc = $me.attr('src');

        var newimg = new Image();

        newimg.src = mysrc;

        var def = new $.Deferred();
        promises.push(def);

        $.imgpreload($me, function(){
            if(newimg.width > globalMaxW) {
                globalMaxW = newimg.width;
            }           
            def.resolve();
        });

        console.log(globalMaxW);
    });

    $.when.apply($, promises).done(function(){
      // when all of the promises are resolved that means all imgpreload functions invoked the callbacks
      // and here your globalMaxW is set.
      $('#info p').css({'width' : globalMaxW});
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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