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);
    });

これをテストしていませんが、遅延を使用して目標を達成する方法の一般的なアイデアはそこにあります。

于 2013-01-02T22:44:39.733 に答える