Skip to content

MS_WebBrowsers

nishi_74322014 edited this page Sep 12, 2026 · 4 revisions

IE、WWWブラウザのいろいろ

補足(本ページ全体の位置付け): 本ページは
Internet Explorer を業務システムの標準ブラウザとして使っていた時代
知見をまとめたものである。

IE 11 は 2022 年 6 月 15 日にサポートを終了し、
現在は Microsoft Edge に置き換わっている
(Windows 10/11 では IE 起動時に Edge へリダイレクトされる)。
したがって、以下の記述のうち
IE 固有の独自仕様に依存する部分は、現在そのままでは使えない

ただし、既存の業務システムを保守・移行する立場では
**「なぜそう作られているのか」**を理解する必要があるため、
記録としての価値は残る。
移行にあたっては Edge の IE モード
(Chromium ベースの Edge 内で Trident エンジンを使う互換機能。
現時点で 2029 年までのサポートが表明されている)が
移行期間を稼ぐ手段となる。

各節では、現在どうなっているかを都度補足する。

バージョン間の問題

問題事例は殆どが、バージョン間の動作の違いに起因します。

  • バージョン間の動作の違い、
  • それに起因する問題

については、「IEバージョンアップ情報」を参照下さい。

HTMLの確認

使ってみよう! [F12] IE9 開発者ツール\

こちらで、

  • HTML のデバッグ
  • JavaScript のデバッグ

が可能です

HTML を確認するには、[F12] で[F12 開発者ツール]を起動し、
メニューの[表示]→[ソース]→[元の形式]で HTML が確認できます。

補足: 「元の形式」(サーバから受信した生の HTML)と
「DOM ツリー」(JavaScript 実行後の状態)を
区別して見るという点は、現在の開発者ツールでも同じである。

見たいもの 現在の Edge/Chrome
サーバが返した HTML [ネットワーク]タブの応答、または Ctrl+U(ソース表示)
JavaScript 実行後の状態 [要素]タブ

「ソースには無いのに画面に出ている」「その逆」という
現象の切り分けは、この 2 つの差を見ることから始まる。

HTTPデバッグ

ブラウザでの動作を分析する際には、HTTP デバッグが必須になるので、
以下を参考にして、HTTP のログを取得分析ください(キャッシュ関連の動作など)。

キャッシュ(戻る)

キャッシュの動作

キャッシュの動作は以下に示すように複雑ですので、
必要に応じて都度 HTTP デバッグ・プロキシを使用して
HTTP デバッグするのが良いかと思います。

  • 浏览器静态资源的版本控制新思路.
    强制更新指定资源缓存.的探讨 - Franky - 博客园
    http://www.cnblogs.com/_franky/archive/2012/07/05/2577141.html

    ↓ Google 翻訳で翻訳

  • 静的リソースブラウザのバージョンについて
    の議論は、新しいアイデアを制御します。
    指定されたリソースのキャッシュを強制的に更新する。

また、システムがキャッシュの動作に翻弄されてしまう場合は、
システム的にはサーバサイドでなんとかすると良いかと思います。

  • クロス・ブラウザで、各ブラウザの使用を理解して・・・
  • パッチなどで動作が変わり得るクライアント・ブラウザの仕様に合わせて・・・

プログラムを作成するという発想が間違いかと思います。

移行メモ(体裁): 原典の「各ブラウザの使用をを理解して」は
「を」が重複していたため修正した。
また、Google 翻訳を経由する長い URL は
翻訳結果へのリンクであり原典の URL と重複するため省いた
(原文の URL は上に残してある)。

補足(この主張は現在の定石そのもの): 「ブラウザの仕様に合わせるのではなく
サーバサイドで制御する」という結論は、
現在のフロントエンド開発における標準的な手法と一致している。

具体的には、

手段 内容
キャッシュ バスティング ファイル名にハッシュを含める(app.3f2a91.js)。内容が変われば URL が変わるので、キャッシュの問題が原理的に起きない
Cache-Control の明示 静的資産は immutable で長期、HTML は no-cache
ETag / Last-Modified 条件付き要求で差分のみ取得

