はじめに

IEのモーダル画面でダイアログの横幅とbodyの横幅を同じにしていると、縦スクロールバーが出た時にスクロールバーに幅をとられて、横スクロールバーまで表示されてしまう。
横スクロールバーが表示されるだけならまだしも、中央位置がずれることで画面左側が切れてしまうことも。

これを解決するには、常に縦スクロールバーを表示して、縦スクロールバーの幅分のスペースを確保するという選択肢もあるが、今回は画面に表示する内容を(ディスプレイの大きさが許す限り)スクロールバーなしで表示できるように自動的にモーダルダイアログのサイズを変更できるようにする。
解像度の低いPCユーザや拡大表示しているユーザにも対応できる。

通常であれば、画面のサイズを動的に変更するのはWebブラウザではユーザビリティの観点等からNGだが、業務システムでモーダルダイアログを表示するという要件であれば、サイズが動的に変わってもユーザビリティは損なわれない。

方法

親画面

やることは特になし。dialogWidth、dialogHeightは適当に指定してOK。

window.showModalDialog(url, this, "dialogWidth=780px; dialogHeight=850px; scroll=yes; resizable=no;");

子画面

JavaScriptで内容の縦横のサイズを取得して、dialogWidthdialogHeightを書き換える。
x = document.documentElement.scrollWidth - document.documentElement.clientWidthであとどれだけ幅を増やせばスクロールバーを消せるかを計算できる。

// モーダルダイアログのサイズを決定する
function decideDialogSize() {
    // 内容が占める幅、高さ
    var scrollWidth = document.documentElement.scrollWidth;
    var scrollHeight = document.documentElement.scrollHeight;
    // 画面のサイズを内容に合わせる。
    window.dialogWidth = scrollWidth + "px";
    window.dialogHeight = scrollHeight + "px";
    // 縦スクロールバーが出ていれば横幅を拡張するように試みる。
    var yScrollSize = document.documentElement.scrollWidth - document.documentElement.clientWidth;
    window.dialogWidth = scrollWidth + yScrollSize + "px";
    // 横スクロールバーが出ていれば縦幅を拡張するように試みる。
    var xScrollSize = document.documentElement.scrollHeight - document.documentElement.clientHeight;
    window.dialogHeight = scrollHeight + xScrollSize + "px";

    // 画面サイズがディスプレイを上回った時のために、表示位置を左上に固定する。
    window.scroll(0, 0);
}

もしモーダル画面ではなくwindow.openで開いている子画面であれば、window.dialogWidthではなくwindow.resizeBy(x, y)で動的に画面を変更することができる。

なお幅、高さを取得するのに使用しているプロパティと関連プロパティは以下の通り。

プロパティ 説明
offsetWidth
offsetHeight
width(またはheight) + padding + borderを返す。
clientWidth
clientHeight
width(またはheight) + paddingを返す。要素の内容を表示する領域の幅と高さ。
scrollWidth
scrollHeight
width(またはheight) + paddingを返す。画面上に表示されていない要素の内容も含む幅と高さを返す。
要素の内容がスクロールバーを生成しなければ、scrollプロパティは、 clientのプロパティ値と同じ。

参考

http://stackoverflow.com/questions/21064101/understanding-offsetwidth-clientwidth-scrollwidth-and-height-respectively
http://it-memorandum.seesaa.net/article/190143841.html
http://kaelab.ranadesign.com/blog/2010/10/javascript-5.html