今天是2019年5月12号——母亲节,小编先祝天下妈妈节日快乐。最近总结了关于jQuery一些常用方法及实现的原理,这些方法也是项目经常会用到的,以后也方便自己看,所以记录下来了。
首先,引入jQuery之后,不妨打印一下$和jquery看下:
也就是说,$符号返回的是一个函数,我们平时用调用$()的时候,本质上就是去执行了上边的这个函数,而函数执行它会返回一个jQuery对象(就是一个类数组),之所以用$而不用jQuery因为$符号写起来方便。
$()这个括号里边传递的参数可以是css选择器(字符串形式的)、原生dom、jquery特有的选择器(字符串形式的)、函数,如:
————————————传css选择器、jquery特有的选择器:
$(".wrapper ul li")————//选择出wrapper下的ul下的所有的li,跟css选择器一样;
$(".wrapper ul li:first")————//选择出wrapper下的ul下的第一个li,jQuery特有选择器;
$(".wrapper ul li:last")————//选择出wrapper下的ul下的最后一个li,jQuery特有选择器;
$(".wrapper ul li:odd")————//选择出wrapper下的ul下的是奇数的li,(从0开始查),jQuery特有选择器;
$(".wrapper ul li:even")————//选择出wrapper下的ul下的是偶数的li,(从0开始查),jQuery特有选择器;
$(".wrapper ul li:eq(0)")————//选择出wrapper下的ul下的第一个li,如果是负一,则返回最后一个,eq()是选择某一个li,jQuery特有选择器;
$("wrapper ul li[data='lvxingchen']")————//自定义属性选择器,选择出wrapper下的ul下的li中有data='lvxingchen'属性的li,可先联想到选择对象的属性,jQuery特有选择器;
————————————传原生dom:
$("div")————//选择出所有div元素,
————————————传函数function:
$(function () {})这个写法就是$(document).ready(function () {})的简写, 当dom加载完毕之后再执行,面试经常会问到!!!
还有一个window.onload = function () {} ,这个是当所有资源全加载完之后执行!!!
先执行$(function () {}),后执行window.onload = function () {}
以上就是$()括号中传递的类型,那问题来了,为什么传递上边这些参数jQuery会帮我们选择出对应的dom元素呢,下边我们剖析下jQuery元素选择及链式调用的原理:
看到jQuery源码的时候,会看到许多变量,我们自己写的变量与jQuery这个库中的变量万一一样了怎么办,jQuery是采用了闭包来解决这个问题的,用闭包来封闭了自己的作用域,怎么封闭作用域了呢,它外边包了一个立即执行函数(function(){})(),当立即执行函数执行完之后,内部的函数不会销毁,因为全局window对象保存了内部这个函数,也就是说把内部函数当做一个方法,挂载到全局window对象上边了,js引擎也不会把它当做垃圾销毁掉,这样就形成了闭包。
jquery中元素选择和链式调用怎样实现的:
(function () {//外层包裹的立即执行函数
function jQuery(selector){
return new jQuery.prototype.init(selector);// 这个jQuery函数里边返回jQuery.prototype.init这个构造函数 构造出来的对象
}
// jQuery.prototype.init这个构造函数它的作用是:判断selector是哪一类选择器并返回包装好的jquery对象
// 我们知道构造函数里边会【隐式】的创建一个空对象 <1> var this = {}; <2> 然后给空对象添加属性及方法; <3>【隐式】返回this————return this
jQuery.prototype.init = function(selector){
// this = {}
this.length = 0;//因为jquery返回的是一个类数组,所以有length这个属性
//下边我们以class和id选择器为例,简单的判断了一下,没有考虑太多,只是说下原理!!!
if ( selector.indexOf(".") != -1 ){//如果传来的selector有点,说明是class选择器
var dom = document.getElementsByClassName(selector.slice(1));
}else if ( selector.indexOf("#") != -1 ){//如果传来的selector有#,说明是id选择器
var dom = document.getElementById(selector.slice(1));
}
if ( dom.length == undefined ) {//判断下选择出来的dom元素是否是由length的,如果没有肯定是带有id的元素
this[0] = dom;//直接把dom赋值给对象this第0位
this.length ++ ;//长度++
}else{//反之,有length,说明选择出来的是带有class类型的元素,循环,把每一个dom元素都赋值给对象this,每次赋值,length都++
for ( var i = 0 ; i < dom.length ; i ++ ) {
this[i] = dom[i];
this.length ++ ;
}
}
// return this 隐式的返回对象this
};
// 这个方法是解析传递过来的对象及链式调用,我们这jQuery原型上边加了一个css方法,对象config参数就是下边传递的要改变元素的样式
jQuery.prototype.css = function(config){
for( var i = 0 ; i < this.length ; i ++ ){//循环里这个this指向上边构造函数返回出来的jq对像
for( attr in config ){//循坏config对象
this[i].style[attr] = config[attr];//把jq对象中的每一位,根据下边传递过来的属性赋值相对应的值
}
}
return this;//在把jq对象返回出去,右边又可以进行属性或方法的调用了,这就是链式调用的原理
}
// 因为最上边的jQuery.prototype.init构造函数,构造出来的对象,上边没有css方法,
// 所以我们把jQuery.prototype.init的原型等于 jQuery的原型,因为jQuery原型上边有css方法
jQuery.prototype.init.prototype = jQuery.prototype;
window.$ = window.jQuery = jQuery;//把上边jQuery这个函数挂载到window上边
})()
hml代码:
<div>
<div id="wrapper">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
当我们测试下:
$(".box")
.css({width:"100px",height:"100px",background:"red"})
.css({color:"#fff"})
返回的结果:
已实现!
以上我们只是以class和id选择器为例,做的判断,实际源码中要复杂的多,但是原理是一样的。
后续,我也会陆陆续续出一些jQuery中常用方法的实现原理,希望大家多多关注,有什么疑问欢迎留言,小编一定会在第一时间给您答复!