【凤凰社】模拟jQuery选择器功能及方法

查看jQuery源码可以发现,jQuery中没有使用new操作符来创建新对象,而是采用调用jQuery原型中init()函数的方法返回一个新对象。
熟悉jQuery的人应该知道,几乎jQuery所有操作,都是从$符号Start,当作为元素选择器的时候,操作结果返回的是一个jQuery对象。以下是个人模拟的写法:

//模拟jQuery选择器功可以
(function () {
function jQuery(selector) {
return new jQuery.prototype.init(selector);
}
//init是存在jQuery原型上的一个方法
jQuery.prototype.init = function (selector) {
//选取dom原生的js
this.length = 0;
if (selector == null) {
return this;
}
if (typeof selector == 'string' && selector.indexOf('.') != -1) {
var dom = document.getElementsByClassName(selector.slice(1));
} else if (typeof selector == 'string' && selector.indexOf("#") != -1) {
var dom = document.getElementById(selector.slice(1));
}
if (selector instanceof HTMLElement || dom.length == undefined) {
this[0] = dom || selector;
this.length++;
} else {
for (var i = 0; i < dom.length; i++) {
this[i] = dom[i];
this.length++;
}
}
}
jQuery.prototype.css = function (propertyname, value) {
for (var i = 0; i < this.length; i++) {
//判断传入的值如果为对象
if (Object.prototype.toString.call(propertyname) == '[object Object]') {
//新数组存储对象的键和值
var arr = []
//遍历对象键和值存入新数组
for (key in propertyname) {
// console.log(i);
arr.push(key)
arr.push(propertyname[key])
}
//遍历数组给目标改变样式
for (var j = 0; j < arr.length; j++) {
this[i].style[arr[j]] = arr[j + 1];
}
}
//判断传入的值是两个值,设置css属性
if (arguments.length == 2) {
this[i].style[arguments[0]] = arguments[1]
}
//判断传入的值是一个值表示返回 CSS 属性
if (arguments.length == 1) {
return window.getComputedStyle(this[i]).getPropertyValue(arguments[0])
// return window.getComputedStyle(this[i]).arguments[ 0];
}
}
return this;
}
//get实现
jQuery.prototype.get = function (num) {
//参数为空
if (num == null) {
//返回一个真数组
return [].slice.call(this, 0)
} else {
if (num >= 0) {
return this[num];
} else {
return this[this.length + num]
}
}
}
//eq实现
jQuery.prototype.eq = function (num) {
var dom = num != null ? (num >= 0 ? this[num] : this[num + this.length]) : null
return jQuery(dom)
}
//add实现
jQuery.prototype.add = function (adddom) {
if (adddom instanceof HTMLElement) {
this[this.length] = adddom;
this.length++;
return this;
}
if (typeof adddom == 'string') {
var arr = adddom.split(',')
for (var j = 0; j < arr.length; j++) {
this[this.length] = jQuery(arr[j])[0];
this.length++;
}
return this;
}
if (adddom.__proto__.constructor instanceof Object) {
this[this.length] = adddom[0];
this.length++;
return this;
}
}
//end实现
jQuery.prototype.end = function () {
this[this.length] = this[0].parentNode
this.length++;
return jQuery(this[this.length - 1]);
}
//init对象的原型指向jQuery原型
jQuery.prototype.init.prototype = jQuery.prototype
window.$ = window.jQuery = jQuery;
})()

本文首发于前端黑洞网,博客园同步跟新


0 评论

回复