Onload mit Callback

jemand anders

Erfahrenes Mitglied
Hallo,

ich dem folgenden Script wird anhand von Video-ID und -Thumbnail gecheckt wird, ob ein Youtube-Video (noch) existiert.
Nachdem alle IDs gecheckt sind, wird eine Meldung mit allen fehlerhaften IDs ausgegeben.
Das geschieht momentan mit Hilfe eines Timeouts, was aber Nachteile hat.
Besser wäre es mit einem Callback zu machen.
Wer kann weiterhelfen?

Gruß

Javascript:
(function() {
    console.clear()
    var msg = [],
        videoIds = [
            "EPGL6Zo0s2o",
            "d6Xn3y1QZHA",
            "THWH2yCiuWI",
            "MpdJ_t5XMvw",
            "AgmA3zKDm8c",
            "1hHvlsVJz1s",
            "zGxy-dOvX0A",
        ]
    function validVideoId(callback) {
        for (var i = 0; i < videoIds.length; i++) {
            var img = new Image()
            img.videoId = videoIds[i]
            img.src = "https://img.youtube.com/vi/" + videoIds[i] + "/mqdefault.jpg"
            img.onload = function() {
                if (this.width === 120) {
                    msg = msg + this.videoId + "\n"
                }
            }
        }
    }
    validVideoId(Msg)
    function Msg(msg) {
        console.log("Msg:\n" + msg)
    }
    setTimeout(function() {
        console.log("Timeout:\n" + msg)
    }, 1000)
})()
 
Zuletzt bearbeitet:
Wenn Du auch einen Listener für das Error-Event registrierst, ist sicher gestellt, dass genau so viele Rückmeldungen kommen wie URLs geprüft wurden und Du kannst mit einem Zähler prüfen ob alle da sind.

BTW: Besser erst den Eventlistener registrieren und dann das src-Attribut setzen, sonst kann es passieren, dass das Event schon kommt bevor der Listener registriert wurde, wenn das Bild im Cache ist.
 
Wenn Du auch einen Listener für das Error-Event registrierst, ist sicher gestellt, dass genau so viele Rückmeldungen kommen wie URLs geprüft wurden und Du kannst mit einem Zähler prüfen ob alle da sind.

BTW: Besser erst den Eventlistener registrieren und dann das src-Attribut setzen, sonst kann es passieren, dass das Event schon kommt bevor der Listener registriert wurde, wenn das Bild im Cache ist.
Der onerror-Fall tritt nicht ein, da immer ein Bild zurückkommt, egal ob das Video existiert oder nicht. Hier ein Beispiel: https://i3.ytimg.com/vi/d6Xn3y1QZHA/default.jpg
Im Gegensatz zu einem Callback ist mit einem Timeout nicht sichergestellt, ob die Zeit ausreicht, um alle fehlerhaften IDs zu sammeln.
PS: Ich habe den Code noch ein wenig lesbarer gemacht.
 
Zuletzt bearbeitet:
Das ist natürlich dumm. Ich habe das mal ausprobiert und das Bild im Fehlerfall scheint eine andere Größe zu haben. Dann dürfte mein Vorschlag ohne onerror funktionieren:
Code:
    let counter = 0;
    function validVideoId(callback) {
        for (var i = 0; i < videoIds.length; i++) {
            var img = new Image()
            img.onload = function() {
                id = this.src.replace("https://img.youtube.com/vi/", "").replace("/mqdefault.jpg", "")
                if (this.width === 120) {
                    msg = msg + id + "\n"
                }
                counter++;
                if (counter == videoIds.length) {
                    // alle Videos sind geprüft
                }
            }
            img.src = "https://img.youtube.com/vi/" + videoIds[i] + "/mqdefault.jpg"
        }
    }
 
Zuletzt bearbeitet:
Ja, stimmt, so klappt es sogar auch ohne Callback.

Und so sieht das Ganze dann aus:

Javascript:
(function() {
    console.clear();
    var msg = [],
        counter = 0,
        videoIds = [
            "EPGL6Zo0s2o",
            "d6Xn3y1QZHA",
            "THWH2yCiuWI",
            "MpdJ_t5XMvw",
            "AgmA3zKDm8c",
            "1hHvlsVJz1s",
            "zGxy-dOvX0A",
        ];
    function validVideoId() {
        for (var i = 0; i < videoIds.length; i++) {
            var img = new Image();
            img.videoId = videoIds[i];
            img.src = "https://img.youtube.com/vi/" + videoIds[i] + "/mqdefault.jpg";
            img.onload = function() {
                if (this.width === 120) {
                    msg = msg + this.videoId + "\n";
                }
                counter++;
                if (counter == videoIds.length) {
                    console.log("Msg:\n" + msg);
                }
            };
        }
    }
    validVideoId();
    setTimeout(function() {
        console.log("Timeout:\n" + msg);
    }, 1000);
})();
 
Zurück