2016-01-12 21 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'; 
    } 
}