0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[ODC]ブラウザバックを禁止できるAPI

Posted at

実際にやりたくなることはあまりないと思うが、ブラウザのバックボタンやショートカットで前のページに戻る操作を禁止できる。
ODCのJavaScript API、Navigationを使う。

環境情報

ODC Studio(Version 1.5.2)

動作確認はMac上のChromeで行った。後述するように、複数回のブラウザバック操作に対する禁止は安定しなかった。

ドキュメント

Navigation - ODC Documentation
2025/01/11時点ではまだ日本語訳がなかった。

ブラウザバック操作時のハンドラを登録するAPI:registerBackNavigationHandler

  1. Client Action内にJavaScript要素を配置
  2. JavaScript要素内にハンドラとなる関数を定義
  3. JavaScript要素内で、$public.Navigation.registerBackNavigationHandlerを読んで、2の関数をハンドラとして登録する

JavaScript要素というのは、以下の「JavaScript1」のような要素。Client Action内に配置して、要素内に記述したJavaScriptのコードを実行できる。
スクリーンショット 2025-01-11 19.42.05.png

注意点

  1. ハンドラは一回実行されると、登録が取り消される。このとき、本来のブラウザバック処理(前のページへ遷移)は行われない
  2. ハンドラは複数登録できる(ブラウザバック処理時は、最後に登録されたハンドラから実行され、登録解除される。つまりスタックされる。ドキュメントにはキューであると書いてあるが、LIFOであるからスタックが正しいと思われる)
  3. registerBackNavigationHandlerは、登録されたハンドラを表すIDを返す(後述)

以下は、alertで数字を表示するだけのハンドラを3つ登録する処理の例。この処理後、ブラウザバックを3回繰り返すと、2 -> 1 -> 0とポップアップ表示され、画面遷移は発生しない。4回目の実行ではブラウザバックが発生する。

.js
for(let i = 0; i < 3; i++)
{
    let handler = () => { alert(`${i}`);}
    $parameters.RegisteredId = $public.Navigation.registerBackNavigationHandler(handler);
}

ハンドラの登録を解除するAPI:unregisterBackNavigationHandler

registerBackNavigationHandler実行時の戻り値(ID)を引数に、$public.Navigation.unregisterBackNavigationHandlerを呼ぶと、そのハンドラの登録を解除できる。

.js
// 登録時にIDを保存しておく
$parameters.RegisteredId = $public.Navigation.registerBackNavigationHandler(handler);
// ...

// 登録時のIDを引数に、unregisterBackNavigationHandlerを呼ぶことで登録を解除できる
$public.Navigation.unregisterBackNavigationHandler($parameters.RegisteredId); 

戻る・進む・画面遷移すべてに対応するハンドラを登録するAPI:registerNavigationHandler

$public.Navigation.registerNavigationHandlerを呼び、イベント発生時に動作させたいハンドラを登録する。

開発者ツールのコンソールタブを使い、argumentsを見て確認したところ、ハンドラの第1引数には遷移先の相対パス、第2引数には何らかの関数が渡ってきた。2025/01/12時点ではドキュメントに記述がないので正体は不明。

スクリーンショット 2025-01-12 13.05.45.png

動作確認したところ、ブラウザの戻る・進む・画面上のリンククリック時には、登録したハンドラが動作した。

.js
function navigationHandler(param) {
    console.log(param);
}

$public.Navigation.registerNavigationHandler(navigationHandler);

永続的にブラウザバックを防ぐのはちょっと難しそう

いろいろ試した限り、一度目のブラウザバック操作時には確実にハンドラが動いてくれるが、二度目以降は、ハンドラ登録方法に関わらずうまく行ったりいかなかったりする。バグだろうか。

必要になったときにもう少し詳しく見ることにする。

うまくいかなかった方法①:ハンドラー内で自分自身をもう一度登録する

ハンドラーが動いたときに、そのハンドラーの登録が解除されてしまう。そこで、ハンドラー内で自分自身を再登録することで、実現できるのではないかと思ったが、うまくいく時といかない時があって使えなさそう。うまくいかない時は、一度ブラウザバックした時はちゃんと止められるのだが、もう一度バックすると普通に画面遷移してしまう。

原因がわからないので、今の所、この方法は取れないかな。

.js
function backNavigationHandler() { 
    $public.Navigation.registerBackNavigationHandler(backNavigationHandler);
    alert("stop");
}
$public.Navigation.registerBackNavigationHandler(backNavigationHandler);

うまくいかなかった方法②:常に複数のハンドラが登録された状態を維持する

↑で書いた、一度に3つのハンドラを登録する処理をボタンに紐づけておく。ブラウザバックを3回繰り返す→ボタンクリック→もう一度ブラウザバックという手順で確認してみた。

この場合も、うまくいく時は想定通り、何度でもハンドラを動作させられる。しかし結構な確率で2回目のブラウザバックが普通に画面遷移してしまう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?