2013-08-09 17 views
11

Sto tentando di caricare l'API iframe di YouTube. Finora, tutto quello che sto cercando di fare è caricare e caricare il giocatore. Sembra caricare l'API, ma non riconosce "YT.Player()" come costruttore. L'errore esatto che sto ricevendo in quella linea, nella console js Chrome, è:Caricamento dell'API YouTube in jQuery

Uncaught TypeError: undefined is not a function 

Quindi ... Che nel mondo sto facendo di sbagliato? Ho gettato le dichiarazioni di console.log su questa cosa e ho provato a riscriverlo in alcuni modi. Ho provato a copiare l'API in un file locale. Ho provato a caricarlo con tag di script regolari. Ho provato a caricarlo con la stravagante modifica del DOM utilizzata nel riferimento API a https://developers.google.com/youtube/iframe_api_reference. Sono abbastanza sicuro che il codice sotto dovrebbe funzionare:

function youtubeAPIReady(script, textStatus, jqXHR) 
    { 
     player = new YT.Player('player', { 
      height: '390', 
      width: '640', 
      videoId: 'CxTtN0dCDaY' 
     }); 
    } 

    function readyFunction() 
    { 
     $.getScript("https://www.youtube.com/iframe_api", youtubeAPIReady); 
    } 

    jQuery(document).ready(readyFunction); 

Qualsiasi aiuto?

risposta

3

Citazione di http://api.jquery.com/jQuery.getScript/

la richiamata viene sparato una volta che lo script è stato caricato, ma non necessariamente eseguito.

L'API probabilmente non ha eseguito per il momento si chiama YT.Player()

+0

Il JS 'iframe_api' è stato caricato ed eseguito, ma probabilmente è solo un caricatore asincrono per il giocatore stesso.Il giocatore non è pronto immediatamente e devi usare il codice di una delle altre risposte per ritardare l'uso di "YT.Player". –

2

Non riesco a parlare per la soluzione jQuery, ma provate a utilizzare il javascript standard standard. In ogni caso non sarà necessario aspettare che il documento da caricare (questo codice dovrebbe sedersi fuori $(document).ready())

// Load the YouTube API asynchronously 
var tag = document.createElement('script'); 
tag.src = "https://www.youtube.com/iframe_api"; 
var firstScriptTag = document.getElementsByTagName('script')[0]; 
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 

// Create the player object when API is ready 
var player; 
window.onYouTubeIframeAPIReady = function() { 
    player = new YT.Player('player', { 
     height: '390', 
     width: '640', 
     videoId: 'CxYyN0dCDaY' 
    }); 
}; 
+1

Quote da http://api.jquery.com/jQuery.getScript/: 'La richiamata viene attivata una volta che lo script è stato caricato ma non necessariamente eseguito. Probabilmente l'API non è stata eseguita dal momento in cui si chiama' YT.Player() ' –

+0

Quindi, tutto ciò che dovevo veramente fare era usare la funzione onYouTubeAPIFrameReady. Voglio ancora usare getScript per caricare i dati, perché quella modifica DOM è sciocca, ma se si invia quel commento come risposta separata, lo contrassegnerò come corretto. – Daniel

+0

Inoltre, sto ricevendo: "" "Bloccato un frame con origine" https://www.youtube.com "dall'accesso a un frame con origine" http://danhakimi.com ". Il frame che richiede l'accesso ha un protocollo di "https", il frame a cui si accede ha un protocollo di "http". I protocolli devono coincidere. "" "Di cosa si tratta? – Daniel

14

È possibile prendere in prestito la tecnica used in YouTube Direct Lite di rinviare il caricamento del JavaScript finché non è esplicitamente necessaria:

var player = { 
    playVideo: function(container, videoId) { 
    if (typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') { 
     window.onYouTubeIframeAPIReady = function() { 
     player.loadPlayer(container, videoId); 
     }; 

     $.getScript('//www.youtube.com/iframe_api'); 
    } else { 
     player.loadPlayer(container, videoId); 
    } 
    }, 

    loadPlayer: function(container, videoId) { 
    new YT.Player(container, { 
     videoId: videoId, 
     width: 356, 
     height: 200, 
     playerVars: { 
     autoplay: 1, 
     controls: 0, 
     modestbranding: 1, 
     rel: 0, 
     showInfo: 0 
     } 
    }); 
    } 
}; 
+2

Mi sembra che questo potrebbe finire per chiamare getScript un po 'troppe volte. – Daniel

+1

ma secondo il repository di controllo di origine questo è un progetto di proprietà di Google. non saprebbero cosa stanno facendo? –

7
soluzione

poveri, ma ...

function readyYoutube(){ 
    if((typeof YT !== "undefined") && YT && YT.Player){ 
     player = new YT.Player('player', { 
      ... 
     }); 
    }else{ 
     setTimeout(readyYoutube, 100); 
    } 
} 
+0

Questa è un'ottima soluzione. YT non è stato definito per me, quindi ho fatto questo: if (tipo di YT! == "indefinito" && YT && YT.Player) { – sjsc

+0

grazie! aggiunto id alla risposta – user151496

0

Ho risolto questo problema combinando approcci di Simon e user151496.

Il codice:

<script> 
    // load API 
    var tag = document.createElement('script'); 
    tag.src = "https://www.youtube.com/iframe_api"; 
    var firstScriptTag = document.getElementsByTagName('script')[0]; 
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 

    // define player 
    var player; 
    function onYouTubeIframeAPIReady() { 
     player = new YT.Player('player', { 
      height: '360', 
      width: '640' 
     }); 
    } 

    $(function() { 

     // load video and add event listeners 
     function loadVideo(id, start, end) { 
      // check if player is defined 
      if ((typeof player !== "undefined")) { 
      // listener for player state change 
      player.addEventListener('onStateChange', function (event) { 
       if (event.data == YT.PlayerState.ENDED) { 
        // do something 
       } 
      }); 
      // listener if player is ready (including methods, like loadVideoById 
      player.addEventListener('onReady', function(event){ 
       event.target.loadVideoById({ 
        videoId: id, 
        startSeconds: start, 
        endSeconds: end 
       }); 
       // pause player (my specific needs) 
       event.target.pauseVideo(); 
      }); 
     } 
     // if player is not defined, wait and try again 
     else { 
      setTimeout(loadVideo, 100, id, start, end); 
     } 
     } 

     // somewhere in the code 
     loadVideo('xxxxxxxx', 0, 3); 
     player.playVideo(); 
    }); 
</script> 
-1

Rimuovere il blocco aggiuntivo dal vostro browser e riprova. Ha funzionato per me.

Problemi correlati