Windowオブジェクト

Windowオブジェクトは、JavaScriptコードが動作しているWebブラウザのウィンドウまたはフレームを表します。

クライアントサイドJavaScript オブジェクト

Webブラウザで実行されるJavaScriptは、クライアントサイドJavaScriptと呼ばれます。

  • Windowオブジェクト … ドキュメントを表示するウィンドウ
  • Documentオブジェクト … HTMLドキュメント

グローバル変数 (global variable)

クライアントサイドJavaScriptでは、Windowオブジェクトはグローバル オブジェクトです。そしてすべてのグローバル変数は、Windowオブジェクトのプロパティとなります。

つまり、

var a = 0;

とグローバル変数を定義することと、

window.a = 0;

とすることは同義です。

メソッド

print

window.print();

moveBy、moveTo (ウィンドウの移動)

セキュリティ上の制約から、ブラウザによっては移動できないことがあります。

resizeBy、resizeTo (ウィンドウのサイズの変更)

セキュリティ上の制約から、ブラウザによってはサイズを変更できないことがあります。

ウィンドウのオープンとクローズ

open

このメソッドは、ポップアップ ブロックにより阻止されることがあります。

var win = window.open(
    url,          // ウィンドウで開くURL
    name          // ウィンドウの名前
    [, features ] // ウィンドウのサイズと制御機能
    );
window.open - Web API リファレンス | MDN

urlで異なるホストのページを指定した場合、そのプロパティにアクセスすると「Permission denied to access property 'XX'」のように例外が発生します。

name'_blank'か空文字とすると、追加でopen()を呼び出したとき新しいウィンドウで開かれます。これを同じウィンドウで表示されるようにするには、固有の名前を指定します。

featuresで、ウィンドウのサイズや機能を指定します。これを指定しないときは、ウィンドウはすべての機能を持ちます。一方で特定の機能を指定したときは、その機能のみを持ちます。

  • featuresを未指定 … ウィンドウは、すべての機能を持つ
  • featuresを指定 … ウィンドウは、指定された機能だけを持つ

設定はfeature[=value]の書式で行います。yesかnoで指定する項目ではvalueは省略でき、そのときはyes (機能を有効) とみなされます。

複数の項目は'height=300,centerscreen,resizable'のようにカンマ区切りで指定できます。そのとき空白を含めてはなりません。

featuresの設定は、ブラウザによってサポートされない項目があります。Examples - Window.open - Web API Interfaces | MDN

featuresの項目の一部
項目 説明 設定値
left ウィンドウのX座標 数値
top ウィンドウのY座標 数値
width ウィンドウのドキュメント表示領域の幅 数値
height ウィンドウのドキュメント表示領域の高さ 数値
centerscreen yesのとき、親ウィンドウの中央に表示 yes、no
menubar yesのとき、メニューバーを表示 yes、no
toolbar yesのとき、ナビゲーションツールバーとタブバーを表示 yes、no
location yesのとき、ロケーションバーを表示 yes、no
     
位置とサイズの特性 - window.open - Web API リファレンス | MDN Position and size features - window.open - Web API reference | MDN

戻り値のwinには、新しく開かれたウィンドウ (Windowオブジェクト) が返されます。

実行例

次のコードの実行例を確認できます。

window.open(
    'https://www.yahoo.co.jp/',
    'sample',
    'height=300,centerscreen,resizable' )
ここをクリックすると、ウィンドウが開きます。
ポップアップ ブロック (Pop-up Blocker)

ユーザーの操作によらずウィンドウを開こうとすると、ポップアップとしてブロックされることがあります。また同時に複数のウィンドウを開くことも、ブラウザによってはブロックされます。

ポップアップ ブロック時のメッセージ

IE9

Firefox 14

ブロックを回避するには、onclickまたはonmousedownイベントハンドラ内で処理するようにします。

link.onclick = function()
{
    window.open();
    return false;
}
ロード完了の捕捉 (onload)
link.onclick = function()
{
    var win = window.open();
    win.onload = function()
    {
        alert( this.document.title );
    }
    win.location = '/';

    return false;
}

ここをクリックすると新しいウィンドウを開き、そのページのタイトルをダイアログに表示します。※一部のブラウザでしか機能しません。

onloadイベントによる方法は一部のブラウザでしか機能しないため、より汎用的には次の方法を用います。

開かれたウィンドウからロード完了を通知する

ウィンドウを開いた側からでは、ウィンドウが開かれたことを確実に捕捉できないため、開かれた側からそれを通知するようにします。

ウィンドウを開く側
var win;

link.onclick = function()
{
    win = window.open( 'sample.html' );
    return false;
}

// 開かれた側のウィンドウから呼ばれる関数
function Foo( text )
{
    alert( text );

    win.close();
}
ウィンドウを開かれる側
window.onload = function()
{
    if( window.opener )
    {
        // このウィンドウを開いたウィンドウの関数を呼び出す
        window.opener.Foo( now );
    }
}

ここをクリックすると新しいウィンドウを開き、そのウィンドウから返される情報を下に表示します。そして、そのウィンドウを閉じます。

