はじめに
こんにちは、スタイル・エッジLABOの┣と申します。
前回の記事より早2年経ち入社3年目になります。
昨年からCSIRTとしてサイバーセキュリティ関連の業務に携わらせていただくようになりました。
そのCSIRTとは関連性の薄い話題ですが、今回は別のシステムの開発中に便利そうなWeb APIを見つけたので2つほどつづらせていただきました。
ブラウザの画面制御など、何かのお役に立てますと幸いですm(_ _)m
Web APIについてざっくりと
今回ご紹介する『Web API』は『ブラウザ API』とも呼ばれ、読んで字のごとくブラウザの機能にアクセスしたり挙動をコントロールしたりするものを指します。
有名なWeb APIとして『XMLHttpRequest』や『File』が挙げられると思いますが、今回は若干マイナー(!?)かつ便利そうなものを挙げさせていただきました。
本題
1. 異なるウィンドウやタブで連携するBroadcastChannel
このWeb APIは、一言で表すと「同一オリジン1のコンテンツを開いているウィンドウやタブ・フレームに対してメッセージを送受信する」といった制御ができるAPIです。
なお、メッセージを送受信するためにはウィンドウやタブ・フレームごとに下記のようなコードでチャンネルを作成/閉設しなければなりません。
// チャンネル作成 const bc = new BroadcastChannel('channel1'); // チャンネル閉設(不要なチャンネルが残り続けるとメモリリークの可能性あり) bc.close();
この特性を利用して、特定のページにのみ「チャンネルを作成/閉設する」という処理を組み込むことで「同一オリジンの中でも特定のページのみ利用する」といった制御もできます。
似たようなWeb APIに『MessageChannel』があります。
ですが、このAPIは1対1でのやり取りに用いるので「不特定多数のウィンドウやタブと連携する」……といった用途だとチャンネル管理が煩雑になりそうです。
(どちらかというと「特定の子フレームと円滑に連携したい」といった用途に向いているものと思っております。)
BroadcastChannelの用途として、「とあるタブの操作により複数の別タブの操作を行う」といったことが考えられます。
そこで、簡単にですが動作検証用に下記のサンプルを用意してみました。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>BroadcastChannelサンプル</title> </head> <body> <div>BroadcastChannelサンプルです</div> <div id="message"></div> <button id="post">テスト</button> <script> // チャンネルを作成 const bc = new BroadcastChannel('channel1'); // メッセージ受信時の処理 bc.addEventListener('message', (e) => { // 受信したメッセージにより処理を振り分け switch (e.data) { case 'alert': alert('test'); break; default: break; }; // 受信したメッセージを表示 document.querySelector('#message').innerText = e.data; }); window.addEventListener('unload', () => { // 不要になったチャンネルは閉じないとメモリーリークの可能性あり bc.close(); }); document.querySelector('#post').addEventListener('click', () => { bc.postMessage('alert'); }); </script> </body> </html>
このHTMLファイルをブラウザで複数開いてどれかのボタンを押すと……
このようにボタンを押さなかったウィンドウ(もしくはタブ)が反応します(∩´∀`)∩
2. サイズ変更を監視して検知するResizeObserver
こちらにつきましては読んで字のごとくですが、「要素のサイズ変更を検知する」といったものです。
「だったらresizeイベントで十分じゃ……?」と思われるかもしれませんが、resizeイベントはウィンドウにしか設定できないのに対し、ResizeObserverはページ内の要素にも適用できるのが大きな利点だと思います。
また、似たようなWeb APIに『MutationObserver』があります。
このAPIは「属性やテキストの変更を検知するか」「子要素の変更も検知するか」……といった細かい設定ができるので、今後使ってみたいと思いますm(_ _)m
こちらも簡単にですがサンプルを用意したので、ご覧いただけますと幸いです。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>ResizeObserverサンプル</title> </head> <body> <div>ResizeObserverサンプルです</div> <textarea id="sample"></textarea> <div id="target" style="background-color: cadetblue;"></div> <script> // 監視対象(textarea)とサイズ変更する要素(div)を取得してResizeObserverに設定 const textarea = document.querySelector('#sample'), target = document.querySelector('#target'), ro = new ResizeObserver(() => { target.style.width = textarea.clientWidth + 'px'; target.style.height = textarea.clientHeight + 'px'; }); ro.observe(textarea); </script> </body> </html>
このHTMLファイルをブラウザで開いて、テキストエリアを大きくすると……
緑色の部分も大きくなりました(∩´∀`)∩
本題は以上となりますm(_ _)m
おわりに
実はこの2つのWeb API、弊社システムのUI改善の一環として取り入れられないか思案しております。
とある機能において、
- システムの他の画面とはウィンドウを分けて独立したアプリっぽく使えるようにしつつ、他の画面と連携して操作をコントロールする
- このウィンドウのサイズを中のUIのサイズによって自動で調整する
といった挙動にできないか検討しているので、正にうってつけだと考えております。
☆スタイル・エッジLABOでは、一緒に働く仲間を募集しています☆
システムの構築・改善に限らず、フロントエンド開発やサイバーセキュリティに関する活動などにも興味をお持ちでしたら、
採用サイト↓も覗いてみてください!
recruit.styleedge-labo.co.jp