0

我正在尝试编写一些代码来查找网页上的所有链接图像。到目前为止,我能够生成所有链接 (imageLinks) 的数组,但在最终 console.log(linkedImages) 下面的代码中始终显示一个空数组。

我无法理解的是我评论过“这有效/但这不起作用:”

我究竟做错了什么?非常感谢这个有点菜鸟的任何帮助。谢谢!

//Create an array of all the links containing img tags
var imageLinks = $("img").parent("a").map(function () {
    var h = $(this).attr("href");
    return h;
}).get();
//This correctly shows all the links:
//console.log(imageLinks);
//Declare an array to hold all the linked images 
var linkedImages = [];
//Loop through all the links to see if they're images or not
for (var l = 0; l < imageLinks.length; l++) {
    var currLink = imageLinks[l];

    function myCallback(url, answer) {
        if (answer) {
            //This works:
            console.log(url + ' is an image!');
            //But this doesn't work
            linkedImages.push(url);
        } else {
            //alert(url+' is NOT an image!');
        }
    }

    function IsValidImageUrl(url, callback) {
        var img = new Image();
        img.onerror = function () {
            callback(url, false);
        }
        img.onload = function () {
            callback(url, true);
        }
        img.src = url
    }
    IsValidImageUrl(currLink, myCallback);
};
//HELP! This always evaluates as just "[]"
console.log(linkedImages);
4

1 回答 1

0

@SLaks 说了什么。由于图像的加载是异步的,因此您的回调在图像加载完成之前不会触发。要解决此问题,您可以使用jQuery 中的$.Deferred(我假设您使用的是 jQuery,因为您的代码中有 $(...) ):

    function callback(dfd, url, answer) {
        if (answer) {
            //This works:
            console.log(url+' is an image!');
            //But this doesn't work
            dfd.resolve(url);
        } else {
            //alert(url+' is NOT an image!');
            dfd.reject();
        }
    }

    //Create an array of all the links containing img tags
    var imageLinks = $("img").parent("a").map(function() {
        var h = $(this).attr("href");
        return h;
    }).get();

    //This correctly shows all the links:
    //console.log(imageLinks);

    //Declare an array to hold all the linked images 
    var linkedImages = [];

    //Loop through all the links to see if they're images or not
    var dfds = [];
    for (var l=0; l<imageLinks.length; l++) {
        var currLink = imageLinks[l];
        var dfd = $.Deferred();
        dfd.done(function(url) { linkedImages.push(url); });
        dfds.push(dfd.promise());

        (function(dfd, url) {
            var img = new Image();
            img.onerror = function() { callback(dfd, url, false); }
            img.onload =  function() { callback(dfd, url, true); }
            img.src = url
        })(dfd, currLink);
    };

    $.when.apply(null, dfds).done(function() {
         console.log(linkedImages);
    });

尚未对此进行测试,但是关于如何使用 deferred 来实现目标的一般想法就在那里。

于 2013-01-02T22:44:39.733 回答