2008年12月14日日曜日

jquery + jquery-sizzle.js のセレクタの違い(2)

jquery + jquery-sizzle.js のセレクタの違い(2)

昨日の続き

jglycy を動かすための改造

jglycy が動かない原因は sizzle の セレクタの場合 HTMLElement が持っているプロパティとして存在する属性以外は取得できなくなっているから
で、その問題の行は jquery-sizzle.js の 561行目

561行目 var result = elem[ match[1] ], value = result + "", type = match[2], check = match[4];

match[1] には $('[xxx]'); とした際の xxx が入る。 elem.className や elem.id などは存在するが
elem.jg などと言うものは存在しない。
(xxx が class の場合は preFilter で className に変更されている)

elem.getAttribute(name) としてならば jg は取得できるので以下のように変更することで利用できるようになる。

var result = elem.getAttribute(match[1]), value = result + "", type = match[2], check = match[4];


ただし、この場合 preFilter の ATTR で class -> className と変更されているので [class] が使えなくなる。
275行目を削除する必要がある。
(elem.getAttribute() の場合は class , elem のプロパティは className と名前が違う。)

275行目 "class": "className"

削除するのも嫌だし、速度も多少遅くなりそうな気もするので、以下のように Sizzle.selectors を拡張し、
[@xxx] とした場合は、jg など定義されていない属性値も取れるようににした。
(速度は計っていないので近いうちに・・・遅くならないならこんなことする必要もない)


Sizzle.selectors.match.EXTATTR = /\[@((?:[\w\u0128-\uFFFF_-]|\\.)+)\s*(?:(\S{0,1}=)\s*(['"]*)(.*?)\3|)\]/
Sizzle.selectors.filter.EXTATTR = function(elem, match, i, array){
var result = elem.getAttribute(match[1]), value = result + "", type = match[2], check = match[4];
return result == null ?
false :
type === "=" ?
value === check :
type === "*=" || type === "~=" ?
value.indexOf(check) >= 0 :
!match[4] ?
result :
type === "!=" ?
value != check :
type === "^=" ?
value.indexOf(check) === 0 :
type === "$=" ?
value.substr(value.length - check.length) === check :
type === "|=" ?
value === check || value.substr(0, check.length + 1) === check + "-" :
false;
}


また、この変更をするだけでは jglycy は動かないので jglycy の 27 行目を以下のように変更する。

$[jg].invoke($("*[" + prefix + "]", node));

$[jg].invoke($("*[@" + prefix + "]", node));

これで動作するようになる

ここまでやって 対象を絞るために htmlに準拠しない attribute を追加するよりも、 class="jglycy" と
書くようなのでもいい気がしてきた。

こんな感じ?
<a href="" class="jglycy" jg="xxxx" jg:xxxx="aaa:'bbb'">link</a>

ちょっと長くなるのが嫌ならこんな感じかな、この方がシンプルか
<a href="" class="jglycy" jg="xxxx:{aaa:'bbb'}">link</a>


これで動くための jqlycy の変更はまた今度