简易版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>
点击不同颜色的元素块,将在右侧显示具体的颜色值
简易版jQuery——mQuery的更多相关文章
- 简易版jquery
最近写了一个简易版的jquery github地址:https://github.com/jiangzhenfei/Easy-Jquery 完成的方法: 1.$('#id') 2.extend扩展 ...
- 贫下中农版jQuery
之前写过一篇JavaScript命名空间的文章,写完后一对比对jQuery的简单使用很是惊羡,看了看人家源码,用的原理很类似啊,改进一下之前的版本,做个简易版的jQuery 之前的代码 (functi ...
- 学生管理系统(SSM简易版)总结
之前用 Servlet + JSP 实现了一个简易版的学生管理系统,在学习了 SSM 框架之后,我们来对之前写过的项目重构一下! 技术准备 为了完成这个项目,需要掌握如下技术: Java 基础知识 前 ...
- 实现简易版德州扑克|学习麻瓜编程以项目为导向入门前端 HTML+CSS+JS
实现简易版德州扑克 1.先上达到网页效果图(简易版德州扑克) 网页分为发牌区和牌池,上面为发牌区,下面是牌池区 2. 代码实现 2.1 HTML和JS代码 ` <link rel="s ...
- .NET Core的文件系统[5]:扩展文件系统构建一个简易版“云盘”
FileProvider构建了一个抽象文件系统,作为它的两个具体实现,PhysicalFileProvider和EmbeddedFileProvider则分别为我们构建了一个物理文件系统和程序集内嵌文 ...
- MVC 验证码实现( 简易版)
现在网站上越来越多的验证码,使用场景也是越来越多,登陆.注册.上传.下载...等等地方,都有可能大量使用到验证码,那么制作验证码到底有多简单呢?我们一起来看下最简易版的验证码实现过程- 验证码的基本步 ...
- 简易版自定义BaseServlet
这几天在学Java Web,一直在思考Servlet重用的问题,就用java的反射机制实现自定义的简易版BaseServlet; 该方式有点像struts2 利用映射获取前端的参数.有兴趣的同学可以自 ...
- 简易版的TimSort排序算法
欢迎探讨,如有错误敬请指正 如需转载,请注明出处http://www.cnblogs.com/nullzx/ 1. 简易版本TimSort排序算法原理与实现 TimSort排序算法是Python和Ja ...
- 迷你版jQuery——zepto核心源码分析
前言 zepto号称迷你版jQuery,并且成为移动端dom操作库的首选 事实上zepto很多时候只是借用了jQuery的名气,保持了与其基本一致的API,其内部实现早已面目全非! 艾伦分析了jQue ...
随机推荐
- mysql存储过程详细讲解及完整实例下载
一.存储过程概念 1.存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集.经编译后存储在数据库 中. 2.存储过程是数据库中的一个重要对象,用户通过指定存储过程的名字并给 ...
- Linq to Objects for Java 发布 1.0.1 版本
现在 java 支持 linq 啦.比原生 stream api 更好用,功能更强大.现已发布 version 1.0.1 地址: https://github.com/timandy/linq. A ...
- C++数组和指针加减法和sizeof问题
关于指针和加减法: 指针的加减法:指针的加减法,加多少或者减多少,主要是看所指对象的sizeof值. 例子: double m = 3.0; ; double *p=&m; int* p1=& ...
- dll的两种加载方式(pend)+ delayload
看过关于动态库的调用例子,于是决定动手做一做:dll的对外接口声明头文件,Mydll.h: //Mydll.h #include <stdio.h> #include <stdlib ...
- CSS中的盒模型
CSS的盒模型描述了一些长方形盒子,这些长方形盒子被用来表示文档树中的元素,并根据视觉格式化模型进行定位. 1. 盒子的尺寸 每个盒子都有一个content区域(比如文本.图片等)和可选的包围cont ...
- StringBulider简单用法
StringBuild的是个动态对象,可直接拼加上字符串:而string对象的步骤:先初始化对象并赋值了,而后在拼加字符串时,先要创建需要拼加的字符串,然后再拼加,所以这就是StirngBuild远比 ...
- 为什么我们要使用Async、Await关键字
前不久,在工作中由于默认(xihuan)使用Async.Await关键字受到了很多质问,所以由此引发这篇博文“为什么我们要用Async/Await关键字”,请听下面分解: Async/Await关键字 ...
- 删除多余的win10软件
第一步:开始→所有程序→WindowsPowershell→然后右键以管理员方式运行 全部应用: Get-AppxPackage | Remove-AppxPackage 计算器: Get-AppxP ...
- java 数组去重总结
如果一个数组中有重复元素,用什么方法可以去重?有其他方法继续更新 一.用List集合实现 int[] str = {5, 6, 6, 6, 8, 8, 7,4}; List<Integer> ...
- Struts2学习笔记(十一)——文件上传
1.单文件上传 单文件上传步骤: 1)创建上传jsp页面 文件上传的表单提交方式必须是POST方式,编码类型:enctype="multipart/form-data",默认是 a ...