2016-01-12 60 views
10

我正在嘗試使用圖像和YouTube視頻構建滑塊。我想讓它在觸摸設備上正常工作,所以我想使用來自angular的ngTouch模塊的ng-swipe-*。不幸的是,滑動並不適用於youtube的iframe。我試圖設置較低的z-index: -10;,但後來我無法播放視頻。使用YouTube iframe進行角度劃像掃描

你有什麼想法如何解決這個問題?

有一個片段:

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>

(以測試它的最好辦法,就是在Chrome開發者控制檯運行它,並模擬觸摸屏設備上)

+1

這似乎是同一個問題 - http://stackoverflow.com/questions/28180672/youtube-cannot-swipe-past-iframe-in-carousel-slider - 他們推薦使用代替圖像的iframe的開始。這是一個可行的解決方案嗎? – jjbskir

+0

@jjbskir,嗯,我可以使用自定義播放按鈕的圖像,並用ng-show單擊替換視頻和圖像,但如果用戶暫停視頻,他將無法再次滑動。另外我不知道是否可以用自定義按鈕啓動視頻;) – akn

回答

2

這裏有一個漂亮的hacky解決方法:使用兩個疊加div,設置在播放器的右側和左側,允許用戶播放和暫停,並將高度設置爲80% m使用底部的菜單。這不是完美的,但它有用!

注1:這是一種越野車的,如果你在這裏玩,所以我加入了codepen:http://codepen.io/anon/pen/LGjwYZ

第二個版本,一點點臃腫但越區覆蓋:http://codepen.io/anon/pen/rxzXxB

注2:爲了演示目的,我在div上使用了透明背景。

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

謝謝。如果沒有人發佈更好的答案,我會接受這一個。 – akn

+0

更新了一個更誇張的版本。 –

2

的問題是,你沒有在iframe中事件的控制,所以當用戶刷過該區域不能告訴。我建議的解決方法是在不觀看的情況下用圖像佔位符替換iframe。爲了做到這一點,請使用YouTube's Iframe API來跟蹤視頻事件。當視頻從播放停止時,我們將隱藏視頻並顯示圖像。 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

在啓動它隱藏的視頻。當圖像被點擊時,它顯示並播放視頻。當視頻從暫停播放onPlayerStateChange處理切換圖像和視頻。每次在圖像上調用滑動事件時,它也會觸發圖像的單擊事件處理程序。變量swiping會記錄事件是否只是點擊或滑動。

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