close

window.close();
window.close - Web API インターフェイス | MDN

このメソッドで閉じることができるのは、open()で開いたウィンドウのみです。

くり返しや遅延実行

遅延実行

ダイアログボックスの表示 (alertなど)

メソッド 説明 実行例
alert ダイアログボックスに簡単なメッセージを表示する
window.alert - Web API インターフェイス | MDN
confirm ダイアログボックスで確認を求める
window.confirm - Web API インターフェイス | MDN
prompt ダイアログボックスで文字列の入力を求める
window.prompt - Web API インターフェイス | MDN

alert()などで表示するメッセージ内では制御コードが解釈されるため、「\n」で改行「\t」でタブを表示できます。

ダイアログ表示の抑止への対処

FirefoxChromeでは同一内容のダイアログをくり返し表示すると、そのページ内での以降のダイアログを無効にする機能が提供されています。

このダイアログが表示されたとき「このページによる追加のダイアログ表示を抑止する (Prevent this page from creating additional dialogs)」にチェックを入れられると、それ以降のalert()、confirm()、prompt()の呼び出しではダイアログが表示されなくなります。

このときChromeでは、それぞれ戻り値が

  • alert() … undefined
  • confirm() … false
  • prompt() … null

となり、confirm()がtrueの場合の処理は行われなず、prompt()では何も入力を得られなくなります。一方でFirefoxでは「Exception... "Component is not available" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)"」の例外が発生するため、これを捕捉しなければプログラムが停止します。633154 – Suppressing alert boxes leads to NS_ERROR_NOT_AVAILABLE

よってFirefoxにも対応させるには、alert()などをtryブロックで囲み例外を捕捉する必要があります。

try
{
    window.alert( 'SAMPLE' );
}
catch( e )
{
}

ドキュメントのスクロール

メソッド 機能
scrollTo 絶対量でのスクロール
window.scrollTo(x-coord, y-coord)
window.scrollTo - Web API インターフェイス | MDN
scrollBy 相対量でのスクロール
window.scrollBy(X, Y);
window.scrollBy - Web API インターフェイス | MDN

スクロールされている位置は、ドキュメントのscrollLeftやscrollTopから取得できます。また上記のメソッドではなく、このプロパティに設定することでもスクロールできます。

ところでドキュメントではなく要素をスクロールさせるには、ElementのscrollLeftやscrollTopプロパティに値を設定します。

特定の要素が表示されるようにスクロール

id属性を持つ要素が表示されるようにドキュメントをスクロールするならば、

location.hash = 'xx';

のように、locationのhashプロパティを指定することでも可能です。

ウィンドウ上で選択されている範囲

getSelection()で、ウィンドウ上で選択されている範囲をSelectionオブジェクトで取得できます。

selection = window.getSelection();
Window.getSelection - Web API Interfaces | MDN

Selectionオブジェクト

Selectionでは、

  • anchor … 選択が開始された点。選択範囲が拡大縮小されても、この点は変更されません。
  • focus … 選択されている範囲の終点

として表されます。

選択されている範囲は、Selection.getRangeAt()によりRangeオブジェクトとして取得できます。選択を無効にするには、Selection.removeAllRanges()を呼び出します。Selection.removeAllRanges() - Web API Interfaces | MDN

たとえば、

<p>ABC<span>DEF</span></p>

で表される要素を、

ABCDEF

のように着色部分を選択すると、Selectionのプロパティでは

  • anchorNode … <TextNode textContent="ABC">
  • anchorOffset … 1
  • focusNode … <TextNode textContent="DEF">
  • focusOffset … 2

となります。なおSelectionのプロパティは読み取り専用であるため、選択範囲を変更するには次項のようにメソッドを呼び出します。

選択範囲の変更

選択範囲の開始点を変更しないならば、Selection.extend()で範囲を拡大縮小できます。開始点も含めて新規に範囲を設定するには、Rangeオブジェクトを作成し、それをSelection.addRange()で範囲に追加します。

たとえば、

<p id="a">ABCDE</p>

の要素のテキスト部分「BCD」を選択するには、次のようにします。

var target = document.getElementById( 'a' );

var range = document.createRange();
range.setStart( target.firstChild, 1 );
range.setEnd( target.firstChild, 4 );

var selection = window.getSelection();
selection.addRange( range );

クロスドメイン通信

otherWindow.postMessage( message, targetOrigin );
window.postMessage - Web API インターフェイス | MDN

otherWindowにmessageを送ります。そのときotherWindowの生成元targetOriginに一致していないと、イベントは伝達されません。第3回 localStorageとpostMessageの使いどころ(2):フロントエンドWeb戦略室|gihyo.jp … 技術評論社 mala (2012/11/01)

プロパティ

Windowオブジェクトはグローバル オブジェクトであるため、プロパティを参照するときにオブジェクト名を省略できます。たとえばwindow.documentへは、documentの記述だけでアクセスできます。

