打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
简易版jQuery

前面的话

  虽然jQuery已经日渐式微,但它里面的许多思想,如选择器、链式调用、方法函数化、取赋值合体等,有的已经变成了标准,有的一直影响到现在。所以,jQuery是一个伟大的前端框架。前端世界日新月异,由于实在是没有时间去精读源码,于是自己封装一个简易版本的jQuery,来梳理jQuery的核心思路

 

基本构架

  由于火柴的英文是match,应该将这个简单框架称为mQuery。使用面向对象的写法来写mQuery,构造函数是Mquery(),调用$()方法,将根据Mquery()构造函数,创建一个实例对象

//构造函数function Mquery(arg){}
function $(arg){  return new Mquery(arg);} 

  jquery几大特征:

  1、通过$()选择的元素都是一个集合,即使仅仅是一个元素

  因此,创建一个elements属性为一个数组,去接收获取的元素

//构造函数function Mquery(arg){  //保存所选择的元素  this.elements = [];}

  2、链式调用

  所以,原型函数要返回this,以实现链式调用的效果

 

$函数

  $函数根据参数类型的不同,用途也不同

  1、参数为函数时,则直接运行

$(function(){    console.log(1)})

  2、参数为对象时,则把DOM对象转换为$对象

$(document.body)

  3、参数为字符串时,则根据字符串选择出元素,并转换为$对象

$('#box')

  下面根据以上三个分类,来编写Mquery构建函数

//事件绑定兼容写法function _addEvent(target,type,handler){    if(target.addEventListener){        target.addEventListener(type,function(e){          //如果事件函数中出现 return false;则阻止默认事件和阻止冒泡          if(typeof handler == 'function' && handler() === false){            e.preventDefault();            e.cancelBubble = true;          }        },false);    }else{        target.attachEvent('on'+type,function(event){          if(typeof handler == 'function' && handler() === false){            event.cancelBubble = true;            event.returnValue = false;          }            return handler.call(target,event);        });    }}//将类数组转换成数组function _toArray(arrayLike){  return Array.prototype.slice.call(arrayLike);}
//构造函数function Mquery(arg){  //保存所选择的元素  this.elements = [];  switch(typeof arg){    //当参数是函数时,如$(function(){})(),直接运行里面的代码    case 'function':      _addEvent(window,'load',arg);      break;    //当参数是字符串时,选择元素    case 'string':      this.elements = _toArray(document.querySelectorAll(arg));                    break;    //当参数是DOM对象时,将DOM对象转换为$对象      case 'object':      if(arg.constructor == Array){        this.elements = arg;      }else{        this.elements.push(arg);      }            break;  }}

 

HTML、CSS及特性设置

  下面来介绍常用的HTML、CSS及特性设置

【HTML】

  对于文本内容来说,一般地,有三种方法:html()、text()和val()。本文只实现最常用的html()方法

  当html()方法没有参数时,表示获取内容;有一个参数时,表示设置内容

//HTML获取与设置Mquery.prototype.html = function(str){  //设置  if(str){    for(var i = 0; i < this.elements.length; i++){      this.elements[i].innerHTML = str;    }  //获取  }else{    return this.elements[0].innerHTML;  }    return this;}

【CSS】

  对于CSS来说,有两种参数格式:一种是json格式,一种是字符串格式

  当第一个参数为对象时,则判断为json格式,否则为字符串格式

  对于字符串格式来说,只有一个参数时,为获取样式,两个参数时,为设置样式

  获取样式时,仅获取当前集合中第0个元素的样式;设置样式时,则设置当前集合中所有元素的样式

//获取计算样式兼容写法function _getCSS(obj,style){    if(window.getComputedStyle){        return getComputedStyle(obj)[style];    }    return obj.currentStyle[style];}
//CSS获取与设置Mquery.prototype.css = function(attr,value){  //如果是对象的形式,以对象的形式设置  if(typeof attr == 'object'){    for(var att in attr){      for(var j = 0; j < this.elements.length; j++){        this.elements[j].style[att] = attr[att];      }    }  //如果不是对象的形式  }else{    //设置    if(arguments.length == 2){      for(var i = 0; i < this.elements.length; i++){        this.elements[i].style[attr] = value;      }    //获取    }else if(arguments.length == 1){      return _getCSS(this.elements[0],attr)    }  }  return this;}

【attr】

  特性设置与获取的思路与CSS类似,只是方法变成了setAttribute()和getAttribute()

