虽然排除了$("div")
,但有一个类似[<div>1</div><div>2</div><div>3</div>]
的数组
从jQuery.fn
获取了一堆方法,我对模拟它很感兴趣,但我无法做到这一点#34;顺利&#34;
我提到了zepto.js:
zepto.Z = function(dom, selector) { dom = dom || [] dom.__proto__ = arguments.callee.prototype dom.selector = selector || '' return dom }
但由于它不是跨浏览器,我写了一些片段如下:
var query=function(selector){
return new query.init(selector);
};
query.init=function(selector){
var found=document.querySelectorAll(selector);
this.length=found.length;
for(var i=0,len=this.length;i<len;i++){
this[i]=found[i];
}
return this;
};
query.init.prototype={
method1:function(){},
method2:function(){}
}
输入query("#id")
时输入,但它可以在功能上操作,但它看起来不够好
如你所见,如何编写一个看起来像jQuery的查询函数?谢谢
答案 0 :(得分:1)
您可能希望从简单的事情开始:
function MaterObject(selector) {
this.selector = selector;
this.elements = document.querySelectorAll(selector);
}
现在通过MasterObject.prototype添加功能:
MasterObject.prototype = {
getLength: function() {
return this.elements.length;
},
refresh: function() {
this.elements = document.querySelectorAll(this.selector);
return this;
},
addMore: function(selector) {
this.selector = this.selector + ',' + selector;
this.refresh();
return this;
}
}
等等。开球:
function $(selector) {
return new MasterObject(selector);
}
以上缺乏功能测试,所以很脆弱。
请注意,jQuery的大部分内容都是重载的,因此需要测试它的内容,然后决定使用结果(想到“isArray”的着名案例)。调用方法可能会对选择器选择的所有元素执行某些操作,或者只执行第一个元素。将方法传递给字符串,对象或什么都不会完全改变方法的作用。
请注意,函数可以返回this
,因此可以链接方法。但是(对于库设计者和用户来说)问题是确定哪些应该是可链接的,哪些不应该是,例如。
var $x = $('div');
// addMore is chainable, getLength isn't
$x.addMore('p').getLength();
如果你想让你的“jQuery”对象成为一个数组,那么你必须将所有要继承的方法添加到Array.prototype,这不是一个好主意。没有其他办法,你不能创建一个数组对象并将自己的原型对象插入其[[Prototype]]
链,数组实例将直接从Array.prototype继承。
您可以做的最好的事情是将NodeList元素转换为数组(就像在OP中一样),并在其上调用类似数组的方法(注意,因此,选择器可能不代表元素数组的内容) ):
function MasterObject(selector) {
this.selector = selector;
this.elements = [];
}
MasterObject.prototype = {
...
refresh: function() {
this.elements = [];
var els = document.querySelectorAll(this.selector);
for (var i=0, iLen=els.length; i<iLen; i++) {
this.elements[i] = els[i];
}
return this;
},
pop: function() {
return this.elements.pop();
},
Perphaps这样的更改应该反映在DOM中(在这种情况下,选择器应该与内容同步,而不必通过qSA再次选择它):
popElement: function() {
var el = this.elements.pop();
el.parentNode.removeChild(el);
return el;
},
...
};
function $(selector) {
var newObj = new MasterObject(selector);
newObj.refresh();
return newObj;
}