封装一个叫jQuery的函数
function jQuery(selector) {
return new jQuery.fn.init(selector)
}
封装一个可以选择这个类的函数例如$("类名")可选择这个标签
jQuery.fn.init = function (selector) {
// 获取到选择列表
var list = document.querySelectorAll(selector);
// 当前对象的长度
this.length = list.length;
for (var i = 0; i < list.length; i++) {
// 便利类别对this赋值
this[i] = list[i]
}
}
然后在通过全局,让这个定义的函数可以使用
// 如何让new init 产生对象拥有JQuery显示原型上的所有方法?
jQuery.fn.init.prototype = jQuery.fn;
// 全局对jQuery与$可以访问
window.$ = window.jQuery = jQuery
写一个click函数
思路是在jQuery里边的prototype里边写一个函数,通过用this来指向点击的这个元素,从而添加一个click事件
click(callback) {
//利用for循环来选择有几个一样的类,若为一个这选中,若为多个可利用for循环来各个添加click时间
for (var i = 0; i < this.length; i++) {
//选中这个元素然后利用addEventListener添加click事件
this[i].addEventListener("click", callback)
}
},
手写一个显示隐藏的函数
思路是首先定义一个toggle的函数,然后利用for循环选择指向的元素,然后判断一下子,如果这个元素里边的style属性有display!=none,让这个元素display = "none",反之则让这个display="block",利用上述的点击事件来完成点击执行这个函数,从而实现点击显示,在点击消失的功能
toggle() {
// 遍历每个元素如果display不是none就隐藏 否则显示
for (var i = 0; i < this.length; i++) {
if (this[i].style.display != "none") {
this[i].style.display = "none"
} else {
this[i].style.display = "block"
}
}
},
手写一个添加或者删除类的方法
这个方法其实很简单,也就是利用classList.add或者classList.remove来进行添加或者删除类的方法,同样利用for循环找到this指向的这个元素,从而给这个元素添加一个类或者删除一个类
addClass(callback) {
// classList.add
for (var i = 0; i < this.length; i++) {
this[i].classList.add(callback)
}
},
removeClass(callback) {
for (var i = 0; i < this.length; i++) {
this[i].classList.remove(callback)
}
}
写一个each函数
定义这个函数是为了让遍历这个元素,可在下边定义其他函数时用到,这样简化了代码,同样有利于jQuery的运行
each(callback) {
for (var i = 0; i < this.length; i++) {
callback(this[i]);
}
return this;
},
定义一个构造函数显示选型【上述写的函数都是添加到里边的】
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
jquery: "9.9.9",//版本号
length: 0,//长度
get(index) {
return this[index]
},
}
写extend方法
函数体中的this指的是 jQuery.fn = jQuery.prototype,因此是在原型上添加属性和方法。
jQuery.extend = jQuery.fn.extend = function(){
var target = arguments[0] || {},//第一个参数是目标对象
i=1,
length = arguments.length,//参数长度
deep = false,//是否深度拷贝
options,//用于在复制时记录参数对象
name,//用于在复制时记录 对象属性名
src,//用于复制时记录 目标对象的属性值
copy,//用于复制时记录 添加对象的属性值
copyIsArray,
clone;
if(typeof target === "boolean"){//第一个参数是布尔型,深度拷贝
deep = target;//深度拷贝,target赋值给deep
target = arguments[1] || {};//把第二个参数作为target
//跳过boolean和target 从第三个开始
i = 2;
}
//不是对象且不是函数 target置空 (string 或其他)
if(typeof target != "object" && typeof target != "function"){
target = {};
}
//如果传入一个参数,是对jquery的扩展
if(length == i}{//参数长度等于传递进去的长度 只能在等于1的时候
target = this;//this是jquery对象本身 在$.fn.extend()中表示jQuery函数所构造对象
--i;
}
for(;i<length;i++){
//只处理非空参数
if((options = arguments[i])!=null)
for (var name in options){
var src = target[name],//目标对象的属性值
copy = options[name];//待拷贝 对象或数组的属性值
if(target === copy){//存在目标对象本身的引用,构成死循环,结束此次遍历
continue;
}
//深度处理copy 最深为元素 值是纯对象或数组 拷贝原型链中的
if(deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))){
if(copyIsArray){//copy是数组
copyIsArray = false;
//clone是src的修正值 把当前的数组作为目标数组
clone = src && jQuery.isArray(src) ? src : [];
}else{//如果copy是对象 把当前的对象作为目标对象
clone = src && jQuery.isPlainObject(src) ? src :{};//src的修正值
}
//递归调用jQuery.extend 对copy迭代深度复制
target[name] = jQuery.extend(deep,clone,copy);
//如果不需要进行深度拷贝
}else if(copy! = undefined){
//直接将待增加的对象copy 复制给目标对象
target[name] = copy;
}
//原先的实现方式
/*if(deep && copy && typeof copy == "object" && !copy.nodeType)
target[name] = jQuery.extend(deep,src || (copy.length !=null ? [] : {}),copy);
else if(copy !== undefined)//不能拷贝空值
target[name] = copy;*/
}
}
return target;
};