2015-10-10 8 views
9

Ive zrobił przycisk pauzy dla filmu na YouTube. To działało dobrze, ale teraz muszę sklonować wideo. Wynika to z tego, jak działa karuzela, z której korzysta, i dlatego wideo może być wyświetlane w Lightbox.Przycisk wstrzymania JavaScriptu do filmu z YouTube, który został sklonowany?

Poniżej znajduje się uproszczona wersja mojego kodu. Teraz przycisk pauzy działa tylko przy pierwszym filmie. Jak mogę zrobić przycisk, który zatrzyma wszystkie sklonowane filmy?

http://jsfiddle.net/36vr2kjv/2/

<p class="trigger">Trigger</p> 
<p class="trigger2">Trigger2</p> 

<div class="player-wrap"> 
    <div id="player"></div> 
</div> 

<div id="player2"></div> 

var player; 

$(function() { 
    // 2. This code loads the IFrame Player API code 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); 

     // 3. This function creates an <iframe> (and YouTube player) 
     // after the API code downloads. 
     onYouTubeIframeAPIReady = function onYouTubeIframeAPIReady() { 
     player = new YT.Player('player', { 
      height: '390', 
      width: '640', 
      videoId: 'M7lc1UVf-VE', 
      events: { 
      'onReady': onPlayerReady, 
      'onStateChange': onPlayerStateChange 
      } 
     }); 
     } 

     // 4. The API will call this function when the video player is ready. 
     function onPlayerReady(event) { 
     event.target.playVideo(); 
     } 

     // 5. The API calls this function when the player's state changes. 
     // The function indicates that when playing a video (state=1), 
     // the player should play for six seconds and then stop. 
     var done = false; 
     function onPlayerStateChange(event) { 
     if (event.data == YT.PlayerState.PLAYING && !done) { 
      setTimeout(stopVideo, 6000); 
      done = true; 
     } 
     } 
     function stopVideo() { 
     player.stopVideo(); 
     } 

     $('.trigger').click(function(){ 
      //this works 
      player.pauseVideo() 
     }); 

    return player; 
}); 

$(function() { 
    setTimeout(function(){ 
     $('.player-wrap').clone().appendTo('#player2'); 
    }, 2000); 
}); 

$(function() { 
    $('.trigger2').click(function(){ 
      // this does not work 
      player.pauseVideo() 
     }); 
}); 
+0

wydaje się tak blisko ciebie niż poprzedni post http://stackoverflow.com/questions/33021656/pause-youtube-video-from-a-separate-function – mpgn

+0

Podobny kod tak, ale bardzo różne pytanie. – Evans

Odpowiedz

0


Issue Opis:


Co się dzieje w kodzie jest ma zostać skopiowany i tworząc dwa identyfikatory w obrębie jednego obciążenia DOM, co oznacza, że ​​skrypt będzie mieć sprzeczne identyfikatory do radzenia sobie. Innym problemem jest to, że funkcja tworzenia interfejsu API youtube wiąże się z identyfikatorem, a nie z klasą.

Po sklonowaniu ramki iframe oryginalna funkcja (przechowywana w player) jest teraz wskazywana w dwóch miejscach ... stąd zamieszanie.


Rozwiązanie:


Aby temu zapobiec, możemy użyć zastępczy. Na podstawie odwołania do interfejsu API odtwarzacza YouTube Youtube umożliwia ładowanie filmów do obiektu odtwarzacza.

player.loadVideoById(videoId:String, 
        startSeconds:Number, 
        suggestedQuality:String):Void 

[Zobacz Youtube API#Queueing_Functions]

Możemy użyć klas i obiektów odniesienia, aby osiągnąć swój cel:

player; 
placeholder; 
playerCount = 1; 
$(function() { 

     // ... Previous code ... // 

     /** 
     * Assuming you have more than one video to play, 
     * the function will change to allow for incrementing the ids 
     * of each player made. [UNIQUE IDS] 
     */ 
     onYouTubeIframeAPIReady = function onYouTubeIframeAPIReady() { 
     player = new YT.Player('player-'+playerCount, { 
      height: '390', 
      width: '640', 
      videoId: 'M7lc1UVf-VE', 
      events: { 
      'onReady': onPlayerReady, 
      'onStateChange': onPlayerStateChange 
      } 
     }); 
     placeholder = new YT.Player('placeholder', { 
      height: '390', 
      width: '640', 
     }); 

      /** 
      * Now add a generic class so we can find all of these elements, 
      * and bind the object to a data instance for access later. 
      */ 
      $('#player-' + playerCount).addClass('youtube-player').data('YoutubeAPI', player); 

      playerCount++; 
     } 

zastępczy wchodzi w grę teraz, gdy karuzela pożarów to beforeChange wydarzenie, ty może uzyskać dostęp do elementu gracza z bieżącego/następnego/poprzedniego slajdu za pomocą obsługi karuzeli event i uruchamiając $(event.target).find('youtube-player') (lub coś w tym stylu, interfejsy API są różne, więc YMMV) i dostęp do warstwa instancja przy użyciu $(event.target).find('youtube-player').data('YoutubeAPI') (lub cokolwiek nazwa zmienna danych).

Następnie wystarczy znaleźć identyfikator wideo z oryginalnego obiektu (korzystając ze schematu dostępu z góry i biorąc identyfikator z obiektu interfejsu API youtube) i załadować wideo do symbolu zastępczego za pomocą połączenia API z góry.

+0

Zrobiłem coś nie tak? To nie działa: http://jsfiddle.net/xknjqcm7/1/ – Evans

1

W rzeczywistości istnieje koncepcja głębokiego klonowania i płytkiego klonowania. Shallow cloning nie kopiuje wydarzeń, dlatego musisz używać głębokiego klonowania. Gdziekolwiek używasz clone() zamiast tego użyj clone (true). Na przykład w powyższym fragmencie kodu można użyć:

$(function() { 
    setTimeout(function(){ 
     $('.player-wrap').clone(true).appendTo('#player2'); 
    }, 2000); 
}); 
+0

To nie działa na mój przykład. – Evans

+0

Klon yeah (true) nie działa. – James

Powiązane problemy