Hatena::ブログ(Diary)

最速チュパカブラ研究会

 | 

2006年8月18日 Re: あれこれポップアップとprototype.jsを同時に使うには

http://www.akatsukinishisu.net/itazuragaki/js/arekore_popup_and_prototype_js.html

 そういえば、私も引数attrにmatchプロパティ(またはメソッド)が無ければreturnするという泥縄で解決していたのですが、せっかくなのでもう少し根本(に近いところ)での解決を試してみました。

 このエラーの原因は、prototype.jsがArrayに対して

Object.extend(Array.prototype, Enumerable);

などいろいろ拡張をかけているため、ArekorePopup.jsの初期設定を格納している配列

this.attrs = ['ap:banner', 'title', 'href', 'cite', 'datetime'];

が汚染され、

for (var i in AP.attrs)

といった部分で余計なものが列挙されてしまうという所にあります。

単純な解決方法としてはfor (var i in AP.attrs)をfor (var i = 0;i < AP.attrs.length;i++)にしてしまう手がありますが、修正箇所が散らばるしなんかモテないコードになるし、ということで初期化時にAP.attrsをArrayから単純なObjectに置き換えてしまうことにしました。つまり、

a = ["foo", "bar"]

a = {0:"foo", 1:"bar"}

に自動的に変換するということです。

ダウンロード

http://gyu.que.jp/data/ArekorePopup1.2.5_20060818.zip

動作テスト

diff

*** ArekorePopup_opera\ArekorePopup.js	Sun Jul 16 21:56:26 2006
--- ArekorePopup_20060818\ArekorePopup.js	Fri Aug 18 13:21:00 2006
***************
*** 118,123 ****
--- 118,136 ----
  }
  
  ArekorePopup.prototype = {
+ 
+     // 2006-08-18 added for prototype.js
+ 	fixAttrsArray : function() {
+ 		if (!AP.attrs.length) return;
+ 
+ 		var a = AP.attrs;
+ 		var l = a.length;
+ 
+ 		AP.attrs = {};
+ 		for (var i = 0;i < l;i++)
+ 			AP.attrs[i] = a[i];
+ 	},
+ 
  	launch : function() {
  		AP.oBODY = AP.getElements('body')[0];
  		if (!AP.oBODY || AP.safariOnly && !AP.isSafari || !AP.findCSS()) return;
***************
*** 128,133 ****
--- 141,147 ----
  	},
  
  	init : function() {
+ 		AP.fixAttrsArray();
  		if (!AP.cssEnabledCheck()) return;
  		AP.initTimer = (new Date()).getTime();
  		AP.image.prepare(); 
***************
*** 286,292 ****
  	},
  
  	append : function(e) {
! 		if (typeof AP != 'object' || AP.curItem || !AP.attrs.length) return;
  		if (AP.initBeforehand) {
  			e.stopPropagation();
  			AP.curItem    = e.currentTarget;
--- 300,306 ----
  	},
  
  	append : function(e) {
! 		if (typeof AP != 'object' || AP.curItem) return;
  		if (AP.initBeforehand) {
  			e.stopPropagation();
  			AP.curItem    = e.currentTarget;

 |