protoload.jsをIE7でも動かす

Ajaxリクエスト時のローディングインジケーターをよしなにこなしてくれるprotoload.js

Supports partially: IE 7, Opera 8
Element.offsetParent should be the next ancestor element with style.position != 'static', in IE 7 and Opera 8 it is the next ancestor element, a bug I think.
Just add position='relative' to the next ancestor element to prohibit "buggy behavior".

ってな通りIE7は一部しか動かないよママン!ということで見事にズレた。

時期的(リリースが2007/09/07)な問題で、このprotoload.jsが書かれたのはprototype.jsが1.5.1.1だと推測。
Element.offsetLeft,offsetTopはブラウザによって返る値が変わる(特にIEがうんこ)のを自前でなんとかしなきゃいけないという時代でした。
Element.cumulativeOffset()はprototype.js-1.6からなのでオフセット計算によるブラウザ依存吸収が無かったんですね。合唱。

そんなわけで勝手にバージョンアップします。

protoload.js-ie7.patch

Index: /protoload.js
===================================================================
--- /protoload.js	(0.1beta)
+++ /protoload.js	(hoge)
@@ -43,12 +43,12 @@
 		element._loading.className = className;
 		window.setTimeout((function() {
 			if (this._waiting) {
-				var left = this.offsetLeft, 
-					top = this.offsetTop,
+				var offset = this.cumulativeOffset();
+				var left = offset.left, 
+					top = offset.top,
 					width = this.offsetWidth,
 					height = this.offsetHeight,
 					l = this._loading;
-					
 				l.style.left = left+'px';
 				l.style.top = top+'px';
 				l.style.width = width+'px';
  • 動作確認はIE7/Firefox3しかやってません。
  • prototype.js 1.6以上だったらたぶん動きます。Element.cumulativeOffset()次第。

おまけ

protoload.jsのローディングインジケータをAjax.Updater全部におっかぶせる簡単な方法

	Ajax.Responders.register({
		onLoading: function(elem){
			$(elem.container.success).startWaiting('bigWaiting');
		},
		onLoaded: function(elem){
			$(elem.container.success).stopWaiting('bigWaiting');
		}
	});

よしなに。