// jquery的所有对象都封装在闭包上
// 闭包防止全局变量污染
(function(){
function jQuery(selector){
return new jQuery.prototype.init(selector)
}
// 通过传进来的参数selector来查找元素,init为初始化的意思
jQuery.prototype.init = function(selector){
// this = {}
this.length = 0;
// null undefined dom
if(selector == null){
return this
}
// 根据selector参数选出对应的dom元素包装成一个对象进行返回
// id class
if(typeof selector == "string" && selector.indexOf('.') != -1){
var dom = document.getElementsByClassName( selector.slice(1) )//类数组
}else if(typeof selector == "string" && selector.indexOf('#') != -1){
var dom = document.getElementById( selector.slice(1) )//一个
}
// 如果传进来一个dom原生对象就不需要查找元素,直接把它放到返回的jquery对象中就好
if(selector instanceof Element || dom.length == undefined){
// id dom
this[0] = dom || selector;
this.length ++;
}else{
for(var i = 0;i < dom.length;i++){
this[i] = dom[i]
this.length ++;
}
}
// return this;
}
jQuery.prototype.css = function(config){
// this
for(var i = 0;i < this.length;i++){
for(var attr in config){
this[i].style[attr] = config[attr]
}
}
return this;
}
jQuery.prototype.get = function(num){
return num != null ? ( num >= 0 ? this[num] : this[this.length + num]) : ([].slice.call(this,0))
}
// 实现绑定自定义事件,不写实现系统事件
jQuery.prototype.myOn = function(type,handle){
for(var i = 0 ; i< this.length; i++){
// 因为在循环中,我们需要加一个判断,判断有没有存储事件的空间: this[i].cacheEvent
if( !this[i].cacheEvent ){
// 如果一个dom元素上没有缓存事件,我们需要添加一个存储位置来存储所有要绑定的事件
this[i].cacheEvent = {};
}
if( !this[i].cacheEvent[type]){
this[i].cacheEvent[type] = [handle]
}else{
this[i].cacheEvent[type].push(handle)
}
}
}
jQuery.prototype.myTrigger = function(type){
// 判断参数有几个
var params = arguments.length > 1 ? [].slice.call(arguments,1) : [];
var self = this;
for( var i = 0 ; i < this.length;i++ ){
this[i].cacheEvent[type].forEach(function(ele,index){
ele.apply(self,params)
})
}
}
jQuery.prototype.eq = function(num){
var dom = num != null ? ( num >= 0 ? this[num] : this[this.length + num]) : null;
return jQuery(dom)
}
jQuery.prototype.queue = function(type,handle){
// 保存this
var queueObj = this;
// fx是animate方法的内置队列名
var queueName = type || 'fx';
var addFunc = handle || null;
// 用参数长度判断queue方法是创建队列还是查看队列
var len = arguments.length;
if(len == 1){
return queueObj[0][queueName]
}
// 添加队列或已有的队列中添加内容
// dom:queueObj[0]
queueObj[0][queueName] == undefined ? queueObj[0][queueName] = [addFunc] : queueObj[0][queueName].push(addFunc)
return this;
}
jQuery.prototype.dequeue = function(type){
var self = this;
var queueName = type || 'fx';//
// 取出队列数组
var queueArr = this.queue(type)//[f(1),f(2),f(3)]
// 把数组队列汇总的第一个内容取出
var currFunc = queueArr.shift()//f(3)
if(currFunc == undefined){
return;
}
// 但是在内容执行别忘了next技巧,造成一列穿的取出队列,递归思想
var next = function(){
self.dequeue(queueName)
}
currFunc(next)
return this;
}
jQuery.prototype.delay = function(duration){
// 把dom中的名为fx的队列
var queueArr = this[0]['fx'];
queueArr.push(function(next){
setTimeout(function(){
next()
},duration)
})
return this;
}
jQuery.prototype.animate = function(json,duration,callback){
var len = this.length;
var self = this;
// 创建一个内容函数,最后把内容函数添加到队列中,这个内容函数中肯定包含物体运动
var baseFunc = function(next){
// 创建一个开关,判断是否所有的物体都进行了运动 times == len
var times = 0;
// 利用for循环让每一个元素都添加运动方法
for(var i = 0 ; i < len;i++){
startMove(self[i],json,function (){
times ++;
if(times == len){
callback && callback()
next()
}
})
}
}
this.queue('fx',baseFunc)
if(this.queue('fx').length == 1){
this.dequeue('fx')
}
function startMove(dom, attrObj,callback) { // 传入一个元素,我让元素运动城你想要的的目标
clearInterval(dom.timer)
var iSpeed = null,
iCur = null;
dom.timer = setInterval(function () {
var bStop = true;
for (var attr in attrObj) {
if (attr == "opacity") {
iCur = parseFloat(getStyle(dom, attr)) * 100
} else {
iCur = parseFloat(getStyle(dom, attr))
}
iSpeed = (attrObj[attr] - iCur) / 7;
iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed)
if (attr == "opacity") {
dom.style.opacity = (iCur + iSpeed) / 100
} else {
dom.style[attr] = iCur + iSpeed + "px"
}
if(iCur != attrObj[attr]){
bStop = false
}
}
if(bStop){
clearInterval(dom.timer)
typeof callback == "function" && callback()
}
}, 30)
}
function getStyle(dom,attr){
if(window.getComputedStyle){
return window.getComputedStyle(dom,null)[attr]
}else{
return dom.currentStyle[attr]
}
}
return this;
}
jQuery.prototype.init.prototype = jQuery.prototype;
// 闭包思想:函数执行完以后函数里面的变量不会被释放
window.$ = window.jQuery = jQuery;
})()
Jquery底层封装
最新推荐文章于 2023-07-12 15:39:49 发布