あれこれポップアップとprototype.jsを同時に使うには

txqzではあれこれポップアップを使っているようなのに、FirefoxとOperaでポップアップが出ないのが気になったので、原因を調べてみました。

試してみたところ、どうもprototype.jsを同時に使っている場合に、ArekorePopup.jsでエラーになるようでした。エラーが出るのはgetAttrという関数(514行~)で attr.match() を呼び出している部分。

  getAttr : function(node, attr) {
    if (!node || !attr) return null;

    ...

    if (!ret && node.getAttributeNS && attr.match(/:/)) {

ここで、"attr.match is not a function"というエラーになっていました。Opera 9.01でも同じ箇所でエラーになっていました。

なぜそんなことがおこるのかと更に調べてみたところ、どうもgetAttrの引数attrとして、文字列(おそらく属性名)ではなく、prototype.jsで定義された関数オブジェクトが入ってくる場合があるためのようでした。

どうしてそんなことになるのか、というところまでは追っていけなかったのですが、取り敢えずの対処方法としては、

  getAttr : function(node, attr) {
    if (!node || !attr) return null;
    if (typeof(attr) != 'string') return null;

    ...

    if (!ret && node.getAttributeNS && attr.match(/:/)) {

として、attrに文字列以外が入ってきた場合に即returnさせれば回避できました。

しかしこの現象は、prototype.jsの影響でふだん以上にgetAttrが呼び出されている、という状況だと思われるので、本来ならgetAttrを呼び出す前のところで何とかするべきであるような気もします。なのですが、ArekorePopup.jsを読んでいくのは難しく、処理の流れを追っていける自信がないので、今回はここまでにいたしとうござりまする。

追記(2006年8月18日)

Satoshi Ueyamaさんがより詳しく原因を調べ、あれこれポップアップの改良版を作成されました。なるほど attrs はArrayオブジェクトであり、それがprototype.jsで拡張されたところに for in でループさせているから、ということか。

というわけであれこれポップアップをprototype.jsと一緒に使いたい人は、Ueyamaさんの改良版を使うことをお勧めします。