夢のツールと JavaScript との奮闘

偶然 ModalBox なんてのを見つけて、ちょうど使いどころがあったので早速導入してみた。どんなものかは配布サイトのデモを見ていただくとして、ちょっとハマったので備忘録。

ModalBox がちょっとアレ

何がハマったかっていうと、ダイアログを表示するときに、その内容としてオブジェクトを渡しても設定したイベントハンドラが呼ばれない。ソースを追っていくと、内部の関数で要素を無条件で複製していることを発見。それが以下。

modalbox.js:203
var _htmlObj = content.cloneNode(true); // If node already a part of DOM we'll clone it

まぁコメントがアレなわけですが、とりあえずバージョン 1.5.4 向けのパッチを作成。ちなみに、該当箇所の前後も怪しかったので修正してます。

--- modalbox.js.orig	2007-09-07 20:25:48.101510600 +0900
+++ modalbox.js	2007-09-07 21:17:34.624538200 +0900
@@ -199,9 +199,9 @@
 			//if(console.log){console.log(this.MBcontent.getHeight())};
 			//this.MBcontent.show();
 		}
-		else if (typeof this.content == 'object') { // HTML Object is given
-			var _htmlObj = content.cloneNode(true); // If node already a part of DOM we'll clone it
-			if(this.content.id) _htmlObj.id = "MB_" + _htmlObj.id; // If clonable element has ID attribute defined, modifying it to prevent duplicates
+		else if (typeof content == 'object') { // HTML Object is given
+			var _htmlObj = content.parentNode ? content.cloneNode(true) : content; // If node already a part of DOM we'll clone it
+			if(content.id) _htmlObj.id = "MB_" + _htmlObj.id; // If clonable element has ID attribute defined, modifying it to prevent duplicates
 			this.MBcontent.hide().appendChild(_htmlObj);
 			this.MBcontent.down().show(); // Toggle visibility for hidden nodes
 		}

script.aculo.us の Builder.node() がちょっと変

これでもまだうまくいかない。なので、覚えたての Firebug でトレースしてみる。話がはずれるけど、Firebug って便利ねだれか IE 版作ってくれないかしら。

結果、どうも動的に生成したダイアログの内容が悪いらしい。これは script.aculo.us に含まれる Builder.node() で作ってるんだけど、これを使うとへんな親要素が一緒に生成されるらしい。

Builder.node() は、要するには document.createElement() のラッパー。ということでソースを追ってみた。

こいつはどうも要素を生成するときに、 td なら table、option なら select という風に親要素を生成してから、その子要素として目的の要素を生成している。で、td なら table っていう対応を内部で持ってて、そこに記述されていない分については div 要素を親として生成するようになってる。

問題はここからで、上記の手順で要素を生成した後、この関数は生成した子要素をそのまま return してくる。だから返された要素には、呼び出し側が意図していない親要素がついたままになっている。

どうしてこういう実装なのかわかんないけど、親から切り離してから返すようにしちゃう。対象は 1.7.1 beta 3 ツッコミ大歓迎。

--- src/builder.js.orig	2007-09-07 20:30:35.370107400 +0900
+++ src/builder.js	2007-09-07 20:31:28.432565400 +0900
@@ -74,7 +74,7 @@
     if(arguments[2])
       this._children(element, arguments[2]);
 
-     return element;
+     return parentElement.removeChild(element);
   },
   _text: function(text) {
      return document.createTextNode(text);