ポイントは、「キャッシュを消させる」のではなく
**「別物として扱わせる」**という発想の転換である。
ブラウザやパッチの挙動に依存しないため、確実に動く。

戻る操作

設計思想の異なる、2 つのインターネット・バンキングを参考にすると良いかと思います。

  • 三菱東京 UFJ 銀行
    二重送信やバックサブミットを不正操作に倒す方式で、
    (開発者・技術者にとっては)解り易いのですが、
  • みずほ銀行
    ブラウザの「戻る」ボタンで発生するリクエストも
    (恐らくフラグなどを使用して)理解して処理しているようです。
    #なので、ブラウザの「戻る」ボタンで、業務トップに戻るなどの動作をします。

後者の方がユーザフレンドリですが、当然ですがメリット・デメリットがあります。

補足(この 2 方式の本質的な違い): 「戻る」問題の根本は、
HTTP がステートレスであるのに対し、業務は状態を持つことにある。
ブラウザの「戻る」はサーバに何も伝えずに過去の画面を復元するため、
サーバ側の状態と画面が食い違う。

方式 実装 長所 短所
A. 不正操作として弾く ワンタイム トークン(PRG パターン+画面トークン)。不一致ならエラー 実装が単純、二重送信も同時に防げる ユーザにはエラー画面が出る
B. 状態を理解して誘導する 遷移状態をサーバで管理し、妥当な画面にリダイレクト ユーザに優しい 全画面の遷移状態を管理する必要があり、状態遷移の設計・試験が重い

実務では A が既定である。
B は状態管理の実装量と考慮漏れのリスクが大きく、
金融機関のように投資できる場合の選択肢と言える。

なお、いずれの方式でも
二重送信対策(PRG パターン+トークン)は必須である。
ここを省くと「戻る → 再送信」で二重登録が発生する。

デザイン

DPIと単位

長さ(length) の単位 - Web 標準普及プロジェクト
http://www.mozilla.gr.jp/standards/webtips0027.html

このように絶対単位はディスプレイで表示する場合、読み手が適切な設定を行っていないと
正しい物理長は計算できないため、絶対単位という名前から受けるイメージとは違い、
実際の表示は環境に大きく依存してしまいます。

DPI

環境:ディスプレイの設定。

  • dpi - Wikipedia
    http://ja.wikipedia.org/wiki/Dpi

    dots per inch の略で、ドット密度の単位である。
    1 インチ(1 平方インチではない)の幅の中にどれだけのドットを表現できるかを表す。
    なお、dpi で表したドット密度の数値を、単に dpi と呼ぶことがある。

設定方法については下記参照のこと。

Windows 8 では、解像度の高い環境では、
自動的に『すべての項目のサイズを変更する』の設定が
『中(125%)』などに変更されることがあるようです。

これにより、下記にもある、
スクロールバーの幅
が変更され、問題となることがあります。

単位

WEB 作成の豆知識 - 単位について -
http://www.web-mame.net/css_course/css_size.html

  • px : 画面の 1 ピクセルの長さを表す単位
  • em : 文字の高さを 1em とした単位
  • ex : 小文字の「x」の高さを 1ex とした単位
  • in : インチ
  • pt : ポイント(1/72 インチ)
  • pc : パイカ(12 ポイント)
  • cm : センチメートル
  • mm : ミリメートル
  • % : 相対的なサイズ指定

補足(現在の指針): 引用にあるとおり、
Web における絶対単位は絶対ではない
現在は次のように使い分けるのが標準的である。

単位 使いどころ
rem 既定のフォント サイズ基準。ユーザのブラウザ設定を尊重できるため、フォントや余白の第一選択
em 親要素基準。コンポーネント内部の相対指定
px ボーダーなど、拡大縮小してほしくないもの
% / vw / vh レイアウトの相対指定
pt / cm / mm / in 印刷用スタイル(@media print)のみ

rem が推奨されるのは、
アクセシビリティの観点で
ユーザが文字サイズを大きくした際に追随できるためである
px 固定だと追随しない)。

