Onload mit Callback

phwert

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:

Sempervivum

Erfahrenes Mitglied
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.
 

phwert

Erfahrenes Mitglied
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:

Sempervivum

Erfahrenes Mitglied
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:

phwert

Erfahrenes Mitglied
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);
})();