//attr获取与设置Mquery.prototype.attr = function(attr,value){  //如果是对象的形式  if(typeof attr == 'object'){    for(var att in attr){      for(var j = 0; j < this.elements.length; j++){        this.elements[j].setAttribute(att,attr[att]);      }    }  //如果不是对象的形式  }else{    //设置    if(arguments.length == 2){      for(var i = 0; i < this.elements.length; i++){        this.elements[i].setAttribute(attr,value);      }    //获取    }else if(arguments.length == 1){      return this.elements[0].getAttribute(attr);    }  }  return this;}

 

事件绑定

【on】

  在jQuery中,最常用的事件绑定方法就是on方法。在on方法中要特别注意的是this的绑定,由于函数fn中的this实际上是window,所以应该将fn的this绑定到当前元素

//事件绑定Mquery.prototype.on = function(eventType,fn){  for(var i = 0; i < this.elements.length; i++){    _addEvent(this.elements[i],eventType,fn.bind(this.elements[i));  }  return this;}

【click和hover】

  click方法是一个简写方法

Mquery.prototype.click = function(fn){  this.on('click',fn);  return this;}

  hover方法是mouseover和mouseout的合成方法

Mquery.prototype.hover = function(fnOver,fnOut){  this.on('mouseover',fnOver);  this.on('mouseout',fnOut);  return this;}

【return false】

  在jQuery中,使用return false可以同时阻止默认行为和阻止冒泡

//事件绑定兼容写法function _addEvent(target,type,handler){    if(target.addEventListener){        target.addEventListener(type,function(e){          //如果事件函数中出现 return false;则阻止默认事件和阻止冒泡          if(typeof handler == 'function' && handler() === false){            e.preventDefault();            e.cancelBubble = true;          }        },false);    }else{        target.attachEvent('on'+type,function(event){          if(typeof handler == 'function' && handler() === false){            event.cancelBubble = true;            event.returnValue = false;          }            return handler.call(target,event);        });    }}

 

其他设置

  jQuery的功能非常强大。下面选择一些常用功能进行实现

【显示隐藏】

//隐藏Mquery.prototype.hide = function(){  for(var i = 0; i < this.elements.length; i++){    //保存当前元素的display值    this.elements[i].displayValue = this.elements[i].style.display;    this.elements[i].style.display = 'none';  }  return this;}//显示Mquery.prototype.show = function(){  for(var i = 0; i < this.elements.length; i++){   this.elements[i].style.display = this.elements[i].displayValue;   //删除保存的元素的display值   delete this.elements[i].displayValue;  }  return this;}

【插件设置】

$.extend = function(json){   for(var attr in json){    $[attr] = json[attr];  }};$.fn = {};$.fn.extend = function(json){  for(var attr in json){    Mquery.prototype[attr] = json[attr];  } };

【索引设置】

//根据索引选择元素Mquery.prototype.eq = function(number){  return $(this.elements[number]);}//根据元素获取索引Mquery.prototype.index = function(){  var elements = this.elements[0].parentNode.children;  for(var i = 0; i < elements.length; i++){    if(elements[i] === this.elements[0]){      return i;    }  }}

【子级筛选】

//筛选出当前匹配的元素集合中每个元素的后代Mquery.prototype.find = function(str){  var arr = [];  for(var i = 0; i < this.elements.length; i++){    Array.prototype.push.apply(arr,this.elements[i].querySelectorAll(str));  }  return $(arr);}

 

完整源码

  下面是mQuery的完整源码