また、本文が指摘する DPI 問題は、現在は
CSS ピクセル(論理ピクセル)とデバイス ピクセル
ブラウザが分離することで扱われている
devicePixelRatio。高 DPI 環境では 2.0 等になる)。
高 DPI 対応は srcset や SVG を使う。

表示拡大率

デフォルトの設定

  • 前回ブラウザ終了時の拡大率を使用し、表示します。
  • ただし、以下の場合は指定の拡大率を使用します。
    • 明示的にページ側で拡大率を設定した場合
    • ThirdParty の add-on により各サイトの拡大率を設定した場合

拡大率の設定方法

[インターネットオプション]-[詳細設定タブ]
 -[ユーザ補助]-[新しいウィンドウとタブの拡大レベルをリセット]
をオンにするとすべてのページで 100% で表示されるようになる。

ページから制御する方法としては、
あまりお勧めできませんが、以下のような方法があります。

  • zoom 属性を利用した方法
    • IE のみの独自仕様であり、バージョンによっても挙動が異なる
      との報告がありますので、安易に利用することは推奨しません。
    • Web ページに拡大/縮小機能をつける(IE 専用)
      http://www.h-fj.com/blog/archives/2005/04/21-115524.php
  • screen.deviceDPI による方法

補足: zoom は長らく IE の独自拡張だったが、
その後 WebKit / Blink 系も実装し、
2024 年に CSS 標準(CSS Viewport Module)に採り入れられた
現在は主要ブラウザで利用できる。

ただし、ユーザが設定した拡大率をページ側が上書きするのは
アクセシビリティ上望ましくない
という原典の指摘は、
現在でも(むしろ以前より強く)妥当である。
レイアウト崩れを拡大率で誤魔化すのではなく、
レスポンシブに作るのが正しい解決である。

自動調整

拡大率はディスプレイの設定にも依存する。

[コントロールパネル]-[ディスプレイ]-[画面上の文字を読みやすくします]

最近の解像度の高いディスプレイだと、文字が小さく読みづらいため、
見た目上の文字のサイズを大きくする設定となっている。

移行メモ(体裁): 原典の「読みずらい」は「読みづらい」の
誤りであるため修正した。

スクロールバーの幅、ボーダ幅

ブラウザによってスクロールバーの幅、ボーダ幅が異なる。

ブラウザの表示領域幅 その2 - hedgehog's blog
http://d.hatena.ne.jp/iDrop/20070608/1181273594

IE は Windows OS のテーマが「Windows XP」の場合と、「Windows Classic」の場合とで、スクロールバーのデザインが大きく異なり、それはスクロールバー幅やボーダー幅にも影響を及ぼしています。Firefox と Opera については、テーマの違いによるスクロールバーのデザインの変化は一見ありませんが、やはり各値に微妙な差異が生じています。

横スクロールバー表示問題

ただし、overflow-xoverflow-y は IE のみの独自拡張なので、
IE 以外のブラウザでは横スクロールバーが出てしまう。

以下のようなケースもあるようですので、基本的には、
クロスブラウザでもサイズが足りるように余裕を持たすのが良いようです。

  • ブラウザ幅を超えた部分を隠す手法として body { overflow-x:hidden; }
    あまり使わない方がいい気がする件 - JeffreyFrancesco.org
    http://jeffreyfrancesco.org/weblog/2011050801

    例えば Mac のマルチタッチトラックパッドで 2 本指スクロールが有効な場合、うっかり斜め方向にスワイプしてしまったがために、スクロールした瞬間にコンテンツが消滅したように見えてしまう(実際にははみ出た部分が見えてしまうのですが、スクロールバーが無いのでずれたのかどうかよく分からない)という現象が Safari では時たま発生してしまいます(発生しない事もあるのでこれがまたよく分からない)その他の Firefox や Opera ではそこまで酷い事にはなりませんが、どちらにせよ斜め方向にスワイプしてしまった場合には横側方向にもズレてしまう事に変わりありませんです。

  • IE で overflow hidden が効かない - GEKKO CREATORS
    http://gekko-inc.co.jp/gekko_creators/2011/10/css-tips1.php

    IE は子要素に【position:relative;】を指定している場合、親要素の【overflow:hidden;】が効かなくようで、親ボックスにも【position:relative】いれると IE でも正常に表示されるようです。

  • ???のブログ 消えない縦スクロール - livedoor Blog(ブログ)
    http://blog.livedoor.jp/papi1963/archives/442568.html

    しかしこれをやると縦スクロールバーは "必ず" 出なくなるが、そのために横スクロールバーが必要な状況になっても横スクロールバーもでなくなる。つまり、右端は明らかにちょんぎれた状態だが、スクロールバーがでないためスクロールさせてみることができない。そこで、overflow-y:auto とするとスクロールバーが不要のときは表示しないが、横方向がきつくなると、スクロールバーを表示しようとするが、「なぜか」縦スクロールバーを表示し、横スクロールバーも「なぜか」ウィンドウの下端ではなく 1 つ上がった中途半端な位置にでてくる。ちなみに overflow-y なしのデフォルトでは常に縦スクロールバーがあり、横スクロールバーは必要な状況となるとウィンドウ下端のまっとうな位置にでてくる。

