ブログネタ
JavaScript に参加中!
jQuery の AJAX の機能をバリバリ使ったものを、本番サーバーにアップしたら動かない!という悲劇があった。先日。
色々試したけど、分かった原因は「サーバーの仕様っぽい」止まり。(誰か原因を教えてー)
サーバーの仕様変更はできないし、これに時間をかけてもアレなので、AJAX を使わず、iframe で回避した。

その時やったことを忘れないよう、jQuery を使って iframe の中の要素にアクセスする方法を書いておく。

■ 基礎

まず、iframe 内のページの document オブジェクトの参照はこれでOK

$('iframe:first').contents()
(例として、ページ内にある最初 (:first) の iframe を対象とする)
(contents() については、contents() - jQuery 1.3.2 日本語リファレンス を参照してください)

これを元すれば、jQuery の find() と強力なセレクタを使って、目的の要素にアクセスできる。
なので例えば、iframe 内のページにある、id="main" へのアクセスは

$('iframe:first').contents().find('#main')
カンタン!

■ 使い方

あとは、jQuery の機能で自由自在に操作が可能なのは、なんとなく想像できると思う。
サンプルを用意したので、↓をご覧アレー

■ 問題点

  • 親ページのドメインと、iframe の中のドメインが異なる場合、JavaScript のセキュリティ制限で、一切アクセスできない (上記サンプルを参照)。
    他ドメインのページの情報を無断に拝借するのはレアケースかもだけど、必要な場合はサーバーサイドでプロキシ的な役目のページを置く必要があるね。

    (2010/02/17 追記) プロキシのページを設けることができる環境なら、iframe 使わずに素の? XMLHttpRequest というか、jQuery の AJAX 系の機能を素直に使ったほうが回りくどくない。

    それと、iframe 内の要素を親ページに配置した場合、class や id による見た目の制御がリセットされる。
    やってみれば分かると思うんだけど……なんて言ったら伝わるかなー。
    親ページでも iframe でロードしたページの CSS を読み込んでおかないとイケない、ということです。
  • AJAX の代用とするには、動作の快適さに気を配る必要がある (特にIE)。
    これもケースバイケースだと思うんだけど、俺が今回作ったのは、
    「a タグに onmouse すると、リンク先ページの特定の部分を画面に表示する」
    という機能だった。
    1. a タグにて、onmouseover イベントを発生
      a タグの href にある URL を iframe に 渡す。
    2. iframe の読み込みがスタート
    3. iframe の onload イベントで描画処理
    という流れになるんだけど、onmouse ということもあり、スピーディーな挙動が要求される。
    iframe の読み込みはバックグラウンドで行われ、言うなれば「非同期」。
    うはw AJAX じゃんwww スピード感マックス!
    と期待していたら、Internet Explore は iframe 読み込み開始時の挙動がびっくりするほど重い
    バックグラウンドで動いているとは思えないような雰囲気。
    これには色々な回避方法があると思う。
    俺がやった方法を大雑把に書くと、
    • iframe は1つだけ用いて、使いまわす。
      iframe を瞬時に複数発生させると、重たかったので (IEで)
    • iframe で進行している読み込みが不要になった場合、強引に中断させる。
      つまり、a タグの onmouseout 発生で、iframe の src はダミーの空ページを読み込ませて、かつ iframe の onload イベントをクリア (jQuery の unbind)
    こんな感じ。

はい。
ということで、jQuery チョー便利ィイ!