【JavaScript】windows.open()で新規ウィンドウの情報取得やDOM操作をする方法
更新日:2023/02/25
JavaScriptで新規ページを開くときはwindows.open()を使用します。
開いた後に条件が合えば、そのページの情報を取得したり、DOMを操作したりできます。
今回は、その方法をお伝えします。
同一オリジンポリシーの問題
windows.open()を実行すると、新規ウィンドウの window オブジェクトを取得できます。
このオブジェクトを参照することで、新規ウィンドウに表示されたWebページを操作できます。
ただし、windows.open()は同一オリジンポリシーの影響を受けます。
つまり操作するには、操作する側とされる側が同じドメインということが条件になります。
異なるドメインの場合でもwindowオブジェクトを取得できますが、参照すると例外エラーがスローされるため操作ができない仕様になっています。
window.open()
window.open()の構文を簡単に紹介します。
window.open()の構文
window.open( url , target , features )
- url : 表示するWebページのURL
- target : linkタグのtarget属性またはウィンドウ名
適当な名前を付けると、初回に新規で作成されて以降は同じウィンドウで表示できます。
同じウィンドウで表示
window.open( url1 , "aaaWindow"); window.open( url2 , "aaaWindow"); window.open( url3 , "aaaWindow");
- features : ウィンドウの特性をカンマ区切りで指定できます。
次の文字を指定できます。
popup、left=数値、top=数値、width=数値、height=数値、noopener、noreferrer
例:ポップアップで開く
window.open( url , null , "width=500,height=500");
新規タブを開いて読み込み完了まで待つ
新規タブを開いて読み込み完了まで待つ関数を作成してみます。
window.openNewWindow = (()=>{
// 同一オリジンポリシーのチェック
const checkNewWindow = newWindow =>{
try{ // 例外を発生させる
const a = newWindow.document;
}catch(e){
return e.message;
}
return false;
};
// 指定ミリ秒数のスリープ
const sleep = waitTime => new Promise( resolve => setTimeout(resolve, waitTime) );
// 新規タブを開いて読み込み完了まで待つ
// return { window:新規ウィンドウ , error: false またはエラーメッセージ}
return async url =>{
const newWindow = window.open( url , "_blank");
const error = checkNewWindow(newWindow);
if( error !== false ) return {window:newWindow,error:error};
// 読み込み完了まで待つ
do{
if( newWindow.document.readyState === "complete" ) break;
await sleep(500 );
}while( newWindow.document.readyState !== "complete" );
return {window:newWindow,error:false};
};
})();
window.open()でタブを開いた後、同一オリジンポリシーのチェックをしています。
方法は、プロパティを参照してエラーがスローされるかどうかを確認です。
読み込み完了までの待機は、readyStateの監視でおこなっています。
■【JavaScript】DOMが構築されてから実行する方法(async・defer属性対応)
sleep()については、次のページを参考にしてください。
■【JavaScript】 一定時間停止(sleep)のやりかた
なお、この関数はpromiseオブジェクトを返します。
then()メソッドやawaitキーワードを使用してください。
■【JavaScript】 非同期はPromise?解説が難しいので自分で理解してみた
■【JavaScript】 async/awaitを解説します
使用例
URLの入力欄と、読み込み開始ボタンを設置します。
HTML
<button id="buttom">読み込み開始</button>
<label>URL:<input type="text" id="input"></label>
<p style="color:red" id="error"></p>
ブラウザ上では、次のように表示されます。
※イメージとして設置してあるので、このボタンを押しても実行されません。
JavaScriptは次のようになります。
ボタンが押されたら、前項のopenNewWindow()を呼び出してWebページを表示します。
エラーがなければ、表示されたページのh2タグの文字を赤色に変更します。
document.addEventListener("DOMContentLoaded",()=>{
const input = document.getElementById("input");
const errorP = document.getElementById("error");
document.getElementById("buttom").addEventListener("click",
async ()=>{
errorP.innerText = "";
const newWindow = await openNewWindow( input.value );
if( newWindow.error !== false ) {
errorP.innerText = "エラー:" + newWindow.error;return;
}
Array.from( newWindow.window.document.getElementsByTagName("h2") )
.forEach( e=> e.innerHTML = `<span style="color:red">${ e.innerHTML }</span>` );
});
});
更新日:2023/02/25
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。