移行メモ(最新化): 「overflow-xoverflow-y は IE のみの独自拡張」という
記述は執筆当時のものであり、現在はCSS 標準として
全ての主要ブラウザが対応している。

補足(横スクロールバーが出る原因のほとんどは 2 つ): 「横幅は足りているはずなのに
横スクロールバーが出る」現象は、現在では原因がほぼ特定できる。

原因 対策
box-sizing の既定値 幅 100% の要素に padding / border を足すと 100% を超える。box-sizing: border-box を全体に適用する
margin のはみ出し 負のマージン、または子要素の絶対配置
100vw の罠 vw縦スクロールバーの幅を含むため、縦スクロールがあると必ず横に溢れる。100% を使う

したがって、現在の定石は
overflow-x:hidden で隠すのではなく、

*, *::before, *::after { box-sizing: border-box; }

を最初に置き、溢れさせないことである。
原典が「隠すな、余裕を持たせろ」と結論しているのと
方向性は同じである。

なお、犯人の特定には開発者ツールで
「幅がビューポートを超えている要素」を探すのが早い。

ブラウザで表示されるフォント

ブラウザで表示されるフォントが異なるケースの対応について。

CSS の font-family:ヒラギノとMS Pゴシックとメイリオの悩ましい関係
http://loconet.web2.jp/blog/archives/2007/02/cssfontfamily.html

  • CSS などで「正しく」「フォント名」を指定する。
    • 「書体の総称」ではブラウザ毎に解釈が変わる事がある。
    • フォント名でも適切に指定しないと、環境によっては正しく解釈されない。
  • 環境依存もあるので注意する。
    • 第一候補のフォントが環境にインストールされていない場合
    • 同じフォント名でも、書体が違うケースがある。
      • Vista の新 MS フォントのうちの 168 文字は、改正後 JIS X0213 に基づいたデザインとなった。
      • Windows XP に標準搭載されている MS 明朝・MS ゴシックのバージョンは 2.3(V2.3)
      • Vista に標準搭載される MS 明朝・MS ゴシックのバージョンは 5.0(V5.0)

補足(JIS2004 問題): 本文が挙げる「168 文字」は、
**JIS2004(JIS X 0213:2004)**による字形変更を指す。
「祇」「逗」「辻」などの字形が変わったもので、
同じ文字コードなのに OS によって字形が違うという
厄介な問題を生んだ。

業務システムでは、帳票の字形が変わることが
問題になる場合がある(氏名の表記など)。
対策としては、

  • JIS2004 対応/非対応を明示したフォントを配布する
    MS 明朝 に対する MS 明朝(JIS2004) 等)
  • 帳票は PDF 化してフォントを埋め込む

といった手段が採られる。

なお、現在は Web フォント@font-face)により、
クライアント環境に依存せず字形を固定できる
業務システムで字形の同一性が要求される場合、
これが最も確実な解決策である
(ライセンスの確認は必要)。

IE n 互換モード

モードの節を参照。

IEイベント

F1抑止

onhelp イベントで抑止します。

<!-- onhelpイベントを無効にする。-->
<script language="javascript" for="document" event="onhelp">
 event.returnValue = false;
</script>

