写一个简单的jQuery
- jQuery中—闭包
- 文档加载属性
- 等待递归执行
- 参数的多态
- 链式调用
- 写一个很简单的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];}// 拷贝所有扩展的方法}// 全局方法trimjQuery.extend({trim:function(str){return str.trim()}// 把字符串移除掉空格 返回})// 添加对象方法 show hidejQuery.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;// 给简写})()