「サブウインドウ化ボタン」のツールチップ表示
プレーヤー右下部の「ワイド表示」「フルスクリーン」ボタンの列に「サブウインドウ」ボタンを配置したのは正解だったと思いますが、ボタンの機能を説明するツールチップが欲しくなりました。
下は「フルスクリーン」ボタンをポイントした時に表示されるツールチップです。
「サブウインドウ」ボタンにツールチップの表示要素を追加し、こちらでスタイルを指定して「:fover」で表示させることは可能ですが、デフォルトのプレーヤーのツールチップ関連の要素の「クラス名」を、こちらで生成した要素にも付与する方法を採りました。
この方法は、スタイル指定のJavaScriptの仕事を軽減し、負荷の節約になります。 また、簡単に揃った同じツールチップのデザインが得られます。
ただし、クラス名を共通にしたこちらの要素に、デフォルトのスクリプトが機能しないかだけは、チェックが必須です。 クラス名を借りたボタンを押すと、借りた側のボタンも動作したら困りますから。 今回は、全く無問題でした。
実際のコードのやりくり
クラス名を借りたのは「フルスクリーン」のボタンです。 DevToolsで調べると、このボタンの要素(ボタンの子要素を含む)には以下のスタイルが付与されています。
ボタンデザインもそれなりに文字数を要します。 これらを指定する「styleタグ」の埋め込みが不要になるのですから、クラス名の利用はとても有効です。
で、ボタンを生成する際に、デフォルトの「フルスクリーン」ボタンのHTML構成に似せた構造を生成して、上記で使われているクラス名を付与します。 別方法で、デフォルトのボタンのクローンを生成して、必要な部分のみ改造する事も出来ますが、この場合は却ってコードが複雑になるので、前者の方法を採りました。
下は、今回の「サブウインドウ」ボタンの生成コードです。
AmbTV Comfy ver. 0.4 94行以降
前半は生成するHTML要素のコードで、「button要素」の中にツールチップ自体や矢印デザインを作る要素がネストされています。
後半は、ボタンデザインの「styleタグ」です。「フルスクリーン」ボタンは「svg」アイコンですが、「サブウインドウ」ボタンは Windows絵文字を利用しています。 「:fullscreen .atv_sw { display: none; }」のコードは、フルスクリー表示の時に、「サブウインドウ」ボタンを非表示にするコードです。
ver. 0.3 のこの部分を書き変えただけですが、「AmbTV Comfy」が生成した「サブウインドウ」ボタンに下の様なツールチップを表示出来ました。
ツールチップを表示する事で、ユーザーはヘルプなしで操作が理解できます。
なお、「フルスクリーン」のショートカット「F」キーは、使い始めると便利です。 「サブウインドウ」のショートカット実装を考えましたが、「Shift + F」が既に「ワイド表示」に設定され、「Ctrl+F」はブラウザ標準の「検索」のショートカットで、良い空きがありません。
「サブウインドウ」は、他のウインドウを開いて操作している場合があり、下手なショートカットは誤操作になり得るので、このショートカット設定は控えました。
「AmbTV Comfy」を利用するには
このツールは Chrome / Edge / Firefox版の拡張機能「Tampermonkey」上で動作します。 以下に、このツールの導入手順を簡単に説明します。
❶「Tampermonkey」を導入します
◎ 使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。
既に「Tampermonkey」を導入している場合は、この手順 ❶ は不要です。
拡張機能の導入については、以下のページに簡単な説明があるので参照ください。
❷「Tampermonkey」にスクリプトを登録します
◎「Tampermonkey」の「+」マークの「新規スクリプト」タブを開きます。
◎「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。
〔コピー方法〕 軽量シンプルなツール「PreBox Button 」を使うと
コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」
の操作で、掲載コードのコピーが可能になります。
◎ 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。
〔 AmbTV Comfy 〕 ver. 0.4
// ==UserScript== // @name AmbTV Comfy // @namespace http://tampermonkey.net/ // @version 0.4 // @description AbemaTV ユーティリティ // @author Ameba User // @match https://abema.tv/* // @icon https://www.google.com/s2/favicons?sz=64&domain=abema.tv // @grant none // ==/UserScript== main(); let target=document.querySelector('head > title'); let monitor=new MutationObserver(main); monitor.observe(target, { childList: true }); function main(){ let style= '<style class="atv_style">'+ '.c-common-HeaderContainer-header, '+ '.c-application-SideNavigation, '+ '.c-application-SideNavigation--collapsed, '+ '.com-vod-VODRecommendedContentsContainerView__player-aside-recommended '+ '{ display: none; } '+ '.c-video-EpisodeContainerView-breadcrumb, '+ '.com-vod-VODRecommendedContentsContainerView__details, '+ '.com-vod-VODRecommendedContentsContainerView__episode-list, '+ '.com-feature-area-FeatureRecommendedArea__section, '+ '.c-video-EpisodeContainerView__page-bottom, '+ '.c-application-FooterContainer '+ '{ display: none; } '+ '.c-application-DesktopAppContainer__content-container '+ '{ align-items: center; height: 100vh; } '+ '.com-vod-VODResponsiveMainContent '+ '{ margin: 0 !important; padding: 0 !important; } '+ '.com-vod-VODRecommendedContentsContainerView__player-and-details '+ '{ margin-right: 0 !important; } '+ '.com-vod-VODRecommendedContentsContainerView__player '+ '{ margin: 0 6px !important; } '+ '.c-application-DesktopAppContainer__content '+ '{ min-width: 400px !important; } '+ '.com-vod-VODResponsiveMainContent '+ '{ --com-vod-VODResponsiveMainContent--content-min-width: 400 !important; } '+ '.com-vod-VODResponsiveMainContent__container { overflow: hidden; } '+ '</style>'+ '<style class="atv_style_basic">'+ '.com-vod-VODScreen-container { background: #000 !important; }'+ '</style>'; if(!document.querySelector('.atv_style')){ document.body.insertAdjacentHTML('beforeend', style); let atv_style=document.querySelector('.atv_style'); if(atv_style){ atv_style.disabled=true; }} let retry=0; let interval=setInterval(wait_target, 20); function wait_target(){ retry++; if(retry>100){ // リトライ制限 100回 2secまで clearInterval(interval); } let player=document.querySelector( '.com-vod-VODRecommendedContentsContainerView__player'); if(player){ clearInterval(interval); set_player(player); }} function set_player(player){ let wrap=player.querySelector('.c-vod-EpisodePlayerContainer-wrapper'); if(wrap){ let monitor1=new MutationObserver(play); monitor1.observe(wrap, { childList: true }); } setTimeout(()=>{ let wrap_tv=player.querySelector('.c-tv-TimeshiftPlayerContainerView'); if(wrap_tv){ let monitor2=new MutationObserver(play); monitor2.observe(wrap_tv, { childList: true }); } }, 1000); } function play(){ let nav_b=document.querySelector( '.com-vod-VideoControlBar__playback-rate'); if(nav_b){ let sw= '<button type="button" class="atv_sw com-vod-FullscreenButton">'+ '<div class="com-vod-FullscreenButton__tooltip">'+ '<div class="atv_tp com-a-Tooltip com-a-Tooltip--arrow-position-center">'+ '</div></div>'+ '<span class="atv_icon">🔳</span></button>'+ '<style>.atv_icon { padding: 0 0 2px; '+ 'filter: drop-shadow(2px 2px 0 #fff); } '+ ':fullscreen .atv_sw { display: none; }</style>'; if(!document.querySelector('.atv_sw')){ nav_b.insertAdjacentHTML('afterend', sw); } let atv_sw=document.querySelector('.atv_sw'); let atv_style=document.querySelector('.atv_style'); let atv_tp=document.querySelector('.atv_tp'); if(atv_sw && atv_style && atv_tp){ if(atv_style.disabled==false){ atv_tp.textContent='デフォルト表示'; } else{ atv_tp.textContent='サブウインドウ表示'; } atv_sw.onclick=function(e){ e.preventDefault(); if(atv_style.disabled==false){ atv_style.disabled=true; atv_tp.textContent='サブウインドウ表示'; } else{ atv_style.disabled=false; atv_tp.textContent='デフォルト表示'; } }}}} // play() } // main() catch_click(); function catch_click(){ // 動画のサムネイルの暗転拡大表示 let html_=document.querySelector('html'); box_env(); document.addEventListener('contextmenu', function(event){ if(!event.shiftKey && !event.ctrlKey){ event.preventDefault(); let elem=document.elementFromPoint(event.clientX, event.clientY); let link_elem=elem.closest('a'); if(link_elem){ set_link(link_elem); set_img(link_elem); close(); }}}); function box_env(){ let lightbox= '<div id="lightbox">'+ '<div id="photo_sw"><a id="photo_link">🎦 Movie Page</a></div>'+ '<img id="box_img">'+ '<style>'+ '@keyframes fadeIn { 0% {opacity: 0} 100% {opacity: 1}} '+ '.fin { animation: fadeIn .5s ease 0s 1 normal; animation-fill-mode: both; } '+ '@keyframes fadeOut { 0% {opacity: 1} 100% {opacity: 0}} '+ '.fout { animation: fadeOut .2s ease 0s 1 normal; animation-fill-mode: both; } '+ '#lightbox { position: fixed; top: 0; left: 0; z-index: 3000; visibility: hidden; '+ 'background: black; width: 100vw; height: 100vh; text-align: center; } '+ '#photo_sw { position: absolute; width: 100%; height: 15%; } '+ '#photo_sw:hover #photo_link { opacity: 1; } '+ '#photo_link { font: bold 21px Meiryo; position: absolute; top: 20px; left: 30px; '+ 'padding: 4px 12px 2px 10px; color: #000; background: #fff; cursor: pointer; '+ 'border: 2px solid #000; border-radius: 6px; text-decoration: none; opacity: 0; } '+ '#box_img { width: 100vw; height: 100vh; padding: 2vh 2vw; '+ 'object-fit: contain; } '+ '</style></div>'; if(!document.querySelector('#lightbox')){ document.body.insertAdjacentHTML('beforeend', lightbox); }} function set_link(target){ let photo_link=document.querySelector('#photo_link'); if(photo_link){ let url=target.getAttribute('href'); if(url){ photo_link.setAttribute('href', url); } photo_link.onclick=function(event){ event.stopImmediatePropagation(); }}} function set_img(target){ let lightbox=document.querySelector('#lightbox'); let box_img=lightbox.querySelector('#box_img'); let img=target.querySelector('img'); if(lightbox && box_img && img){ let img_url=img.getAttribute('src').replace(/%3Fversion%.*$/,""); if(img_url){ box_img.src=img_url; html_.style.overflow='hidden'; lightbox.style.visibility='visible'; lightbox.classList.remove('fout'); lightbox.classList.add('fin'); }}} function close(){ let html_=document.querySelector('html'); let lightbox=document.querySelector('#lightbox'); let box_img=lightbox.querySelector('#box_img'); if(lightbox){ lightbox.onclick=function(event){ event.preventDefault(); html_.style.overflow='inherit'; lightbox.classList.remove('fin'); lightbox.classList.add('fout'); setTimeout(()=>{ lightbox.style.visibility='hidden'; box_img.src=''; }, 200); }}} } // catch_click()
「AmbTV Comfy」最新版について
旧いバージョンの JavaScriptツールは、Abemaサイトのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。
●「AmbTV Comfy」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。