2016-01-12 21 views
10

Sto cercando di creare un dispositivo di scorrimento semplice con immagini e video di YouTube. Voglio farlo funzionare bene sui dispositivi touch, quindi voglio usare ng-swipe-* dal modulo ngTouch di angular. Purtroppo lo scorrimento non funziona sull'iframe di YouTube. Ho provato a impostare inferiore z-index: -10;, ma poi non riesco a riprodurre il video.Angular ng-swipe con iframe youtube

Avete qualche idea su come risolvere questo problema?

Ci

è un frammento:

var app = angular.module('app', ['ngTouch']); 
 

 
app.controller('ctrl', function($scope) { 
 
    $scope.msg = function(msg) { 
 
    alert(msg); 
 
    } 
 
});
.ok { 
 
    width: 300px; 
 
    height: 100px; 
 
    background: green; 
 
}
<script src="https://code.angularjs.org/1.4.8/angular.min.js"></script> 
 
<script src="https://code.angularjs.org/1.4.8/angular-touch.min.js"></script> 
 
<div ng-app="app"> 
 
    <div ng-controller="ctrl" ng-swipe-right="msg('right')" ng-swipe-left="msg('left')"> 
 
    <div class="ok">swipe works here</div> 
 
    <div> 
 
     <iframe width="300" height="200" src="https://www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" allowfullscreen></iframe> 
 
    </div> 
 
    </div> 
 
</div>

(il modo migliore per provarlo, è di lanciarlo in console per sviluppatori di Chrome e di emulare il dispositivo touch)

+1

Questo sembra essere lo stesso problema - http://stackoverflow.com/questions/28180672/youtube-cannot-swipe-past-iframe-in-carousel-slider - dove si consiglia di utilizzare un'immagine in luogo dell'iframe all'inizio. È una soluzione praticabile? – jjbskir

+0

@jjbskir, hmm, Potrei usare l'immagine con il pulsante di riproduzione personalizzato, e sostituire il video e l'immagine al clic con ng-show, ma se l'utente mette in pausa il video non sarà più in grado di scorrere nuovamente. Inoltre, non so se è possibile avviare il video con un pulsante personalizzato;) – akn

risposta

2

Ecco un soluzione alternativa ad hacky: utilizzando due divisioni di overlay, impostate a destra e a sinistra del lettore consente all'utente di riprodurre e mettere in pausa e impostare l'altezza all'80% consente di m per usare il menu in basso. Questo non è perfetto, ma funziona in qualche modo!

Nota 1: È un po 'buggy se si gioca qui, quindi sono l'aggiunta di un codepen:http://codepen.io/anon/pen/LGjwYZ

Seconda versione, un po' più gonfio, ma con una maggiore copertura zona: http://codepen.io/anon/pen/rxzXxB

Nota 2: Ho usato uno sfondo trasparente sui div a scopo dimostrativo.

var app = angular.module('app', ['ngTouch']); 
 

 
app.controller('ctrl', function($scope) { 
 
    $scope.msg = function(msg) { 
 
    alert(msg); 
 
    } 
 
});
.ok { 
 
    width: 300px; 
 
    height: 100px; 
 
    background: green; 
 
}
<script src="https://code.angularjs.org/1.4.8/angular.min.js"></script> 
 
<script src="https://code.angularjs.org/1.4.8/angular-touch.min.js"></script> 
 
<div ng-app="app"> 
 
    <div ng-controller="ctrl" ng-swipe-right="msg('right')" ng-swipe-left="msg('left')"> 
 
    <div class="ok">swipe works here</div> 
 
    <div style="position:relative; height:200px; width:300px;"> 
 
     <iframe style="position:absolute;width:100%;height:100%;z-index:10;" src="https://www.youtube.com/embed/dQw4w9WgXcQ"></iframe> 
 
     <div style="background:rgba(0,0,0,0.3);height:80%;width:40%;left:0;position:absolute;z-index:20;"></div> 
 
     <div style="background:rgba(0,0,0,0.3);height:80%;width:40%;right:0;position:absolute;z-index:20;"></div> 
 
</div> 
 
    </div> 
 
</div>

+1

Grazie. Se nessuno post risposta migliore, accetterò questo. – akn

+0

Aggiornato con una versione più esagerata. –

2

Il problema è che non si ha il controllo di eventi all'interno del iframe, quindi non può dire quando l'utente swipes su quell'area. Il lavoro che ho suggerito è di sostituire l'iframe con un segnaposto immagine mentre non guardi. Per fare ciò, usa YouTube's Iframe API per tenere traccia degli eventi video. Quando il video passa dalla riproduzione alla pausa, nasconderemo il video e mostreremo l'immagine. Here is a demo.

HTML

<div ng-app="app"> 
    <div ng-controller="ctrl" ng-swipe-right="msg($event, 'right')" ng-swipe-left="msg($event, 'left')"> 
    <div id="player"></div> 
    <img id="player-cover" src="http://img.youtube.com/vi/M7lc1UVf-VE/hqdefault.jpg" /> 
    </div> 
</div> 

JS

sull'iniziazione Nasconde il video. Quando viene scattata l'immagine, mostra e riproduce il video. Quando il video passa dalla pausa per riprodurre onPlayerStateChange gestisce la commutazione dell'immagine e del video. Ogni volta che l'evento di scorrimento viene richiamato sull'immagine, attiva anche il gestore di eventi click per l'immagine. La variabile swiping tiene traccia di se l'evento è stato solo un clic o anche uno scorrimento.

var app = angular.module('app', ['ngTouch']); 

app.controller('ctrl', function($scope) { 
    $scope.msg = function(event, msg) { 
    swiping = true; 
    alert(msg); 
    } 
}); 

// keep track of the user swiping. onYouTubeIframeAPIReady needs to occur outside of Angular. 
var swiping = false; 

// Youtube related. 
document.getElementById('player').style.display = 'none'; 
document.getElementById('player-cover').addEventListener("click", function() { 
    if (swiping) { 
     swiping = false; 
     return; 
    } 
    document.getElementById('player').style.display = 'block'; 
    player.playVideo(); 
}); 

// 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); 

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

function onPlayerStateChange(event) { 
    if (event.data === YT.PlayerState.PAUSED || event.data === YT.PlayerState.ENDED) { 
     document.getElementById('player-cover').style.display = 'block'; 
     document.getElementById('player').style.display = 'none'; 
    } else { 
     document.getElementById('player-cover').style.display = 'none'; 
     document.getElementById('player').display = 'block'; 
    } 
} 
Problemi correlati