10

画像とYouTubeビデオを使用して単純なスライダーを作成しようとしています. タッチデバイスでうまく動作させたいのでng-swipe-*、angularのngTouchモジュールから使いたいです。残念ながら、スワイプは YouTube の iframe では機能しません。を低く設定しようとしましz-index: -10;たが、ビデオを再生できません。

この問題を解決する方法はありますか?

スニペットがあります:

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 開発者コンソールで実行し、タッチ デバイスでエミュレートすることです)

4

2 に答える 2

2

これは非常にハックな回避策です: 2 つのオーバーレイ div を使用し、プレーヤーの左右に設定すると、ユーザーは再生と一時停止を行うことができ、高さを 80% に設定すると、下部のメニューを使用できます。これは完璧ではありませんが、ある程度機能します。

注 1: ここで再生するとバグが発生するので、codepen を追加します: http://codepen.io/anon/pen/LGjwYZ

2 番目のバージョン。少し肥大化していますが、より多くのエリアをカバーしています: 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>

于 2016-01-14T20:32:36.103 に答える
2

問題は、iframe 内のイベントを制御できないため、ユーザーがその領域をいつスワイプしたかがわからないことです。私が提案する回避策は、見ないときに iframe を画像プレースホルダーに置き換えることです。これを行うには、YouTube の Iframe APIを使用してビデオ イベントを追跡します。ビデオが再生から一時停止に移行すると、ビデオが非表示になり、画像が表示されます。ここにデモがあります。

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';
    }
}
于 2016-01-14T21:49:43.893 に答える