Greasemonkeyスクリプトで、処理対象がフレーム内のページの場合、iframeなのかframeなのかを判断することはできるのでしょうか。

iframeで開かれたページの場合のみ処理しないようにしたいのですが。。。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2007/10/29 10:00:05
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:znz No.1

回答回数193ベストアンサー獲得回数25

ポイント27pt

DOMのparentNodeをたどっていてiframeがあるかどうかを調べるというのはどうでしょうか?

id:castor

ありがとうございます。

フレームで開かれたページでも、独立したページとして扱われるので、親子間でDOMツリーの繋がりはないかと思います。

念のため試してみましたが、フレームページのノードを遡っていくと HTMLHtmlElement→HTMLDocument→null で終わってしまうようです(調べ方が間違ってたりして)。

似たような方法で、親ウィンドウが存在する場合はiframeを検索して、srcが自分自身のURLと一致するものがあればiframe内のページと判断する。なんてことを思いついたのですが、そもそもiframeでは処理させないことで軽くしたかったのに、かえって重くなるような気がしてきました…orz。

引き続き、ご意見お待ちしております。

2007/10/23 08:58:13
id:znz No.2

回答回数193ベストアンサー獲得回数25

ポイント27pt

ちゃんと確認せずに失礼しました。

http://d.hatena.ne.jp/brazil/20071013/1192265905

に「window == window.parent」とあったので、試してみたところうまくいくことを確認できました。

http://www.n-z.jp/tmp/2007/iframe-test/a.html

にテストページをおいてみました。

ここでh1の内容がそれぞれ「test true」と「inner false」になって区別できているようです。

比較用にhtmlの中にscript直接も書いていますが、そちらは両方trueになってしまっています。

id:castor

わざわざテストまでしていただき、ありがとうございます。

親ウィンドウなのか、フレームページなのかはご指摘いただいた方法で判別できますね。ただ、window.parentとの比較の場合、フレームページがiframeなのかframeなのかは判断できないかと思います。


1つ目のリンク先にあるように、Greasemonkeyスクリプトはiframe/frameの回数だけ実行されてしまうので、無駄な処理が走ることがあります。iframeは外部サイトであることが多いのに対して、frameは自サイト内のコンテンツである可能性が高いので、iframeの場合のみ判別(して処理させないように)するのが、質問の意図でした。

引き続き、ご意見お待ちしております。

2007/10/23 19:21:51
id:znz No.3

回答回数193ベストアンサー獲得回数25

ポイント26pt

いろいろ考えてみたところ、一番目の回答のコメントにあったように親の中のiframeのsrcをチェックする方法はループになってしまうので、逆にframe側かどうかをframesetなどを探してみるという方法で試してみました。

http://www.n-z.jp/tmp/2007/iframe-test/f.html

にテストページを置いています。

iframe-test2.user.jsの方です。

frameの中にソースが表示されるとインストールがうまくいかないことがあるようなので、右クリックして新しいタブで開くを選んだ方がいいようです。

試しに書いてみた他のタグでのチェックも含めて以下のようにしています。

noframesなどはないこともありそうなので、うまくいかないことがあれば目的のページの構成に合わせてチェックするタグを変えてみるとよさそうですが、frameだと確実に存在しそうなframesetだけチェックするのがいいのではないかと思います。

(function(){
  var h1 = document.getElementsByTagName("h1")[0];
  if (h1) {
    h1.innerHTML += " " + (window == window.parent);
    if (window != window.parent) {
      var iframes = window.parent.document.getElementsByTagName("iframe");
      for (var i=0; i<iframes.length; i++) {
        if (iframes[i].src == document.location) {
          h1.innerHTML += " (iframe)";
          break;
        }
      }
      var frameset = window.parent.document.getElementsByTagName("frameset");
      if (frameset &amp;&amp; frameset[0]) {
        h1.innerHTML += " (frameset)";
      }
      var noframes = window.parent.document.getElementsByTagName("noframes");
      if (noframes &amp;&amp; noframes[0]) {
        h1.innerHTML += " (noframes)";
      }
      var body = window.parent.document.getElementsByTagName("body");
      if (body &amp;&amp; body[0]) {
        h1.innerHTML += " (body)";
      }
    }
  }
})();
id:castor

度々のご回答、ありがとうございます。

framesetで判定するのは非常に良さそうですね。これは、目から鱗でした…。

フレームページの場合(window.parentが存在する)に、親ページにframesetが存在しない場合はiframe内のページだと判断して処理させないようにすれば、比較的低コストで意図した動作になりそうです。

しばらく、これで検証してみたいと思います。ありがとうございました!

(追記)フレームページが別ドメインだと動作しませんでした

2007/10/24 12:25:17
  • id:castor
    うう、別ドメインだとwindow.parent.documentは触れないですね…orz
    フレームウィンドウ側から判別するのは絶対に無理な気がしてきました。。。
  • id:znz
    試していなくてアイデアだけなのでコメントに書いてしまいますが、documentが見えなくても他のプロパティが見えるのなら、framesetがある側でwindow.hasframeset=trueのようにフラグをセットしておいて、中からはwindow.parent.hasframesetをチェックするというのはどうでしょうか?
  • id:castor
    ありがとうございます。
    一応試してみましたが、アクセス可能なのは親のWindowオブジェクトまでですね。
    これでクロスドメインが回避できたとしても、それはそれでブラウザのバグな気がします…。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません