🍩

iframeを超えたwindow、document、elementの取得方法

2022/06/09に公開

ページに他ページを埋め込むiframe。
よくYoutubeの動画埋め込みなどに使われるね。

iframeで別ページを埋め込む際の情報のやり取りについて一通り調べたのでまとめてみる。

自分から自分を参照

意外と初心者が悩むポイントなので記載。
試しに開発ツールを開いてコンソールにコマンドを打ってみると、イメージを掴めるかも。

windowの取得

console.log(window)

documentの取得

console.log(document)

そのまんまだね。

elementの取得(idあり)

console.log(document.getElementById("id"))

elementは他にも

document.getElementsByClassName()
document.getElementsByTagName()

で取得できる。だが、これらはElementsになっているように複数を配列で返すので注意。
idはページ内でユニークである特徴がここで活きるんだね。

親ページから子ページを参照

親ページから子ページのwindowの取得

iframeElement.contentWindowを使う

iframeタグにidがない場合

console.log(document.getElementsByTagName("iframe")[0].contentWindow)

iframeタグにidがある場合

console.log(document.getElementById("iframe-id").contentWindow)

親ページから子ページのdocumentの取得

console.log(document.getElementById("iframe-id").contentWindow.document)

windowからdocumentが取得できるから流れは一緒だね。

親ページから子ページのelementの取得(idあり)

console.log(document.getElementById("iframe-id").contentWindow.document.getElementById("elem-id"))

子ページから親ページを参照

子ページから親ページのwindowの取得

topは何階層に埋め込まれても一番外側のwindowを取得。parentは一つ上を取得

console.log(window.top)
console.log(window.parent)

子ページから親ページのdocumentの取得

流れは一緒

console.log(window.parent.document)

子ページから親ページのelementの取得(idあり)

console.log(window.parent.document.getElementById("id"))

最後にサンプルを

parent.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="utf-8">
  <title>iframe間のやりとり</title>
</head>

<body>

  <h1>親ページ</h1>
  <iframe id="parent-iframe" src="./child.html"></iframe>
  <button onclick="getContents()">Click</button>
</body>

<script>
  function getContents() {
    console.log(window)
    console.log(document)
    console.log(document.getElementById("parent-iframe"))

    console.log(document.getElementsByTagName("iframe")[0].contentWindow)
    console.log(document.getElementById("parent-iframe").contentWindow)
    console.log(document.getElementById("parent-iframe").contentWindow.document)
    console.log(document.getElementById("parent-iframe").contentWindow.document.getElementById("child"))
  }
  // この時点でiframe内を取得しても中身がない
  getContents()

</script>
</html>

child.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="utf-8">
  <title>iframe間のやりとり</title>
</head>

<body>
  <h1>子ページ</h1>
  <div id="child">
    子供のページ
  </div>
  <button onclick="getContents()">Click</button>
  <script>
    function getContents() {
    console.log(window.top)
    console.log(window.parent)
    console.log(window.parent.document)
    console.log(window.parent.document.getElementById("parent-iframe"))

  }
  </script>
</body>

</html>

buttonにしているのはロードを終わるのを待つため。
parent.htmlのscriptにgetContent()を初期ロード時に走らせているが子ページの読み込みに失敗しているのが確認できる。

Discussion