外部JavaScriptが吐くdocument.writeを取得する方法

documentWriteFromJavaScript_sh

見る人が見れば分かると思いますが、一応、自分用メモ。

ドコのナニとは言いませんが、外部の JavaScript が盛大に吐いた document.write の内容を、呼び出し元の JavaScript から文字列として取得する方法とかです。jQuery 必須。

※この記事は今後修正・更新する可能性があります。

基本的なアイディアは以下から拝借させていただきました。

相当古い記事なので色々ありますが、確かに目からウロコな方法です。

それなりに精査・見直しをして、jQuery で動くように書くとこんな感じに。あと、ついでなので、画面のスクロールに合わせて発動させる方法も合わせて仕込んでおきます。

var tr_top = jQuery('#widget_box').offset().top;

jQuery(this).on('scroll.tr_widget, load.tr_widget', function(){
	if (jQuery(this).scrollTop() + jQuery(this).height() > tr_top) {
		jQuery(this).off('scroll.tr_widget, load.tr_widget');	// remove events
		tr_func_widget(document);
	}
});

var tr_func_widget = function(d){
	var alts = [];
	d._write = d.write;
	d.write = function(s){ alts.push(s);}
	var src = "http://example.com/widget/js/widget.js";
	var js = d.createElement('script');
	js.setAttribute('type', 'text/javascript');
	js.setAttribute('charset', 'utf-8');
	js.setAttribute('src', src);
	d.getElementsByTagName('head')[0].appendChild(js);
	var olfunc = function(){
		jQuery("#widget_box").append(alts.join("")); // fruits
		d.write = d._write; // restore d.write
	}
	js.onload = function(){ olfunc(); }; // script done.
	js.onreadystatechange  = function(){ // onload is not supported by IE.
		if (this.readyState == 'complete') { olfunc(); }
	};
};

コードを使う場合は、タイミングや環境差、呼び出し先の JavaScript の特性・特質など、もろもろを理解した上で適宜、必要箇所を修正ください。

状況によっては適していない、使えない場合もあります。あと、ブログエディタ上で色々手直ししているため、デバッグも必要かもしれません。

jQuery の呼び出し方がイケてないとか、Syntaxhighlighter も入れてないのかよ、とかも全部ご容赦ください。ワザとです。

異様に遅い外部 JavaScript が、よくよく見てみると document.write を多用してたので。おかげで遅延読み込みさせると色々問題があったりしてね。iframe とか、色々案はあったんですが、本当に苦肉の策です。

トリッキーなので実環境向きかどうかは分かりませんが、それにしてもスゴい発想と思います。

今ならもう少しスマート方法とか無いんですかね。と書いてから思うのであった…。

参考情報

Hatena Pocket Line

コメントを記入