秘文 AE WebGuard の IE アドオンが有効の場合は、
上記イベント抑止が機能しないことがあるようです。

「×」ボタン抑止

今の所、出来ないという結論

技術的問題

IE のクローズ処理をハンドリングする - 開発思考実験日記
http://d.hatena.ne.jp/dotnetmemo/20070125/1169742909

  • JavaScript(onbeforeunload)を使用した方法は抜けが多いため推奨はしない。
    • 更新ボタンを押しても Close だと判断してしまう問題がある。
    • event.clientX を使用して「×」ボタンを識別する方法もあるが、
      • ワイドディスプレイなどで、動作が変わる事がある。
      • JavaScript の Event.clientX プロパティの値が子画面の有無で変わる
        http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=46012&forum=7
      • event.clientX をもっと厳密に調べるアイデア(あまり推奨できる方法が無い)
        ●「File->close」や「Alt-F4」には対応できないようだ。
        ●「×」ボタンの付近で F5 押しても誤った認識をしてしまう。
    • 色々なイベントで入ってきて、且つ区別ができない。
  • Win32、ActiveX 系

要件的問題

要件自体に問題があるとも考えられる。

  • そもそも Web のコンテンツがホストのブラウザを制御する
    と言う発想にリテラシ(セキュリティ)的な問題がある。
  • 従って、いざお金を出すと言う所で「要件がオカシイ」と気が付くため、
    IE のクローズ処理を制御する旧製品なども販売不振であった。
  • また、その操作性(IE の × 系抑止)が、基本的に実現できるものと、
    お客に思われてしまうのもあまり良くないのではないか?と思います。
    例えば、onbeforeunload で実現したものが全社的に適用された後、
    抜けを直して欲しいなどの要求が増えてくると難しくなってきます。

補足(この「要件的問題」の指摘が本ページで最も重要): 技術的に不可能な要求に対し、
なぜ不可能であるべきなのかまで踏み込んでいる点に価値がある。

ブラウザはユーザのエージェント(user agent、代理人)であり、
ユーザの意思で閉じる・戻る・別のページへ行く操作を
サイト側が奪えないのは、バグではなく設計思想である。
もしこれが可能なら、悪意あるサイトが
ブラウザを閉じさせない、戻らせない、といった
攻撃が成立してしまう。

そして実際、ブラウザ側の制限は年々強化されている

挙動 現在
onbeforeunload の確認メッセージ カスタム文言は表示されない(ブラウザ標準の文言に固定)
ユーザ操作なしでの onbeforeunload 発火 無視される(ユーザがページを操作していない場合)
window.close() スクリプトで開いたウィンドウ以外は閉じられない
ポップアップ ユーザ操作を起点としない限りブロック

したがって、この種の要件が出た場合の正しい対応は、
実装方法を探すことではなく
「離脱されても業務が破綻しない設計」に要件を translate することである。
具体的には、

  • 途中離脱を前提にサーバ側で状態を持つ(下書き保存)
  • 二重処理はトークンで弾く(前掲の「戻る操作」)
  • セッションはタイムアウトで自然に切れる設計にする

ログオフ、Sessionクリア

  • JavaScript(onbeforeunload)中で Submit するように実装しますが、上記と同様に困難。
  • なお、onunload では unload 後になるので、サブミットされません(以下、HP を参照)。
  • Session タイムアウトを短めに設定し、タイマーで定期的にリクエストを送り
    ユーザが画面を開いている間は、Session タイムアウトさせない方式も採れます。
    • Open棟梁には、ユーザ操作中の Session タイムアウトを防ぐため、
      Web サーバへ一定期間毎に PING を行う HttpPing() メソッドが用意されています。

補足(現在の手段): 離脱時にサーバへ通知したい場合、
現在は navigator.sendBeacon() が用意されている。

window.addEventListener('pagehide', function () {
  navigator.sendBeacon('/api/logoff', JSON.stringify({ id: sid }));
});

sendBeacon非同期でページの遷移をブロックせず
ブラウザがバックグラウンドで送信を完了させる。
従来 onbeforeunload で同期 XHR を投げていた用途を置き換えるものである。

