htsign's blog

ノンジャンルで書くつもりだけど技術系が多いんじゃないかと思います

全てのフレームを対象にするには

某大手工業系企業の新規開発プロジェクトに参画しているのですが、非常に悲しいことに社内ポータルが未だにフレームを使用したサイトなのです。
フレームを使うと容易にペインで分けたサイトを構築できるため、実用重視のエンタープライズ界隈で重宝されるのはよく分かります。

ただ、フレーム*1を使うと、ブックマークレットを作ろうと思ったときにそのままではトップレベルのウィンドウにしか効力を発揮しません。
埋め込まれているフレームのソースURLがトップレベルのウィンドウと同じドメインに属しているのであれば*2、以下のようなコードを使うことで全フレームに対して操作することができます。

// for IE9+
(function loop(win) {
  return Array.prototype.reduce.call(win, function(p, c) {
    return p.concat(loop(c.window));
  }, [win]);
})(window)
.forEach(function(window) {
  var document;
  try { document = window.document; } catch(e) { return; }
  /* code here */
});
// compressed
(function l(w){return [].reduce.call(w,function(p,c){return p.concat(l(c.window))},[w])})(window).forEach(function(w){try{var d=w.document}catch(e){return}/* code here */})

*1:<iframe>も同様です。

*2:Same-Origin PolicyはWebにおける重要な概念です。