目的
- 前回同じタイトルでFireFox版を書きました。
- 今回はChrome版でもできたっぽいのでその備忘録です。
- Win/MacのFireFox/Chromeで確認しました。
それでは早速コードを。
コード
{main.html}
...
bootstrapを使っています。
...
<iframe id="ifrm" src="https://hogehoge/ifrm_canvas.html" width="650" height="518" scrolling="no" frameborder="0"></iframe>
...
{main.js}
const ifrm = document.getElementById("ifrm");
// iframeをフォーカスする関数
function focus_ifrm () {
ifrm.focus();
// iframeの中のJavascript関数を読む
ifrm.contentWindow.ifrm_focus();
}
//読み込み直後にiframeをフォーカスする
window.addEventListener('DOMContentLoaded', function () {
ifrm.contentWindow.addEventListener('load', function () {
focus_ifrm();
},false);
説明
-
main.js
のポイントは次です。- 親のHTML
main.html
と子HTMLifrm_canvas.html
の両方で.focus()する
- 親のHTML
-
子のHTMLのフォーカスは子のJavaScriptの関数を呼び出して
.focus()
します。それに可能にするのが.contentWindow.関数名()
です -
HTML読み込み直後にフォーカスするために、
.addEventListener('load',...)
でiframe読み込み終了を待ちました。
{infrm_canvas.html}
<body>
<canvas width="624" height="500" id="canvas" ></canvas>
<script src="/js/ifrm_canvas.js"></script>
</body>
{inflame_canvas.js}
const canvas = window.document.getElementById("canvas");
// フォーカスされたかどうかで枠線の色を変える
function ifrm_focus() {
canvas.style="outline: 2px solid red";
document.body.focus();
}
function ifrm_blur() {
canvas.style="outline: 2px solid gray";
document.body.blur();
}
...
document.addEventListener("focus", ifrm_focus, true);
document.addEventListener("blur", ifrm_blur, true);
説明
- iframeで読み込まれる側で枠表示とfocus()される関数を用意しておきます。
- focusを外れると枠の色を変えて、blur()される関数も用意しました。
- focusイベントで呼ばれる関数で親から呼ばれた時に自分自身をfocusする不思議なコード
document.body.focus();
になってしまいました。
備考
- ChromeはセキュリティがFireFoxと考え方が違うのでインプリのポリシーが違うのかもしれません。
- もともとの目的はcanvasに描かれた背景画像に対してクリックしたりその画像のアノテーションするためにキー入力出来るようにすることでした。
- しかしBootstrap4でcanvas描画をレシポンシブル対応するとクリック位置の読み込みと打点座標がずれてしまいました。それを解決するためにiframeに描画することでズレを直したのですが、今度は親と子のHTML間のfocus()のやり取りがFireFoxではOKなのにChromeではできないとなってしましました。
- このブラウザの互換性はひと昔に戻ったみたいで、なかなか難しかったというわけです。
- これでキー入力が想定外など
alert()
を出してもfocusを制御できます(はずです)。 - まずは動いていそうだというレベルなのでまだ不具合があるかもしれません。こうしたら良いよとかありましたら教えていただけると勉強になります。
- 自分向けの備忘録に書きましたがどなたかの参考になりましたら望外の喜びでございます。