写一个简单的jQuery
jQuery中—闭包
-
使用匿名函数 或 闭包实现局部变量避免变量的全局污染
- (function() {})()
-
window全局方法
- window.$ = window.jQuery
-
jQuery无new 操作
- 结论
function jQuery() {
return new jQuery.prototype.init();
}
// 再jQuery的原型上添加init方法
jQuery.prototype.init = function() { return this;}
// jQuery原型上的init方法的原型得到,jQuery原型上的所有方法,实现jQuery无new操作
jQuery.prototype.init.prototype = jQuery.prototype;
- each 与 回调函数
// 创建一个 each方法
// 把this李米娜的元素都传入到回调函数 执行一遍
jQuery.prototype.each = function(fn) {
// 把每个this对象都带入 fn 执行一次
for(var i = 0; i < this.length; i++) {
fn(this[i]);
}
}
// 创建一个添加标签class的方法
jQuery.prototype.addClass = function(val) {
this.each(function(item) {
item.classList.add(val);
})
}
- jQuery 扩展插件
- 全局方法:$.ajax();
- 对象方法: $(".contiainer").fullpage()
- jQuery.fn = jQuery.prototype
- jQuery.extend = jQuery.fn.extend = function(options){
var target = this;
// JQuery.extend this 指向jQuery 和JQuery.fn.extend this 指向实例
for(var k in options){ target[k] = options[k]}
// 执行浅拷贝
}
文档加载属性
- img.onload 图片开始加载
- document.addEventListener(“DOMContentLoaded”) 文档内容已经加载
- window.onload = function() {}
等待递归执行
- JQuery.ready(function(){}) 初始化调用
jQuery.ready = function(fn){
if(jQuery.isReay){
fn();
}else{
setTimeout(function(){jQuery.ready(fn) },10)
// 等待递归执行 // 如果超时可以报错
}
}
参数的多态
$(function(){
$("h1").on("click",function(){
$(this).toggleClass("red").toggleClass("light");
})
})
})
- $() 参数
- 函数:$(function)
- 字符串:$(“p”)
- 对象:$(this)
function(selector){
var str = typeof selector;
if(str === "function"){
jQuery.ready(selector);
// 如果 是一个函数 就当ready的回调函数执行
}
if(str === "object"){
this[0] = selector;
this.length = 1;
}
链式调用
- 每次函数执行都返回this当前执行对象
写一个很简单的jQuery
(function(){
function jQuery(selector){
return new jQuery.prototype.init(selector);
// 返回一个new init的出来的对象
}
jQuery.prototype.version = "2.0"
// 公用属性 version版本
jQuery.prototype.init = function(selector){
var str = typeof selector;
if(str === "function"){
jQuery.ready(selector);
// 如果 是一个函数 就当ready的回调函数执行
}else if(str === "object"){
this[0] = selector;
this.length = 1;
}else{
var elems = document.querySelectorAll(selector);
// 选择到所有元素
for(var i=0;i<elems.length;i++){
this[i] = elems[i];
}
// 设置 this 实例的元素
this.length = elems.length;
// 设置this 实例的长度
}
return this;
}
jQuery.prototype.each=function(fn){
// 把每个this对象都带入 fn 执行一次
for(var i=0; i<this.length;i++){
fn(this[i]);
}
return this;
}
jQuery.prototype.addClass=function(val){
this.each(function(elem){
// 匿名函数就是 fn,elem就是this[i]
elem.classList.add(val);
// 给elem 添加 val class
});
return this;
}
jQuery.prototype.removeClass=function(val){
this.each(function(elem){
elem.classList.remove(val);
});
}
jQuery.prototype.toggleClass=function(val){
this.each(function(elem){
elem.classList.toggle(val);
});
return this;
}
jQuery.prototype.on=function(type,fn){
this.each(function(elem){
elem.addEventListener(type,fn);
})
return this;
}
// 目标:实现插件扩展(全局方法,对象方法扩展)
jQuery.fn = jQuery.prototype; //protoytpe起个别名
jQuery.extend = jQuery.fn.extend =function(options){
var target = this;
for(var k in options){
target[k] = options[k];
}
// 拷贝所有扩展的方法
}
// 全局方法trim
jQuery.extend({
trim:function(str){return str.trim()}
// 把字符串移除掉空格 返回
})
// 添加对象方法 show hide
jQuery.fn.extend({
show:function(){
this.each(function(elem){
elem.style.display = "block";
})
return this;
},
hide:function(){
this.each(function(elem){
elem.style.display="none";
})
return this;
}
})
jQuery.ready = function(fn){
if(jQuery.isReady){
fn();
// 如果已经ready了 再去执行 回调函数 fn
}else{
setTimeout(function(){
jQuery.ready(fn)
},50) //如果没有成功等待50毫秒再执行一次
}
}
document.addEventListener("DOMContentLoaded",
function(){ jQuery.isReady = true;}
// 标识就jQuery已经准备好了
)
// 用户写 插件 $.fn.extend({fullpage:funciton(){}})
jQuery.prototype.init.prototype = jQuery.prototype;
// 让init方法 拥有 jquery原型上的所有方法和属性
window.$ = window.jQuery = jQuery;
// 给简写
})()