2017-09-11 17 views
5

Łączę użycie interfejsu API iFrame YouTube i jQuery załadowanego za pomocą znacznika skryptu z ustawioną flagą defer. Flaga odroczenia musi być ustawiona, ponieważ klient ma doskonały wynik wglądu w stronę Google i chce utrzymać ten wynik.Zdarzenie wyzwalające po załadowaniu jQuery

Interfejs API YouTube po pełnym obciążeniu i gotowości do użycia natychmiastowo wywołuje funkcję, którą definiuję jako onYouTubeIframeAPIReady. Później zadzwoni pod numer onPlayerReady, gdy odtwarzacz zostanie w pełni załadowany i wyrenderowany.

Chcę używać jQuery w tej funkcji, ale użycie jQuery wewnątrz funkcji onPlayerReady spowoduje stworzenie warunku wyścigu (mając nadzieję, że biblioteka jQuery zakończyła ładowanie do czasu, gdy zostanie wywołana funkcja onPlayerReady).

Okazało się, że dobrym rozwiązaniem byłoby użycie funkcji onPlayerReady w celu ustawienia zmiennej przed wywołaniem funkcji testującej zarówno odtwarzacz, jak i jQuery. Inna funkcja ustawia zmienną po przygotowaniu jQuery i wywołuje tę samą funkcję testową.

Mam trochę kodu, który działa, ale część, która sprawdza jQuery wydaje się być niechlujny dla mnie, a także wprowadza niewielką ilość dodatkowego niepotrzebnego opóźnienia. Zastanawiam się, czy ktoś wie o lepszym sposobie uruchamiania czegoś, co natychmiast stanie się dostępne. Zasadniczo, czy są dostępne wywołania zwrotne dla jQuery wbudowane w samej bibliotece?

Mój bieżący kod wygląda następująco:

var ready = { 
    'jquery': false, 
    'youtube' false 
}, 
testJQueryLoaded; 

testJQueryLoaded = function() { 
    if(typeof jQuery == 'undefined') { 
     window.setTimeout(function() { 
      testJQueryLoaded(); 
     }, 25); 
     return; 
    } 

    ready.jquery = true; 
    postLibraryLoad(); 
}; 

testJQueryLoaded(); 

function onYouTubeIframeAPIReady() { 
    // Stuff 
}; 

function onPlayerReady() { 
    ready.youtube = true; 
    postLibraryLoad(); 
}; 

function postLibraryLoad() { 
    if(!ready.jquery || !ready.youtube) { 
     return; 
    } 

    // More stuff 
}; 
+1

Nie, nie ma takiego zdarzenia. możesz jednak dołączyć tag skryptu za pomocą javascript i słuchać jego zdarzeń. –

Odpowiedz

1

Jak sugeruje @KevinB można wykorzystać load zdarzenia specyficznego <script> elementu

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" defer></script> 
 
    <script defer> 
 
    const dojQueryStuff = (el, params) => this.jQuery(el, params).appendTo("body"); 
 
    </script> 
 
    <script defer> 
 
    document 
 
    .querySelector("script[src$='3.2.1/jquery.min.js']") 
 
    .onload = event => { 
 
     console.log(event.target.src); 
 

 
     dojQueryStuff("<div>", { 
 
     html: "jQuery version: " + this.jQuery().jquery + " loaded" 
 
     }); 
 
    } 
 
    </script> 
 
</head> 
 

 
<body> 
 
</body> 
 

 
</html>

+0

Czy dokładnie to, czego szukałem, dziękuję. – Scoots

1

Przypuszczam .ready() zrobi.

$(document).ready(function(){ 
    ready.jquery = true; 
    postLibraryLoad(); 
}); 

Możesz wiedzieć, ale ..
1. Ten błąd wykonanie nie rzucać przed jQuery jest załadowany, a
2. Byłoby to wykonać tylko raz i tylko gdy jQuery jest gotowy.

więc przypuszczam ten kod poniżej działa:

var ready = { 
    'jquery': false, 
    'youtube': false 
}; 

$(document).ready(function(){ 
    ready.jquery = true; 
    postLibraryLoad(); 
}); 

function onYouTubeIframeAPIReady() { 
    // Stuff 
} 

function onPlayerReady() { 
    ready.youtube = true; 
    postLibraryLoad(); 
} 

function postLibraryLoad() { 
    if(!ready.jquery || !ready.youtube) { 
     return; 
    } 

    // More stuff 
} 

Zakładając onYouTubeIframeAPIReady() jest wyzwalany w innym miejscu po pierwsze, ten kod powinien działać postLibraryLoad() nawet dwukrotnie albo po youtube jest gotowy lub jQuery jest gotowy ostatecznie uruchomiony // More stuff tylko kiedy oba są gotowe.

edit: Format
edit: dodaje wyjaśnienie

+0

Niestety, powoduje to błąd, ponownie z powodu ustawienia flagi opóźniającej przy ładowaniu biblioteki jQuery '' - ta flaga powoduje (ze specyfikacji HTML5) "skrypt jest wykonywany, gdy strona zakończyła parsowanie." Z uwagi na to, że wynik wglądu strony jest koniecznością dla mojego klienta, cały javascript MUSI być w odroczonym skrypcie lub w formie inline. Moje własne badania doprowadziły mnie do przekonania, że ​​włączenie tego kodu do pliku defer'd spowoduje wprowadzenie kolejnego stanu wyścigu w niektórych przeglądarkach: https://stackoverflow.com/a/10731231/4027341 – Scoots

+0

Powinieneś również mieć asynchronicznie swój kod. Jednym (interesującym) sposobem na uniknięcie warunków wyścigowych jest holdReady: https://api.jquery.com/jQuery.holdReady/ –

+1

@Scoots Ah, przepraszam, że całkowicie pominąłem kwestię. zdumiewająco, ale czy możliwe jest utworzenie jednego pliku skryptu zawierającego zarówno jQuery, jak i twój kod, zamiast dwóch osobnych plików? – AlexKlaus

1

wiem to maja wydaje się dziwne, ale jeśli jest to mały kod jesteś zaniepokojony, to dlaczego nie można dodać go do wnętrza biblioteki jQuery, u Dolny. i zadzwoń pod numer onYouTubeIframeAPIReady(). możesz również całkowicie usunąć tę część ready.jquery = true;.

+0

Kod interfejsu API YouTube musi być dynamiczny - różne strony mają różne odtwarzane filmy, więc będąc potencjalnie dobrym rozwiązaniem w próżni, nie nadaje się tutaj. +1 chociaż – Scoots

Powiązane problemy