上回介紹過自訂jQuery Selector Filter的做法,在範例中判斷true/false的邏輯用的是字串表示法,例如:
$.extend($.expr[":"], { exact: "(a.textContent||a.innerText||jQuery(a).text()||'') == m[3];"  });

不過,這個簡便字串表示法到了jQuery-1.3就不管用了,會導致Line: 1938 Error: Function expected的錯誤。追了一下原始碼,發現在1.2.6中有以下的邏輯,當發現設定的Filter是字串時,會透過eval方式將其轉換成Function。

            // Otherwise, find the expression to execute
            } else {
                var fn = jQuery.expr[ m[1] ];
                if ( typeof fn == "object" )
                    fn = fn[ m[2] ];
 
                if ( typeof fn == "string" )
                    fn = eval("false||function(a,i){return " + fn + ";}");
 
                // Execute it against the current filter
                r = jQuery.grep( r, function(elem, i){
                    return fn(elem, i, m, r);
                }, not );
            }

在1.3版中,Selector已改為全新的Sizzle引擎,邏輯重寫過,甚至jQuery.expr[":"]都是另行對應宣告過才做到向前相容:

// EXPOSE
jQuery.find = Sizzle;
jQuery.filter = Sizzle.filter;
jQuery.expr = Sizzle.selectors;
jQuery.expr[":"] = jQuery.expr.filters;

目前看來,Sizzle裡已不再提供Filter表示字串自動轉函數的功能,因此上述的例子,要改回用標準函數宣告才可在jQuery 1.3+中正確執行:
$.extend($.expr[":"], { exact: function(a, i, m) { return (a.textContent || a.innerText || jQuery(a).text() || '') == m[3]; } });


Comments

Be the first to post a comment

Post a comment