プロパティ 説明
Boolean closed trueのとき、ウィンドウが閉じている
String name ウィンドウの名前
defaultStatus ステータス バーに表示する既定の文字列
status  
Document document ウィンドウやフレームを含むドキュメント
逆にDocumentを表示するWindowsは、document.defaultViewで取得できる
Event event  
History history  
Location location ドキュメントのURL

Documentオブジェクトにもlocationプロパティが存在するが、クロスブラウザの観点からこちらを使用する。

Navigator navigator スクリプトを実行しているアプリケーションの情報
Screen screen 現在のウィンドウがレンダリングされているスクリーンの情報
Window opener 現在のウィンドウを開いたウィンドウへの参照
parent 現在のウィンドウの親ウィンドウへの参照
top ウィンドウ階層の最上位のウィンドへの参照
selt ウィンドウ オブジェクト自身への参照
window 現在のウィンドウへの参照
Window[] frames  
Number innerHeight / innerWidt ブラウザ ウィンドウのコンテンツ領域のサイズ
(メニューバー、ツールバー、スクロールバーのサイズは含まない) Window.innerHeight - Web API Interfaces | MDN
outerHeight / outerWidth ブラウザ ウィンドウのサイズ
(メニューバー、ツールバー、スクロールバーのサイズも含む) window.outerHeight - Web API Interfaces | MDN
pageXOffset / pageYOffset 現在のドキュメントのスクロール量
screenLeft / screenTop スクリーン上でのウィンドウの左上の座標 (IE、Safari、Opera用)
screenX / screenY スクリーン上でのウィンドウの左上の座標 (Firefox、Safari用)
Properties - Window - Web API Interfaces | MDN

ウィンドウへの参照

parent

親となるウィンドウへの参照を取得できます。親が存在しない場合には、それ自身への参照が返されます。window.parent - Web API インターフェイス | MDN

ウィンドウの位置 (screenX、screenY)

IE9より前はscreenX、screenYをサポートしないため、それにも対応させるならば代替を考慮する必要があります。

if( window.screenX )
{
    var x = window.screenX;
    var y = window.screenY;
}
else
{
    // for IE
    var x = window.screenLeft;
    var y = window.screenTop;
}

これをより簡単にまとめると、

var x = window.screenX || window.screenLeft;
var y = window.screenY || window.screenTop;

となります。ただし次に示すように、IEにおいてはscreenLeftとTopは、screenXとYとは異なる座標を表します。よって単純に代替とはなりません。

それぞれのプロパティは、スクリーン座標での位置を返します。

  IE9より前 IE9以降 Firefox Chrome
screenX、Y 未サポート ウィンドウの左上 ウィンドウの左上 ウィンドウの左上
screenLeft、Top ウィンドウのクライアント領域の左上 未サポート

実行例

現在のウィンドウの位置を、下表に示します。

X Y
screenX screenY
screenLeft screenTop
キャッシュを無視してページを更新すると、表示データが更新されます。

ウィンドウのビューポートの大きさ (innerWidth、innerHeight)

IE9より前はinnerWidth、innerHeightをサポートしないため、それにも対応させるならば代替を考慮する必要があります。

if( window.innerWidth )
{
    var width = window.innerWidth;
    var height = window.innerHeight;
}
else
{
    // for IE
    var width = document.documentElement.clientWidth;
    var height = document.documentElement.clientHeight;
}

これをまとめると、

var width = window.innerWidth || document.documentElement.clientWidth;
var height = window.innerHeight || document.documentElement.clientHeight;

となります。

window.innerWidthは、ウィンドウの表示領域のサイズです。一方でdocument.documentElement.clientWidthはHTML要素のサイズを表すため、状況によっては異なる値となることがあります。

要素の大きさ

実行例

現在のウィンドウの表示領域の大きさを、下表に示します。

Width Height
window.innerWidth window.innerHeight
document.documentElement.clientWidth document.documentElement.clientHeight
document.body.clientWidth document.body.clientHeight
※ウィンドウのサイズを変更すると、表示データが更新されます。

ウィンドウのビューポートに合わせた要素の高さの自動調整

<div id="elem1"></div>
<div id="elem2"></div>
<div id="elem3"></div>

<script type="text/javascript">
var params = [
    { id: 'elem1', margin: 100, min: 100 },
    { id: 'elem2', margin: 200, min: 300 },
    { id: 'elem3', margin: 10, min: 0 }
];
</script>

onresizeイベントを捕捉し、そのときのビューポートの高さを元に要素の高さを算出し、それを要素の高さに設定します。

window.onresize = function()
{
    var viewHeight = window.innerHeight || document.documentElement.clientHeight;
    for( var i = 0; i < params.length; i++ )
    {
        var param = params[ i ];
        var height = Math.max( viewHeight - param.margin, param.min );

        document.getElementById( param.id ).style.height = height + 'px';
    }
}
window.onresize();

これのサンプルは、実行例のページで確認できます。

イベント

Event handlers - Window - Web APIs | MDN

参考

参考書

  • JavaScript 第5版 [オライリー・ジャパン] David Flanagan
    14章「ブラウザウィンドウの制御」