以下基于 jquery 1.7.2
目的是扩展jQuery的伪类选择器:仿照:last
增加:middle
。
扩展过程中需要修改origPOS
的值(jQ源码第4840行),并且jQuery将它暴露出来了(jq源码4851行)
// Expose origPOS
// "global" as in regardless of relation to brackets/parens
Expr.match.globalPOS = origPOS;
以下是我的扩展修改代码
(function($){
$.expr.match.POS =
new RegExp($.expr.match.POS.source.replace(/odd/,'odd|middle'));
$.expr.leftMatch.POS =
new RegExp($.expr.leftMatch.POS.source.replace(/odd/,'odd|middle'));
})(jQuery);
但是这样并没有改变origPOS
的值(debug):
正确的source
值应该是:(nth|eq|gt|lt|first|last|even|odd|middle)(?:\((\d*)\))?(?=[^\-]|$)/
少|middle
但是此时输出$.expr.match.POS
的值是正确的
估计是执行顺序不对导致的:
jQ整体是一个自执行函数,我在外部修改时jq的内部相关处理已经执行完毕,导致扩展失败。
感觉是我的扩展方式不对,请各位大大帮我解惑,谢谢!
===
接着补充:
jQ将此变量暴露应该是可以修改的。而且目的是扩展,所以jq源码是不能有改动的。
我在jQ 1.8.0上扩展是成功的
http://jsbin.com/qayuza/7/edit?html,console,output
console可弹出 4
扩展代码:
$.expr.match.POS =
new RegExp($.expr.match.POS.source.replace(/odd/,'odd|middle'),'ig');
$.expr.setFilters.middle = function(elements,argument,not){
var firstLast = [elements.pop(),elements.shift()];
return not ? firstLast : elements;
};
并且值matchExpr["POS"]
(对应1.7 的origPOS
)是正确的
难道是这是bug?
看了楼主这么多的描述, 你的问题总结如下:
var a = '2222';//origPOS
var b = a;//$.expr.match.POS = origPOS
//$.expr.match.POS = new RegExp($.expr.match.POS.source.replace(/odd/,'odd|middle'));
b = b.replace(/2/g, '1');
console.log(b, a);
希望能解决你的疑惑.
更新: 完整的重现你的问题及解决问题的方案:
//fake jQuery object
var jQuery = {};
(function(){
//局部变量
var origPOS = /:(nth|eq|gt|lt|first|last|even|odd)/;//origPOS
jQuery.POS = origPOS;//$.expr.match.POS = origPOS
jQuery.show = function(){//模拟 Sizzle 中 使用 origPOS 变量
console.log(origPOS, jQuery.POS);
};
//解决方案: 增加SET方法,用于修改 origPOS 变量(即修改jQuery中的源代码)
jQuery.set = function(v){
origPOS = new RegExp(v);
}
})();
jQuery.show();//输出
//模拟你的代码, 对POS 进行修改
(function($){
$.POS = $.POS.source.replace(/odd/, 'odd|middle');
})(jQuery);
jQuery.show();//输出
jQuery.set(jQuery.POS);
jQuery.show();//输出