IEでローディングが表示されない場合

めちゃめちゃ基本なことな気がするけど、
はまったのでメモ。

var elm = document.createElement('div');
elm.innerHTML = 'ほげ〜ほげほげ〜';
document.getElementById('hogehoge').appendChild(elm);

みたいなのとかで、
動的なHTMLを表現したりしますよね。




こういった操作を行った結果の再描画が、
ブラウザによっていつ行われるのか、という話です。


結論から言うと、

firefoxchromesafari
⇒命令が実行された瞬間
IE
⇒一連の処理フローが終わった瞬間にまとめて

だと思うんです。たぶん。


だから、Ajaxの処理の中で、

var http = new XMLHttpRequest();

// 「ロード中ですよ」表示
var elm = document.createElement('div');
elm.innerHTML = 'ロード中ですよ';
document.getElementById('hogehoge').appendChild(elm);

http.onreadystatechange = function(){
	if (http.readyState == 4){
		callback(http.responseXML);
		document.getElementById('hogehoge').removeChild(elm);// 「ロード中ですよ」を消去
	}
};

みたいなことをやっても、
firefoxchromesafariだと、「ロード中ですよ」が表示されるけど、
IEだと、何も表示されないように見える。


どういうことかと言うと、IEだと一連の処理が終わるまでは、再描画がかからないので、
Ajaxの処理が終わった時点では、(上のコードだと if (http.readyState == 4)のとこの処理が終った時点)
「ロード中ですよ」を表示するdivエレメントはappendChildされて、
再描画がかからないままremoveChildされるので、
結局なにも表示されない。


じゃあ、どうすんのよってところですが、
setTimeoutを使うのが、一般的なようす。


つまり、「ロード中ですよ」を表示させる関数( showLoading() とします)と、
httpリクエストを送ったりする関数( myHttp() とします)を分けて、

function myAjax(){
	showLoading();
	setTimeout(function(){myHttp();}, 0);
}

みたいにしてやって、実行する。


そうすると、myAjax()を実行した時点では、
まず「ロード中ですよ」を表示するように再描画がかかり、
その後すぐさま、Ajaxの処理がはじまる。
めでたしめでたし。


javascriptに慣れている人からすると今更なことだと思うけど、
基本からしっかり覚えておきたいと思います。