//事件绑定兼容写法function _addEvent(target,type,handler){    if(target.addEventListener){        target.addEventListener(type,function(e){          //如果事件函数中出现 return false;则阻止默认事件和阻止冒泡          if(typeof handler == 'function' && handler() === false){            e.preventDefault();            e.cancelBubble = true;          }        },false);    }else{        target.attachEvent('on'+type,function(event){          if(typeof handler == 'function' && handler() === false){            event.cancelBubble = true;            event.returnValue = false;          }            return handler.call(target,event);        });    }}//获取计算样式兼容写法function _getCSS(obj,style){    if(window.getComputedStyle){        return getComputedStyle(obj)[style];    }    return obj.currentStyle[style];}//将类数组转换成数组function _toArray(arrayLike){  return Array.prototype.slice.call(arrayLike);}//构造函数function Mquery(arg){  //保存所选择的元素  this.elements = [];  switch(typeof arg){    //当参数是函数时,如$(function(){})(),直接运行里面的代码    case 'function':      _addEvent(window,'load',arg);      break;    //当参数是字符串时,选择元素    case 'string':      this.elements = _toArray(document.querySelectorAll(arg));                    break;    //当参数是DOM对象时,将DOM对象转换为$对象      case 'object':      if(arg.constructor == Array){        this.elements = arg;      }else{        this.elements.push(arg);      }            break;  }}//根据索引选择元素Mquery.prototype.eq = function(number){  return $(this.elements[number]);}//根据元素获取索引Mquery.prototype.index = function(){  var elements = this.elements[0].parentNode.children;  for(var i = 0; i < elements.length; i++){    if(elements[i] === this.elements[0]){      return i;    }  }}//筛选出当前匹配的元素集合中每个元素的后代Mquery.prototype.find = function(str){  var arr = [];  for(var i = 0; i < this.elements.length; i++){    Array.prototype.push.apply(arr,this.elements[i].querySelectorAll(str));  }  return $(arr);}//CSS获取与设置Mquery.prototype.css = function(attr,value){  //如果是对象的形式,以对象的形式设置  if(typeof attr == 'object'){    for(var att in attr){      for(var j = 0; j < this.elements.length; j++){        this.elements[j].style[att] = attr[att];      }    }  //如果不是对象的形式  }else{    //设置    if(arguments.length == 2){      for(var i = 0; i < this.elements.length; i++){        this.elements[i].style[attr] = value;      }    //获取    }else if(arguments.length == 1){      return _getCSS(this.elements[0],attr)    }  }  return this;}//attr获取与设置Mquery.prototype.attr = function(attr,value){  //如果是对象的形式  if(typeof attr == 'object'){    for(var att in attr){      for(var j = 0; j < this.elements.length; j++){        this.elements[j].setAttribute(att,attr[att]);      }    }  //如果不是对象的形式  }else{    //设置    if(arguments.length == 2){      for(var i = 0; i < this.elements.length; i++){        this.elements[i].setAttribute(attr,value);      }    //获取    }else if(arguments.length == 1){      return this.elements[0].getAttribute(attr);    }  }  return this;}//HTML获取与设置Mquery.prototype.html = function(str){  //设置  if(str){    for(var i = 0; i < this.elements.length; i++){      this.elements[i].innerHTML = str;    }  //获取  }else{    return this.elements[0].innerHTML;  }    return this;}//隐藏Mquery.prototype.hide = function(){  for(var i = 0; i < this.elements.length; i++){    //保存当前元素的display值    this.elements[i].displayValue = this.elements[i].style.display;    this.elements[i].style.display = 'none';  }  return this;}//显示Mquery.prototype.show = function(){  for(var i = 0; i < this.elements.length; i++){   this.elements[i].style.display = this.elements[i].displayValue;   //删除保存的元素的display值   delete this.elements[i].displayValue;  }  return this;}//事件绑定Mquery.prototype.on = function(eventType,fn){  for(var i = 0; i < this.elements.length; i++){    _addEvent(this.elements[i],eventType,fn.bind(this.elements[i]));  }  return this;}//click简写Mquery.prototype.click = function(fn){  this.on('click',fn);  return this;}//鼠标移入移出Mquery.prototype.hover = function(fnOver,fnOut){  this.on('mouseover',fnOver);  this.on('mouseout',fnOut);  return this;}$.extend = function(json){   for(var attr in json){    $[attr] = json[attr];  }};$.fn = {};$.fn.extend = function(json){  for(var attr in json){    Mquery.prototype[attr] = json[attr];  } };function $(arg){  return new Mquery(arg);} 

 

实际应用

  下面使用mQuery来实现一个简单的效果

<style>div { width:60px; height:60px; margin:5px; float:left; }</style><span id="result"></span><div style="background-color:blue;"></div><div style="background-color:rgb(15,99,30);"></div><div style="background-color:#123456;"></div><div style="background-color:#f11;"></div><script src="mQuery.js"></script><script>$("div").click(function(){ $("#result").html("背景颜色是 " + $(this).css("background-color"));})</script> 

  点击不同颜色的元素块,将在右侧显示具体的颜色值

  

 

好的代码像粥一样,都是用时间熬出来的
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
项目开发中非常有用的js处理函数(本人原创)
原生JS模拟Bootstrap中的折叠(Collapse)插件
小谈Jquery框架
JS判断元素是否在数组内
cve2016-1646漏洞利用
JScript Array对象的几个原型方法
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服