ただし、送信は保証されない(電源断、クラッシュ、
モバイルでのプロセス終了)。
したがって、原典が挙げる
**「Session タイムアウトで自然に切る」**という考え方が
依然として本筋であり、sendBeacon
「送れたら早く解放できる」という補助と位置付けるべきである。

なお、unload / beforeunload
モバイル ブラウザで発火しないことがあるため、
現在は pagehide / visibilitychange を使うのが推奨される。

画面サイズ拡大・縮小の制御

Ctrl +「+」(画面サイズ拡大)および
Ctrl +「-」(画面サイズ縮小)は JavaScript で抑止できない。

  • 動作検証を行ってみたところ、
    onkeydownonkeypress イベントが
    発生するよりも先に拡大縮小が行われています。
  • 拡大縮小を抑止はできないようですが、WB.ExecWB(ActiveX コントロール)
    にて拡大縮小後に元に戻すことが可能であるかもしれません。

移行メモ(体裁): 上記マイクロソフト コミュニティの URL は
日本語を含む極端に長いものであったため、フォーラムまでのパスに短縮した。

補足: 拡大縮小はブラウザ(ユーザ エージェント)の機能であり、
ページのスクリプトより先に処理される
これも前節と同じく、仕様どおりに抑止できないものである。
拡大しても崩れないよう、レスポンシブに作るのが解決策になる。

Select Boxの切替前確認

実装方法

以下で実現可能の様です。

JavaScript SELECT BOX の OnChange をキャンセルする - MyMemoWiki
http://typea.info/tips/wiki.cgi

  • onbeforeactivate イベントで設定を記憶しておき、

    onbeforeactivate = "this.previouse_selected_value=this.value;";
  • onchange イベントで切替前確認を表示します。
    onchange イベントで false を返すと、変更をクリアできます。

    onchange="if(window.confirm(message)){}else{this.value=this.previouse_selected_value;return false;};"
  • なお、

    • onbeforeactivate イベント
    • previouse_selected_value プロパティ

    は IE 限定のようなので、他のブラウザでは、
    onloadonchange イベントで変更前の値を記憶する必要があります。

補足: 本文が末尾で述べているとおり、
onfocus(または onload)で直前の値を保持しておき、
onchange で必要なら戻す
という方式が、
IE 以外を含めた標準的な実装である。

sel.addEventListener('focus', function () { this.dataset.prev = this.value; });
sel.addEventListener('change', function () {
  if (!window.confirm('変更しますか?')) { this.value = this.dataset.prev; }
});

なお、previouse_selected_value
「IE 限定のプロパティ」ではなく、
IE が任意のプロパティを DOM 要素に付けられたことによる
独自の書き方である。
現在は datasetdata-* 属性)を使うのが作法にかなう。

ASP.NETのDropDownList

AutoPostBack="True" 設定時、onchangedoPostBack が仕掛けられます。
これにより、onchange イベントに以下の JavaScript が仕掛けられます。

onchange="javascript:setTimeout(
 '__doPostBack(\'ctl00$ddlMDropDownList1\',\'\')', 0)"

これも、onchange イベントで false を返すと、変更をクリアできます。

サンプル

全イベントの抑止サンプルは、Open棟梁付属の JavaScript に同梱しています。
https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/CS/Samples/WebApp_sample/WebForms_Sample/WebForms_Sample/Scripts/touryo/ie_key_event.js

モード

キオスク モード

概要

本来、多用途に利用できる汎用コンピュータやタブレットを、
専用端末のように、ひとつの用途のみ利用するモード。

参考

補足(キオスク モードは前節の要件への「正しい答え」): 前掲の
「×ボタンを押させたくない」「拡大縮小させたくない」という要件は、
Web ページ側では実現できないが、
端末側の構成としてなら実現できる

手段 内容
Edge のキオスク モード 全画面固定、指定 URL のみ、アドレス バー無し、一定時間で初期化
割り当てられたアクセス(Windows) 特定アプリのみ実行できるアカウント
Intune / グループ ポリシー 上記を組織全体に配布

