質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

5748閲覧

clickイベントをclickがなかったときも発火させたい

wkh0413

総合スコア20

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2016/07/26 07:18

###前提・実現したいこと
Androidでは、clickイベントはユーザーのアクションがないと発火しないようですが、clickされなかったときも発火させたいです。擬似的にclickがあったということにできる方法はないでしょうか。

###発生している問題・エラーメッセージ
動画を2つ連続で再生させたいのですが、動画を再生するときに、play()を使っています。
clickが無くても1つ目の動画が終了したら、2つ目の動画を再生したいです。
しかし、Androidで実行したときにデバッグしてみたら、play()はユーザーのアクションがないと実行されないということでした。

DOMException: play() can only be initiated by a user gesture.

###該当のソースコード

Javascript

1var Video = function(url) { 2 var thisObj = this; 3 this.url = url; 4 this.video = $('<video>').hide(); 5 this.video.attr('src',url); 6}; 7 8Video.prototype.loadVideo = function(){ 9 this.video.get(0).load(); 10}; 11 12Video.prototype.playVideo = function(){ 13 this.video.get(0).play(); 14}; 15

###試したこと
jQueryの.trigger()を使ってみましたが、同様のエラーが表示されました。
clickイベントを無理矢理発火させる方向で考えていますが、それ以外に良い方法があれば教えていただけるとありがたいです。

###補足情報(言語/FW/ツール等のバージョンなど)
Videoは動画を再生させるための変数です。
Javascript、HTML5を使用しています。
videoタグを使って再生させています。
ブラウザはChromeを使用しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asahina_dev

2016/07/26 07:49

ブラウザのセキュリティを回避する方法は基本ない(あっても次期バージョンアップで塞がれる)ので リロード+オートプレイ等で擬似的に対応したほうがいいです。
wkh0413

2016/07/26 08:22

ありがとうございます。 やはり、自動再生をするのは難しいのですね。 リロードすると、その先に実現したいことができないので、別の方法を探してみます。
glapd332

2016/07/31 12:01 編集

連続再生、ということは、例えばa,bの動画があったとして、 aの再生後にbを再生する、ということでよろしいでしょうか。
wkh0413

2016/07/31 12:03

glapd332さんのおっしゃる通り、連続再生は、a,bの動画があったとき、aを再生終了後bを再生させることです。 また、aの動画はユーザーが画面(動画領域)をクリックすることで.play()を実行させています。 情報が不足していて申し訳ありません。
guest

回答1

0

ベストアンサー

PC版GoogleChromeで確認しました。
この実装は強引?です。ただ疑似化とかはしてません。
単にイベント伝番を使っているだけです。

まず初めにコードを載せておきます。

Javascript

