古詩詞大全網 - 成語查詢 - jquery TypeError: U[a].exec is not a function 是咋個回事

jquery TypeError: U[a].exec is not a function 是咋個回事

這個是jquery構造的問題,jquery官方非常多的提醒過這個,就是不要隨便用prototype,會影響到jquery的遍歷。

children的實現是壹個遍歷,妳自定義了壹個prototype,於是jquery就會遍歷到這個,但妳這個又是個函數,而不是壹個jquery對象

而當妳使用("#question_box p") 在jq內部就不是遍歷來實現的,而是find

find的實現

find:?function(?selector?)?{

//?當表達式不包含“,”符號時候

if?(?this.length?===?1?&&?!/,/.test(selector)?)?{

var?ret?=?this.pushStack(?[],?"find",?selector?);

ret.length?=?0;

jQuery.find(?selector,?this[0],?ret?);

return?ret;

}?

//?當表達式包含“,”符號時候

else?{

var?elems?=?jQuery.map(this,?function(elem){

return?jQuery.find(?selector,?elem?);

});

return?this.pushStack(?/[^+>]?[^+>]/.test(?selector?)?

jQuery.unique(?elems?)?:

elems,?"find",?selector?);

}

}

//其中的jQuery.find是這樣壹個方法:

jQuery.find?=?Sizzle.find;

//而sizzle又是這樣壹個方法:

var?Sizzle?=?function(selector,?context,?results,?seed)?{

results?=?results?||?[];

context?=?context?||?document;

if?(?context.nodeType?!==?1?&&?context.nodeType?!==?9?)

return?[];

if?(?!selector?||?typeof?selector?!==?"string"?)?{

return?results;

}

var?parts?=?[],?m,?set,?checkSet,?check,?mode,?extra,?prune?=?true;

//?Reset?the?position?of?the?chunker?regexp?(start?from?head)

chunker.lastIndex?=?0;

while?(?(m?=?chunker.exec(selector))?!==?null?)?{

parts.push(?m[1]?);

if?(?m[2]?)?{

extra?=?RegExp.rightContext;

break;

}

}

if?(?parts.length?>?1?&&?origPOS.exec(?selector?)?)?{

if?(?parts.length?===?2?&&?Expr.relative[?parts[0]?]?)?{

set?=?posProcess(?parts[0]?+?parts[1],?context?);

}?else?{

set?=?Expr.relative[?parts[0]?]?

[?context?]?:

Sizzle(?parts.shift(),?context?);

while?(?parts.length?)?{

selector?=?parts.shift();

if?(?Expr.relative[?selector?]?)

selector?+=?parts.shift();

set?=?posProcess(?selector,?set?);

}

}

}?else?{

var?ret?=?seed?

{?expr:?parts.pop(),?set:?makeArray(seed)?}?:

Sizzle.find(?parts.pop(),?parts.length?===?1?&&?context.parentNodecontext.parentNode?:?context,?isXML(context)?);

set?=?Sizzle.filter(?ret.expr,?ret.set?);

if?(?parts.length?>?0?)?{

checkSet?=?makeArray(set);

}?else?{

prune?=?false;

}

while?(?parts.length?)?{

var?cur?=?parts.pop(),?pop?=?cur;

if?(?!Expr.relative[?cur?]?)?{

cur?=?"";

}?else?{

pop?=?parts.pop();

}

if?(?pop?==?null?)?{

pop?=?context;

}

Expr.relative[?cur?](?checkSet,?pop,?isXML(context)?);

}

}

if?(?!checkSet?)?{

checkSet?=?set;

}

if?(?!checkSet?)?{

throw?"Syntax?error,?unrecognized?expression:?"?+?(cur?||?selector);

}

if?(?toString.call(checkSet)?===?"[object?Array]"?)?{

if?(?!prune?)?{

results.push.apply(?results,?checkSet?);

}?else?if?(?context.nodeType?===?1?)?{

for?(?var?i?=?0;?checkSet[i]?!=?null;?i++?)?{

if?(?checkSet[i]?&&?(checkSet[i]?===?true?||?checkSet[i].nodeType?===?1?&&?contains(context,?checkSet[i]))?)?{

results.push(?set[i]?);

}

}

}?else?{

for?(?var?i?=?0;?checkSet[i]?!=?null;?i++?)?{

if?(?checkSet[i]?&&?checkSet[i].nodeType?===?1?)?{

results.push(?set[i]?);

}

}

}

}?else?{

makeArray(?checkSet,?results?);

}

if?(?extra?)?{

Sizzle(?extra,?context,?results,?seed?);

}

return?results;

};

而children的實現方法如下(children就是“>”)

relative:?{

//

">":?function(checkSet,?part,?isXML){

//?當part為單詞字符時,如$("form?>?input"),part為“form”

if?(?typeof?part?===?"string"?&&?!/\W/.test(part)?)?{?

part?=?isXMLpart?:?part.toUpperCase();?

for?(?var?i?=?0,?l?=?checkSet.length;?i?<?l;?i++?)?{

var?elem?=?checkSet[i];

if?(?elem?)?{

//?得到elem的父節點

var?parent?=?elem.parentNode;

//?如果父節點名稱為part值時,在checkSet[i]上賦值父節點,否則賦值false

checkSet[i]?=?parent.nodeName?===?partparent?:?false;

}

}

//?當part為非單詞字符時,如$(".blue?>?input"),part為“.blue”

}?else?{

for?(?var?i?=?0,?l?=?checkSet.length;?i?<?l;?i++?)?{

var?elem?=?checkSet[i];

if?(?elem?)?{

checkSet[i]?=?typeof?part?===?"string"?

elem.parentNode?:

elem.parentNode?===?part;

}

}?

if?(?typeof?part?===?"string"?)?{

Sizzle.filter(?part,?checkSet,?true?);

}

}

},

}

看出區別了嗎?用的是Sizzle.filter

說道Sizzle,那是相當牛的壹個選擇器引擎,find和filter是其核心方法之壹,他們的區別可以看這個:

blogs.com/xesam/archive/2012/02/15/2352574.html

blogs.com/xesam/archive/2012/02/18/2356617.html

其中跟妳的問題有關的段落摘錄如下:

find直接用原生的getElementById(當然也會用byname或者其他)去找

Expr.find?=?{

ID:?function(?match,?context,?isXML?)?{

if?(?typeof?context.getElementById?!==?"undefined"?&&?!isXML?)?{

var?m?=?context.getElementById(match[1]);

return?m?&&?m.parentNode[m]?:?[];?

}

},

//byclass?by?name是壹樣的實現

而children因為只找子壹級,不再往下找,所以采取的是兩次過濾的方法,即過濾questionbox的下壹級元素,然後再看是不是p標簽,(在jq的1.2以後的版本裏,這個過程是反過來的,似乎,即先找出所有p,然後再看父元素是不是妳前壹個篩選器,這個機制我記不太清了,懶得去翻源代碼看了,妳有興趣可以研究下)

那麽,這時候就要用到for in循環,而這時候妳又給所有對象定義了新的屬性,所以for in的時候必然遍歷到妳這個新屬性,妳這個自定義的屬性又不是個jq對象,於是自然杯具了。

但奇特的是,我反復測試了妳的代碼,發現在jq2.0以後的版本上似乎是沒問題的。。。難道jq改了選擇器的實現?