MSIEのパッチKB912945の対応案
たとえば・・・ですが、以下のような「やる気のない」対応でもいいかもしれません。
【条件】
- object,embed,appletの各オブジェクトに対し、動的にイベントメソッドなどを追加・削除していないこと
- object,embed,appletの各オブジェクトのonloadが2回呼ばれたり、(自動再生ならば)2回開始したりするかもしれないが、少しの時間差であれば許容できること
【特徴】
- 既存のHTMLのobject,embed,appletのタグ部分に手を加える必要がない
- window.onloadを含め、グローバル変数を使っていない(汚さない)
- HTMLファイルには1行加えるだけ
【外部ファイル】
(function() {
var all = document.all;
if(all) {
var lst = [];
var len = all.length;
for(var i = 0; i < len; i++) {
var obj = all[i];
if(obj && obj.nodeName) {
switch(obj.nodeName.toLowerCase()) {
case "object":
case "applet":
case "embed":
lst[lst.length] = obj;
break;
default:
}
}
}
for(var i = 0; i < lst.length; i++) {
lst[i].outerHTML += "";
}
lst = null;
}
})();
【HTMLファイル】
</body>の直前に、
<script language="JScript" src="★" charset="◆"></script>
★:上記JSファイル
◆:上記JSファイルの文字コード
を入れる。【考え方】
- やる気ない(こんなことに労力を使いたくない)
- HTMLファイルはなるべく変更したくない
- MSIEだけ対象だからdocument.allで対象を探してouterHTMLをそのまま書き換えればいいでしょ*1
- 動的に実装されたイベントハンドラは却下*2
以下2006/01/13追記
【技術的観点】
- 対象とするブラウザ
- document.allのループについて1回目のループではリストアップのみを行い、変更はしません。変更すべきオブジェクトが確定するそばからオブジェクトを置き換えたくなかったので。
- outerHTMLの置き換えについて2回目のループでオブジェクトを置き換えます。
lst[i].outerHTML = lst[i].outerHTML;
で動作(KB912945問題の解決を)確認しましたが、
lst[i].outerHTML += ""
でも(ソースの追記ではなく、ソースの入れ替えになるので)オブジェクトが置換されるはず*3なのでそれにしました。 - <script>タグの記述場所scriptタグは</body>の直前に記述します。
それは、全ての静的なobject,embed,appletタグが読み込まれた後に実行する必要があることと、onloadのタイミングが使用できないことによります。
onloadのタイミングで何らかの処理が走るのを妨げることはできませんし、onloadよりも先に置換しておきたいので。 - 問題点</body>の直前の段階で、すでにobject,embed,appletのオブジェクトに対する参照をJS側で保持していたり、JSでイベントなど(プリミティブ型ではないもの)を付加している場合は、参照が切れてしまいます。
ドキュメントのonloadであれば間に合いますが、そうでなければ参照をコピーする必要があり、汎用的に作るのは結構めんどくさいです。 - 拡張性もし拡張するならば、
- この外部JSを読み込むscriptタグの属性として、(HTMLの仕様になくても)適当な属性を書く。
これはdocument.scripts[document.scripts.length-1].getAttribute(●)とすれば取り出せるはずです。
<script language="JScript" src="★" charset="◆" ●="●属性の値"></script>
●:ありもしない属性 - この外部JSを読み込むscriptタグの開始タグと閉じタグの間に、JSのコメントとしてオプションを記述する。
これは、document.scripts[documents.scripts.length-1].innerHTMLとでもすれば取り出せるはずです。
<script language="JScript" src="★" charset="◆"><!--
//オプション1=値1
//オプション2=値2
//--></script>
- この外部JSを読み込むscriptタグの属性として、(HTMLの仕様になくても)適当な属性を書く。