つまり、要件を「アプリの制約」から「端末の構成」に移すことで、
技術的にも管理的にも正しく解決できる。
業務端末が特定用途に固定できる場合には、こちらを検討すべきである。

IE n 互換モード

IEバージョンアップ情報を参照。

モーダルダイアログ全般

モーダルダイアログのサポート状況

IEバージョンアップ情報を参照。

モーダルダイアログでポストバック

モーダルダイアログ window でポストバックすると、別 window が表示される。

対応方法

下記の方法がある。

  • <base> タグに _self を指定する

    <head runat="server">
     <base target="_self"></base>
    </head>

    ただし、JavaScript で

    • 子画面側でフォーカス移動ができなくなった。
    • 子画面から親画面側のダイアログを動作できなくなった。

    などの問題が報告されている。

  • FRAMESET、FRAME の踏み台を経由する。

    <HTML>
     <HEAD>
      <TITLE></TITLE>
     </HEAD>
     <FRAMESET rows="*" frameborder="0" border="0" framespacing="0">
      <FRAME id="frameDialog" name="frameDialog" src="実際の子フォーム.aspx" noresize scrolling="no" frameborder=0>
     </FRAMESET>
    </HTML>

    ちなみに Open棟梁のモーダルダイアログ表示機能では、こちらの方法を採用している。
    但しこの機能には 1 点問題があり、IE 以外では src に指定した画面から
    showModalDialog の引数(vArguments)が取得できず、動作しないことがある。

  • window.open() でモーダル化

    // 戻り値の子画面オブジェクトを取得
    var subwin = window.open(page, null, param);
    
    // 子画面の表示状況を確認する関数
    function chkSubWin() {
     if(subwin != null && subwin != "") {
      // 子画面が閉じたか否か
      var ret = subwin.closed;
      // 子画面が閉じてない場合は子画面にフォーカス
      if(ret == false) {
       subwin.focus();
      }
     }
    }

注意

  • IE9 から、上記方法ではダイアログサイズ指定が反映されなくなった
    IEバージョンアップ情報)。
    このため、互換モードを使用してこの問題を凌いでいた。
  • しかし、昨今、この互換モードが問題となるケースが増えてきた。
    このため、互換モードを使用しないようにする場合、FRAMESET を IFRAME 化する必要がある。
  • ただし、IFRAME 内のコンテンツから showModalDialog の戻り値が戻らなくなるので、
    cookie 等を使用して IFRAME 内のコンテンツから戻り値を戻すように処理を変更する必要がある。

補足(showModalDialog は廃止された): window.showModalDialog
IE の独自仕様であり、標準化されなかった。

ブラウザ 状況
Chrome 2015 年に削除
Firefox 2016 年に削除
IE 11 更新プログラムで既定無効化(レジストリで復活可)
Edge (Chromium) 存在しない

廃止された理由は、呼び出し元のスクリプト実行を同期的にブロックするという
仕組みそのものにある。
ブラウザのイベント ループを止めるため、
タブのプロセス分離やレンダリングの最適化と両立しなかった。

現在の代替は、別ウィンドウではなく画面内のモーダルである。

【旧】showModalDialog で別ウィンドウを開き、閉じるまで待つ(同期)
【現】<dialog> 要素 / オーバーレイ div を表示し、
      結果は コールバック / Promise で受け取る(非同期)

HTML 標準の <dialog> 要素showModal())は
主要ブラウザで利用でき、

  • フォーカス トラップ(背後の要素に移らない)
  • Esc キーでの閉じる
  • 背景のスクリム表示

を標準で備える。
本節の「親ウィンドウが触れてしまう」問題も、<dialog> では発生しない
(背後の要素が inert 扱いになるため)。

既存システムの移行では、
同期呼び出しを非同期(コールバック/Promise)に書き換える必要があり、
呼び出し元のコード構造にまで影響が及ぶ点が最大の作業量になる。

親ウィンドウが触れてしまう。

