今回はJavaScript関連の話になります。
Chromeの拡張機能に、自作のJavaScriptやCSSを実行/反映できる「User JavaScript and CSS」というものがあります。
この拡張機能でYouTubeの動画ページをカスタマイズしようと考えたのですが、なかなか難航しましたので、その時の調査結果を備忘録も兼ねてまとめておきたいと思います。
前提として
まず私がやろうとしたことは、Web版YouTubeの動画ページを表示した際に、動画の表示領域を広げる、です。
Web版YouTubeの動画ページは、動画の周りに余白があり、もったいないと思っておりました。余白の部分まで動画の表示領域を広げ、動画を大きく表示したいと考えました。
次に、実現するうえでつまずいた点は
- Elementが取得できないときがある
- 広告が入ると動画の拡大表示が元に戻る
- loadイベントが発火しないときがある
です。
つまずいた点
Elementが取得できないときがある
loadイベントの発火後に「document.getElementById('ytd-player')」を実行してもElementが取得できないことがありました。
どうやら取得処理のタイミングが早すぎるようでしたので、
- setIntervalを使用し、「document.getElementById('ytd-player')」が取得を1秒ごとに繰り返す。
- 所得できたら繰り返しを終了する。
function loopProcess() {
const initInterval = setInterval(() => {
if (document.getElementById('ytd-player') != null)
{
// ここに必要な処理を実装する
clearInterval(initInterval);
}
}, 1000);
}
私は「ここに必要な処理を実装する」と記載した部分に、動画の表示領域を広げる処理を実装しました。
広告が入ると動画の拡大表示が元に戻る
Elementが取得できるようになったので動画の表示領域を広げられたのですが、動画に広告が入ったタイミングで表示領域がもとに戻ってしまいました。
そこでMutationObserverを使用しElementを監視することにしました。
const obConfig = {
childList: true,
subtree: true
};
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
// ここに監視処理と必要な処理を実装する
});
});
const initInterval = setInterval(() => {
if (document.getElementById('ytd-player') != null) {
const obTarget = document.getElementById('ytd-player');
observer.observe(obTarget, obConfig);
clearInterval(initInterval);
}
}, 1000);
こうすることで動画に広告が入っても動画の表示領域がもとに戻ることがなくなりました。
loadイベントが発火しないときがある
初めはloadイベントを起点にElementを取得するということをしていたのですが、そのうちloadイベントが発火するときとしないときがあることに気づきました。具体的には、
- 動画ページで更新ボタンを押したとき
- YouTubeのトップページ以外から動画ページに遷移したとき
は発火するのですが、YouTubeのトップページから動画ページに遷移した際にloadイベントが発火していませんでした。
調べてみるとWeb版YouTubeは独特なつくりをしているようで、トップページから動画ページに遷移してもloadイベントは発火しないとのことでした。対処方法としてtransitionendイベントを使用した内容が紹介されていましたので取り入れました。参考にしたのは「参考:Chrome extension is not loading on browser navigation at YouTube」です。
具体的には以下のようなコードとしました。
function afterNavigate()
{
if ('/watch' === location.pathname)
{
// ここで「広告が入ると動画の拡大表示が元に戻る」の処理を実行する
}
}
document.addEventListener('transitionend', function(event)
{
if (event.target.id === 'progress')
{
afterNavigate();
}
}, true);
afterNavigate();
以上のコードにより、これまでの処理が希望通りのタイミングで実行されるようになりました。
最後に
今回はChromeの拡張機能である「User JavaScript and CSS」で、YouTubeの動画ページの特に動画周りをカスタマイズする際につまずいた点と対処方法をまとめました。
コードは抜粋形式で載せており、動画の拡大方法などは端折りましたが、少しでも参考になれば幸いです。

0件のコメント: