简易版jQuery——mQuery

前面的话

  虽然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> 

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

  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/257446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LaTeX 安装配置 OSX

LaTeX 安装配置 OSX官方网站&#xff1a;http://www.latex-project.orghttp://www.tug.org/mactex/http://pages.uoregon.edu/koch/BasicTeX.pdf完整的Tex超过2G&#xff0c;一般用户没必要&#xff0c;可以先安装BasicTeX&#xff0c;当有需要时include必要的库即可1.安装Basi…

php 正三角塔,PHP 环境塔建与数据类型转换

手动塔建PHP开发环境安装php c:\apps\php安装apache c:\apps\apache1.配制apache配制c:\apps\apache\conf\httpd.confDocumentRoot"c:/apps/www" //指定工作目录,WWW为自已创健Directoryindex index.php index.html // 加入:loadModule php5_module "c:\apps\PH…

C/C++基础知识:函数指针和指针函数的基本概念

【函数指针】 在程序运行中&#xff0c;函数代码是程序的算法指令部分&#xff0c;它们和数组一样也占用存储空间&#xff0c;都有相应的地址。可以使用指针变量指向数组的首地址&#xff0c;也可以使用指针变量指向函数代码的首地址&#xff0c;指向函数代码首地址的指针…

告警系统邮件引擎

2019独角兽企业重金招聘Python工程师标准>>> 20.23-20.25 告警系统邮件引擎 创建发邮件的脚本——mail.py [rootlocalhost mail]# pwd /usr/local/sbin/mon/mail[rootlocalhost mail]# vim mail.py #!/usr/bin/env python #-*- coding: UTF-8 -*- import os,sys rel…

【HTTP 2】简介(Introduction)

前情提要 在上一篇文章《【HTTP 2.0】 序言》中&#xff0c;我们简要介绍了 HTTP 2 协议的概要和协议状态。 在本篇文章中&#xff0c;我们将会了解到 HTTP 2 协议简介&#xff08;Introduction&#xff09;部分的内容。 简介&#xff08;Introduction&#xff09; 超文本传输协…

java测试类生成对象,java编写student类 用Java编写一段测试程序,生成student类的两个对象,并输出每个对象基本信息?...

java中怎么创建对象数组&#xff1f;比如我创建了一个学生类Student&#xff0c;怎么用这个类创建一个对象数组&#xff0c;麻烦给个例子&#xff1f;学生类&#xff1a;classA{privateStringnameprivateintagepublicStringgetName(){returnname}publicvoidsetName(Stringname)…

iOS -- SKScene类

SKScene类 继承自SKEffectNode:SKNode:UIResponder:NSObject符合NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObject)框架 /System/Library/Frameworks/SpriteKit.framework可用性可用于iOS 7.0或者更晚的版本声明于SKScene.h参考指南Sprite Kit Progamming Guide概览 重要提…

SSD硬盘 全盘安全擦除

此文From http://ssd.zol.com.cn/575/5753057.html 在SSD固态硬盘的使用过程中&#xff0c;部分用户可能会碰到计算机意外掉电或死机并强行断电后&#xff0c;系统出现异常&#xff0c;扫描SSD后发现坏块&#xff0c;然后一着急一跺脚甚至想返厂维修。 其实掉电后固态硬盘出现坏…

php中等3秒再跳转,跳转和重定向

页面跳转在应用开发中&#xff0c;经常会遇到一些带有提示信息的跳转页面&#xff0c;例如操作成功或者操作错误页面&#xff0c;并且自动跳转到另外一个目标页面。系统的ThinkController类内置了两个跳转方法success和error&#xff0c;用于页面跳转提示&#xff0c;而且可以支…

2017敏捷沙滩大会:完美软件,测量持续交付,以及探索未来

在英国康沃尔郡举行的2017敏捷沙滩大会上&#xff0c;数百名演讲者和参与者共聚一堂&#xff0c;探讨敏捷和后敏捷领域软件开发方法有哪些最新进展。本次大会最后一个下午的要点包括&#xff1a;交付团队可以通过拥抱精益、迭代和持续的部署方法更快速地实现业务价值&#xff1…

做fzu oj 1045 做减法学到的sprintf()函数

题目 做题一直输不出答案&#xff0c;于是就上网去百度了这题的解题&#xff0c;发现解答十分的简短&#xff0c;而且其中我看见了平时没见过的函数&#xff0c;sprintf()。 于是就百度sprintf()的使用。 如下&#xff1a; 函数功能&#xff1a;把格式化的数据写入某个字符串 函…

动态内存分配及变量存储类别(第二部分)

5. C语言变量的存储类别和生存期 我们知道&#xff0c;变量是有数据类型的&#xff0c;用以说明它占用多大的内存空间&#xff0c;可以进行什么样的操作。除了数据类型&#xff0c;变量还有一个属性&#xff0c;称为“存储类别”。存储类别就是数据在内存中的存放区域。一个正在…

oracle的em能干什么,转载 解决Oracle的EM登录

转载 解决Oracle的EM登录(2011-03-13 20:53:39)标签&#xff1a;杂谈这几天解决了EM无法登录的问题&#xff0c;顺便也把j数据库程序中常出现的ORA_12518错误解决了&#xff0c;有必要总结一下&#xff0c;我最初遇到的情况是这样的&#xff1a;1. 编写java程序访问oracle数据库…

python 回溯法 子集树模板 系列 —— 1、8 皇后问题

问题 88格的国际象棋上摆放八个皇后&#xff0c;使其不能互相攻击&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上&#xff0c;问有多少种摆法。 分析 为了简化问题&#xff0c;考虑到8个皇后不同行&#xff0c;则每一行放置一个皇后&#xff0c;每一行的皇后…

Core Java Volume I — 3.6. Strings

3.6. StringsConceptually, Java strings are sequences of Unicode characters&#xff08;Java的字符串是一个Unicode序列&#xff09;. For example, the string "Java\u2122" consists of the five Unicode characters J, a, v, a, and ?. Java does not have a…

Android实用代码七段(五)

前言 每次分享意味着每次都有进步&#xff0c;本系列以实用为主&#xff0c;欢迎和我分享和推荐好用的代码段~~声明欢迎转载&#xff0c;但请保留文章原始出处:) 博客园&#xff1a;http://www.cnblogs.com农民伯伯&#xff1a; http://over140.cnblogs.com 正文 1、展开、收起…

oracle 自增1,oracle自增无法从1开始

问题描述我想让XH字段从1开始增加,由于是varchar类型的,所以就用这种方式,但我发现我的数据表中XH字段是从217开始增加的,为什么啊问题出现的环境背景及自己尝试过哪些方法相关代码// 请把代码文本粘贴到下方(请勿用图片代替代码)declarej number;i number;begini:1;j:1;for i …

ceph Luminous版手动安装零散记录

1.安装必要的依赖包&#xff0c;关防火墙&#xff0c;向/etc/hosts内添加域名等 2.安装ceph 配置yum源 (如果嫌慢&#xff0c;可以配置cachedir/home/yum/$basearch/$releasever和keepcache1两个参数&#xff0c;在第一次安装时将安装包下载到本地做成yum源&#xff0c;给后面的…

C#最简单最完整的webservice实例

我做java&#xff0c;但最近接触crm所以必须研究一下C#中的webservice以备后用&#xff0c;其实就是个新手&#xff0c;哈哈&#xff0c;这个实例是我在参考了网上诸多不完整的例子的情况下&#xff0c;自己摸索完成的。期间遇到过一系列的棘手的问题&#xff0c;经过个人努力终…

2015 UESTC 数据结构专题G题 秋实大哥去打工 单调栈

秋实大哥去打工 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59Description 天行健&#xff0c;君子以自强不息。地势坤&#xff0c;君子以厚德载物。天天过节的秋实大哥又要过节了&#xff0c;于是他要给心爱的妹子买礼物。但由…