1var addListener = document.body.addEventListener ? 2 function (target, eventType, handler) { 3 target.addEventListener(eventType, handler, false); 4 } : 5 function (target, eventType, handler) { 6 target.attachEvent('on'+eventType, handler); 7 }; 8 9var removeListener = document.body.removeEventListener ? 10 function (target, eventType, handler) { 11 target.removeEventListener(eventType, handler, false); 12 } : 13 function (target, eventType, handler) { 14 target.detachEvent('on'+eventType, handler); 15 }; 16 17/** 18 * ビデオクラス 19 * @param url 動画のurl 20 * @author glapd332 21 * @version 2016.07.31 22 */ 23var Video = (function() { 24 function Video(url) { 25 this.url = null; 26 this.video = null; 27 this.initialize(url); 28 }; 29 30 Video.prototype.initialize = function(url) { 31 var video = document.createElement('video'); 32 video.src = url; 33 this.video = video; 34 this.url = url; 35 // 直接<body>に追加しています。 36 // もしほかの要素に追加したいなら、 37 // 要素(document.getElement系で取得したもの).appendChild(this.video); 38 // としてください。 39 document.body.appendChild(this.video); 40 }; 41 42 Video.prototype.play = function() { 43 this.video.play(); 44 }; 45 46 Video.prototype.pause = function() { 47 this.video.pause(); 48 }; 49 50 Video.prototype.stop = function() { 51 this.video.pause(); 52 this.video.currentTime = 0; 53 }; 54 55 /** 56 * @param eventType イベントタイプ(例)load, clickなど 57 * @param handler イベント発火時に伴う処理 58 */ 59 Video.prototype.setEvent = function(eventType, handler) { 60 this.video.addListener(eventType, handler, false); 61 }; 62 63 return Video; 64}()); 65 66var video1 = new Video("mv/sample.mp4"); 67var video2 = new Video("mv/sample.mp4"); 68var isVideo1Running = false; 69 70video1.setEvent('click', function() { 71 if ( isVideo1Running === false ) { 72 video1.play(); 73 isVideo1Running = true; 74 return; 75 }; 76 video1.pause(); 77 isVideo1Running = false; 78}); 79 80video1.setEvent('loadeddata', function() { 81 video1.play(); 82 isVideo1Running = true; 83}); 84 85video1.setEvent('ended', function() { 86 video2.play(); 87}); 88

解説

簡単にまとめると、今回必要なことは、

  1. 自動再生
  2. 連続再生

の2つです。
それぞれ、videoのイベントハンドラで表現できます。

クロスブラウザ対策

まず初めに、今回はイベントを多用するのでクロスブラウザを意識して、

Javascript

1var addListener = document.body.addEventListener ? 2 function (target, eventType, handler) { 3 target.addEventListener(eventType, handler, false); 4 } : 5 function (target, eventType, handler) { 6 target.attachEvent('on'+eventType, handler); 7 }; 8 9var removeListener = document.body.removeEventListener ? 10 function (target, eventType, handler) { 11 target.removeEventListener(eventType, handler, false); 12 } : 13 function (target, eventType, handler) { 14 target.detachEvent('on'+eventType, handler); 15 };

と記述します。
これは、IEとその他ブラウザでのイベントの設定の仕方が異なるのを吸収するためのものです。
あえて三項演算子で戻している理由としては、何度も
"addEventListenerが使えるかな?それともattachEventかな?"
と調べると、結果的にDOMに何度もアクセスすることになり、
パフォーマンスが落ちるのでそれを防ぐためです。

Videoクラス

Javascript

1var Video = (function() { 2 function Video(url) { 3 this.url = null; 4 this.video = null; 5 this.initialize(url); 6 }; 7 8 Video.prototype.initialize = function(url) { 9 var video = document.createElement('video'); 10 video.src = url; 11 this.video = video; 12 this.url = url; 13 document.body.appendChild(this.video); 14 }; 15 16 Video.prototype.play = function() { 17 this.video.play(); 18 }; 19 20 Video.prototype.pause = function() { 21 this.video.pause(); 22 }; 23 24 Video.prototype.stop = function() { 25 this.video.pause(); 26 this.video.currentTime = 0; 27 }; 28 29 Video.prototype.setEvent = function(eventType, handler) { 30 this.video.addListener(eventType, handler, false); 31 }; 32 33 return Video; 34}());

単に拡張性に優れていること、すっきりとする、という理由から使用しています。
(本来はDOMと処理を切り離すべきですが...)

Javascript

1document.body.appendChild(this.video);

直接bodyに追加していますので、bodyでなく
あるdivにしたい場合は書き換えてください。

処理

Javascript

1var video1 = new Video("mv/sample.mp4"); 2var video2 = new Video("mv/sample.mp4"); 3var isVideo1Running = false; 4 5video1.setEvent('click', function() { 6 if ( isVideo1Running === false ) { 7 video1.play(); 8 isVideo1Running = true; 9 return; 10 }; 11 video1.pause(); 12 isVideo1Running = false; 13}); 14 15video1.setEvent('loadeddata', function() { 16 video1.play(); 17 isVideo1Running = true; 18}); 19 20video1.setEvent('ended', function() { 21 video2.play(); 22}); 23

まず動画を2つ、video1, video2用意します。

Javascript

1var video1 = new Video("mv/sample.mp4"); 2var video2 = new Video("mv/sample.mp4");

今回は、どちらも"mv/sample.mp4"であるとします。
また、

Javascript

1var isVideo1Running = false;

というフラグをたてておきます。
動画が再生されているかの判別用です。
trueなら再生、falseなら停止されているということを表現します。

処理>>再生/一時停止

Javascript

1video1.setEvent('click', function() { 2 if ( isVideo1Running === false ) { 3 video1.play(); 4 isVideo1Running = true; 5 return; 6 }; 7 video1.pause(); 8 isVideo1Running = false; 9});

単に、一時停止と再生をするためです。
先ほどのフラグで判別します。
もちろんこちらをクリックして再生することもできます。
質問者様の現在の実行の仕方もできます。

処理>>自動実行

Javascript

1video1.setEvent('loadeddata', function() { 2 video1.play(); 3 isVideo1Running = true; 4});

自動実行のキモです。でも3行。クラスのおかげです。
ここで、自動実行します。
なぜできるのか?それは動画が読み込まれると同時にVideoクラスの.play()が自動発火されるからです。ではVideoクラスのvideo要素のplay()が実行されるのは?ということの答えは、
...すいません。よくわかりません。おそらくイベント伝番的な何かだと思います。
調べておきます。

処理>>連続再生

Javascript

1video1.setEvent('ended', function() { 2 video2.play(); 3});

これは、video1の再生の終了後に発行される'ended'イベントを使っています。
これで連続再生が可能なはずです。

結論

以上でおそらく...実行できると思います。
一応GoogleChromeのスマホデバッグ機能で試して動くので良いと思って解答しましたが...、
なにせ私は携帯を持っていないので、実際には違った動きをするかもしれません。
なお、GoogleChromeのデバック機能のスマホの、
GalaxyS5, Nexus5s, Nexus6P, iPhone5, iPhone6, iPhone6Plus, iPad
での動作を確認しています。

追記

wkh0413様、私こそ、質問文をろくに読まずに質問をしてしまって申し訳ありません。
また、該当のソースコードをわざわざ書いていただいたのにもかかわらず、
別の書き方で実装してしまい、申し訳ありません。

投稿2016/07/31 13:09

編集2016/08/01 04:04
glapd332

総合スコア75

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wkh0413

2016/08/01 03:28

glapd332様 丁寧なご回答ありがとうございます。ロード終了を一つのアクションとしてplay()を実行させるという発想はありませんでした。大変勉強になります。また、クロスブラウザのことまで考慮できていなかったので、その点も非常に勉強になります。 ソースコードですが、別の書き方で実装してくださったおかげで、新たに必要なこと(クロスブラウザなど)や、自分の書き方との差異についても知るきっかけになったので、むしろありがたいです。 スマホで実装してみます!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問