WWW ブラウザのダイアログ(showModalDialog)は、OS レベルのダイアログではないので、
稀にブラウザのバグに起因し、親画面が触れる現象の報告がある(バグ情報が見つかり次第報告)。

  • e.g.
    Spy++ を使用して確認可能。
    • メモ帳のバージョン情報
      • クラス名:#32770(ダイアログ)
      • クラス スタイル:CS_DBLCLKS
    • IE のダイアログ(showModalDialog
      • クラス名:Internet Explorer_TridentDlgFrame
      • クラス スタイル:CS_DBLCLKS

補足(この調査手法自体が示唆に富む): Spy++ でウィンドウ クラス名を比べ、
#32770(Win32 の標準ダイアログ クラス)ではないことを確認する、という
アプローチが、そのまま原因の説明になっている点が優れている。

  • OS のモーダル ダイアログは、ウィンドウ マネージャが
    親ウィンドウへの入力を止める(OS が保証する)。
  • showModalDialogブラウザが自前で
    親ウィンドウの入力を止めている(アプリが頑張っている)。

したがって、ブラウザ側の実装に不具合があれば
親が触れてしまうことがある、という因果になる。
「モーダルに見えるが、OS が保証しているわけではない」という理解が要点である。

ちなみに、この性質は前掲の <dialog> でも同様で、
あくまでブラウザ内での制約である
(その代わり実装がブラウザ標準になったため、
独自実装より信頼できる)。

参考情報

描画の問題

settimeout化

javascript - IE9 Alert() now blocks range.select from displaying selected text - Stack Overflow
http://stackoverflow.com/questions/13021294/ie9-alert-now-blocks-range-select-from-displaying-selected-text

IE のバージョンが変更され、

  • 描画タイミング
  • JavaScript の実行タイミング

が変わって、問題となるケースがあるようです。

対応方法としては、setTimeout 化が挙げられますが、

  • IE6 側の動作を変えてしまう。
  • IE9 側も厳密には意図する動作に合わせられない。

ため、機械的に setTimeout 化すれば良いという訳ではない様です。

補足(setTimeout(fn, 0) が効く理屈と、その限界): setTimeout(fn, 0)
「0 ミリ秒後に実行」ではなく、
**「今の処理を最後まで終わらせてから実行」**という意味を持つ。

【同期実行】 DOM変更 → alert()           …描画が追いつかないまま止まる
【setTimeout化】 DOM変更 → (一旦処理を返す=描画される) → alert()

JavaScript はシングル スレッドで、
実行中は描画が行われない
setTimeout はタスクを一旦キューに戻すため、
その隙にブラウザが描画できる、という仕組みである。

ただし原典が指摘するとおり、確実ではない
「いつ描画されるか」はブラウザの実装依存だからである。

現在は、描画タイミングを狙う場合
requestAnimationFrame() を使うのが正しい
(次の描画の直前に確実に呼ばれる)。
また、マイクロタスク(Promise)と
マクロタスク(setTimeout)の
実行順序の違いも理解しておく必要がある。

とはいえ、タイミング依存の実装そのものが脆いという
原典の指摘(「機械的に setTimeout 化すれば良いという訳ではない」)が
最も本質的であり、可能なら
状態変化を明示的に待つ設計に改めるのが望ましい。

ActiveX

Win7、IE9、VBCOMの問題

IEバージョンアップ情報を参照。

補足(ActiveX は終了した): Edge (Chromium) は ActiveX を一切サポートしない
ActiveX に依存する画面は、Edge の IE モードでのみ動作する。

業務システムでの主な用途は次のとおりで、それぞれ代替がある。

旧用途 現在の代替
ファイルの一括アップロード <input type="file" multiple>、Drag & Drop API
ローカル ファイルの読み書き File System Access API(対応ブラウザ限定)、ダウンロード
印刷制御 サーバ側で PDF を生成
ICカード・生体認証 WebAuthnFIDO
帳票・グラフ描画 Canvas / SVG、サーバ生成

IE モードのサポートにも期限があるため、
ActiveX 依存の解消は移行計画の必須項目となる。

参考

ダウンロード全般

ダウンロードのいろいろ

IE:タブのプロセス分割

IEバージョンアップ情報を参照。

IE10で"__doPostBack" 実行エラー

IEバージョンアップ情報を参照。

WWWブラウザ - .NET 開発基盤部会 Wiki


Tags: 移行, その他、開発の色々

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally