2016-01-12 11 views
10

Próbuję zbudować prosty suwak z obrazami i filmami z YouTube. Chcę, aby działał dobrze na urządzeniach dotykowych, dlatego chcę użyć ng-swipe-* z modułu kątowego ngTouch. Niestety przesunięcie nie działa nad iframe youtube. Próbowałem ustawić niższy z-index: -10;, ale nie mogę odtworzyć wideo.Kątowe przesuwanie palcem z iftube ifrube

Czy masz pojęcie, jak rozwiązać ten problem?

Nie

jest fragment:

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>

(najlepszym sposobem, aby go przetestować, to uruchomić go w konsoli programisty Chrome i emulować na urządzeniu dotykowym)

+1

To wydaje się być ten sam problem - http://stackoverflow.com/questions/28180672/youtube-cannot-swipe-past-iframe-in-carousel-slider - gdzie zalecamy użycie obrazu w miejscu iframe na początku. Czy to możliwe rozwiązanie? – jjbskir

+0

@jjbskir, hmm, mógłbym użyć obrazu z niestandardowym przyciskiem odtwarzania i zamienić wideo i obraz po kliknięciu na ng-show, ale jeśli użytkownik wstrzyma wideo, nie będzie mógł ponownie machnąć palcem. Również nie wiem, czy można uruchomić wideo za pomocą przycisku niestandardowego;) – akn

Odpowiedz

2

Oto dość hackowaty sposób obejścia: użycie dwóch nakładek divs, ustawionych po prawej stronie i po lewej stronie odtwarzacza umożliwia użytkownikowi odtwarzanie i wstrzymywanie, a ustawienie wysokości na 80% pozwala m, aby użyć menu na dole. To nie jest doskonałe, ale to działa!

Uwaga 1: To trochę buggy jeśli odtworzyć go tutaj, więc jestem dodanie codepen:http://codepen.io/anon/pen/LGjwYZ

druga wersja, trochę bardziej nadęty, ale z większym zasięgiem obszar: http://codepen.io/anon/pen/rxzXxB

Uwaga 2: Użyłem przezroczystego tła na elementach div do celów demonstracyjnych.

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

Dzięki. Jeśli nikt nie napisze lepszej odpowiedzi, zaakceptuję to. – akn

+0

Zaktualizowana o bardziej przesadzoną wersję. –

2

Kwestia jest taka, że ​​nie masz kontroli nad wydarzeniami w ramach iframe, więc nie można powiedzieć, kiedy użytkownik przejeżdża nad tym obszarem. Proponowana praca polega na zastąpieniu elementu iframe zastępczym obrazem bez oglądania. W tym celu użyj YouTube's Iframe API, aby śledzić zdarzenia wideo. Gdy wideo przejdzie z odtwarzania do pauzy, ukryjemy wideo i pokażemy obraz. 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

Na inicjacji ukrywa film. Po kliknięciu obrazu pojawia się i odtwarza wideo. Gdy wideo przechodzi z trybu pauzy, aby odtworzyć onPlayerStateChange obsługuje przełączanie obrazu i wideo. Za każdym razem, gdy zdarzenie przesuwania zostanie wywołane na obrazie, wyzwala także obsługę zdarzeń kliknięcia dla obrazu. Zmienna swiping śledzi, czy wydarzenie było tylko kliknięciem, czy też przesunięciem.

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'; 
    } 
}