| << | 2006/03 | >> | ||||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
| 1 | 2 | 3 | ![]() |
|||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 | |
なにげにリファを覗いていたら、 target 属性を無効にする例のあれを、引用しているところがいくつかあるようで。
あれは全然未完成で、場所によってはおかしな挙動をするところも少なくないと思うんで、そのまま使い続けるのはいかがなもんでしょう?そんなわけで、少し改善してみました。
まず、 Noriya さんのスクリプトを参考に、フレームのページとそうでないページの処理を分けました。
フレームでないページの target は removeAttribute で全て削除します。ここまではほぼ Noriya さんのスクリプトのまま。
フレームページは、終点アンカーが外部の時と target のフレームが存在しない時は _top にします。なお、"window.framesにより子windowオブジェクトを取得し、それぞれのwindowオブジェクトについて再帰的に"処理する
というのは、 user.js はフレームごとに実行されるはずなので、ナンセンスかと思われます。
/* 不正な target を _top に設定する*/ function setTopToIllegalTaget() { for(var i in linkElements) { var items = window.document.getElementsByTagName(linkElements[i]); for (var j = 0 ; j < items.length ; j++) { var targetFrame = items[j].getAttribute('target'); var linkHref = items[j].getAttribute('href') || items[j].getAttribute('action'); //リンクが別のサイトの場合は _top に if(linkHref.indexOf(BaseHost) < 0) { items[j].setAttribute('target','_top'); } else // target フレームが存在しない時は _top に if(targetFrame && !seekTargetFrame(top,targetFrame) && targetFrame != '_self' && targetFrame != '_parent') { items[j].setAttribute('target','_top'); } } } }
さて、これでたいがいのサイトは想定通りの挙動をしますが、フレームのページが異なるドメインのページである場合、セキュリティエラーで、スクリプトの実行が終了してしまいます。そこで、 top.document.frames を取得できないページは、先の処理を行う前に分岐します。
if(!top.document.frames) //トップのフレームコレクションを取得出来ない { outSiteTarget(w); }
で、分岐したところでどんな処理をさせたらいいもんかと悪戦苦闘の末、各要素に click イベントを追加して、 click 時に top.document.location = this.href; として無理矢理 top フレームに移動させることにした。
/* top.document.location で強制移動 */ function outSiteTarget() { for(var i in linkElements) { var items = window.document.getElementsByTagName(linkElements[i]); for (var j = 0 ; j < items.length ; j++) { // onclick イベントがない時だけ設定するようにしなくっちゃダメだけど、どうやってすればよいかな items[j].addEventListener ('click', function() { top.document.location = this.href; // これはアクセスできちゃうところがいまいち解せないが、そういう仕様なのだろう。 },false ); } } }
で、あとは実行のタイミングなんですが、 load 時だけだと、読み込みが終わらないうちにクリックしたりすると新しいページが開いたりするんだよね。苦肉の策として click 時にも起動させたりしてみましたが、うまくないなぁ。もっと確実に実行できる方法はないもんですかね?
あと、 id:takeopera さんが余計なことはしないでほしいでふれられている、target="_blank" を使わないで新しいウィンドウでリンクを開く方法や、_blankを使わないで別ウィンドウを開くにはrel="external"を使うのが美しいと思う。なんかの、 window.open で新しいウィンドウを開くのを防ぐヤツは以下の感じでどうでしょうか?。やり方が正しいかどうか分かんないけど、これでだいたいのページは新しいウィンドウを開かずにリンク先を開くことが出来ます。
document.addEventListener
('load',
function()
{
window.open = function(url,winName)
{
window.location = url;
window.name = winName;
return window;
}
},false
);
ちなみに、 load イベントにしているのは、そうしないと自動ポップアップのページに自動的に移動してしまうことがあるからです。自動ポップアップはポップアップ抑制で殺してください。
usopion2006/03/27 01:56return document; は return window; の方がいいかな?
usopion2006/03/27 02:04window.open の 既定の返り値は多分ウィンドウオブジェクトだと思われるので、やっぱり return window; で。 return this; でもいいのかな?
usopion2006/03/27 02:09return document; ではエラーだったところが return window; で直ったので、やはり return window; が正しいようだ。というわけで、 return window; に直した。