zepto源码研究 - zepto.js-4(常用的工具)
2016-07-08 21:57
351 查看
$.each:
这里的elements可以是数组或者对象,如果是对象,则会将其原型里面的属性也遍历出来,最后返回elments本身,如果回调函数返回了false,则终止循环
remove:
这里的重点是parentNode.removeChild(this);如果是没有父节点的这里不会执行。
is:
例如$("#id").is(".hasClass");实际就是调用matches进行匹配
not:
这里首先判断selector是否为函数,如果是,则遍历执行函数,如果返回false,则push到数组中
如果css选择字符串则调用this.filter(seelctor),这里有个小技巧使得not和filter相互调用
如果是数组或对象,则直接返回$(他自己)
最后遍历this,只要不是在excludes里面的都是满足条件的
has:
重点提示下:这里的this如果也满足selector,则最后返回的结果集里也会有this
show:
this.style.display=''是清除元素的style里面的display样式,恢复元素的默认样式。
getComputedStyle(dom)能获取dom的所有css样式,第二个参数可以不传
getComputedStyle(dom,":after")能获取dom的:after伪类的所有css样式(这里只谈移动端)
详情请看:http://www.zhangxinxu.com/wordpress/2012/05/getcomputedstyle-js-getpropertyvalue-currentstyle/
如果清除了style里面的display属性还是无效的话,直接显式的给display赋默认值,defaultDisplay的内部实际是在document里面新添加一个元素,来获取默认值的。
css:
判断只传了一个参数:arguments.length<2或者1inarguments,
流程大致如下:
1:判断参数,如果是一个参数则为只读模式
1.2:如果property为字符串,则直接获取元素的css属性值
1.3:如果property为数组,则this.each遍历数组,获取每个属性的value值并形成props对象返回
2:若有2个参数,为写模式
2.1:如果property为字符串,则style.cssText+=property:value(这里的处理没有去重,但本人测了一下,这并不影响页面的渲染)
2.2:如果property为对象,则循环遍历property
这里有几个函数要提一下:
camelize()将带“—”的转为驼峰命名例如“background-color”转为“backgroundColor”,对象属性是必须驼峰命名的。
dasherize()将“backgroundColor”转为“background-color”,内部实现是用正则表达式匹配
style.removeProperty删除style中的某个属性
style.setProperty(property,value,priority)设置style中的某个属性,priority可取“important”,(不太明白为什么zepto不用这个方法,望高人指教)
maybeAddPx(property,value):根据property类型给value加上“px”后缀
html:
html():不传参数则获取元素的innerHTML,
html("<div></div>"):设置元素的innerHTML
html(function(){....}):可传入方法,返回值设置为元素的innerHTML
这里的funcArg的功能是判断html为函数则以this为上下文,以idx,originHtml为参数执行函数
text:
/** *以集合每一个元素作为上下文,来执行回调函数 *@paramelements *@paramcallback *@returns{*} */ $.each=function(elements,callback){ vari,key if(likeArray(elements)){//数组、伪数组 for(i=0;i<elements.length;i++) if(callback.call(elements[i],i,elements[i])===false)returnelements }else{ for(keyinelements)//对象 if(callback.call(elements[key],key,elements[key])===false)returnelements } returnelements }
这里的elements可以是数组或者对象,如果是对象,则会将其原型里面的属性也遍历出来,最后返回elments本身,如果回调函数返回了false,则终止循环
remove:
/** *删除元素集 *原理parentNode.removeChild *@returns{*} */ remove:function(){ //遍历到其父元素removeChild returnthis.each(function(){ if(this.parentNode!=null) this.parentNode.removeChild(this) }) },
这里的重点是parentNode.removeChild(this);如果是没有父节点的这里不会执行。
is:
//返回集合中的第1条记录是否与selector匹配 is:function(selector){ returnthis.length>0&&zepto.matches(this[0],selector) }
例如$("#id").is(".hasClass");实际就是调用matches进行匹配
not:
//排除集合里满足条件的记录,接收参数为:css选择器,function,dom,nodeList not:function(selector){ varnodes=[] //当selector为函数时,safari下的typeofnodeList也是function,所以这里需要再加一个判断selector.call!==undefined if(isFunction(selector)&&selector.call!==undefined) this.each(function(idx){ //注意这里收集的是selector.call(this,idx)返回结果为false的时候记录 if(!selector.call(this,idx))nodes.push(this) }) else{ //当selector为字符串的时候,对集合进行筛选,也就是筛选出集合中满足selector的记录 varexcludes=typeofselector=='string'?this.filter(selector): //当selector为nodeList时执行slice.call(selector),注意这里的isFunction(selector.item)是为了排除selector为数组的情况 //当selector为css选择器,执行$(selector) (likeArray(selector)&&isFunction(selector.item))?slice.call(selector):$(selector); this.forEach(function(el){ //筛选出不在excludes集合里的记录,达到排除的目的 if(excludes.indexOf(el)<0)nodes.push(el) }) } return$(nodes)//由于上面得到的结果是数组,这里需要转成zepto对象,以便继承其它方法,实现链写 },
这里首先判断selector是否为函数,如果是,则遍历执行函数,如果返回false,则push到数组中
如果css选择字符串则调用this.filter(seelctor),这里有个小技巧使得not和filter相互调用
如果是数组或对象,则直接返回$(他自己)
最后遍历this,只要不是在excludes里面的都是满足条件的
has:
/* 接收node和string作为参数,给当前集合筛选出包含selector的集合 isObject(selector)是判断参数是否是node,因为typeofnode=='object' 当参数为node时,只需要判读当前记当里是否包含node节点即可 当参数为string时,则在当前记录里查询selector,如果长度为0,则为false,filter函数就会过滤掉这条记录,否则保存该记录 */ has:function(selector){ returnthis.filter(function(){ returnisObject(selector)? $.contains(this,selector): $(this).find(selector).size() }) },
重点提示下:这里的this如果也满足selector,则最后返回的结果集里也会有this
show:
/**
*获取元素的默认display属性
*是为了兼容什么?
*@paramnodeName
*@returns{*}
*/
functiondefaultDisplay(nodeName){
varelement,display
if(!elementDisplay[nodeName]){//缓存里没有
element=document.createElement(nodeName)
document.body.appendChild(element)
display=getComputedStyle(element,'').getPropertyValue("display")
element.parentNode.removeChild(element)
//display=="none",设置成blaock,即隐藏-显示
display=="none"&&(display="block")
elementDisplay[nodeName]=display//TODO:缓存元素的默认display属性,缓存干嘛?
}
returnelementDisplay[nodeName]
}
/**
*展示
*@returns{*}
*/
show:function(){
returnthis.each(function(){
//清除内联样式display="none"
this.style.display=="none"&&(this.style.display='')
//计算样式display为none时,重赋显示值
if(getComputedStyle(this,'').getPropertyValue("display")=="none")
this.style.display=defaultDisplay(this.nodeName)
//defaultDisplay是获取元素默认display的方法
})
},
this.style.display=''是清除元素的style里面的display样式,恢复元素的默认样式。
getComputedStyle(dom)能获取dom的所有css样式,第二个参数可以不传
getComputedStyle(dom,":after")能获取dom的:after伪类的所有css样式(这里只谈移动端)
详情请看:http://www.zhangxinxu.com/wordpress/2012/05/getcomputedstyle-js-getpropertyvalue-currentstyle/
如果清除了style里面的display属性还是无效的话,直接显式的给display赋默认值,defaultDisplay的内部实际是在document里面新添加一个元素,来获取默认值的。
css:
/**
*读写样式写:内联样式读:计算样式
*原理读:elment[style]/getComputedStyle,写this.style.cssText行内样式设值
*@parampropertyString/Array/Fun
*@paramvalue
*@returns{*}
*/
css:function(property,value){
//只有一个传参,读
if(arguments.length<2){
varcomputedStyle,element=this[0]
if(!element)return
//getComputedStyle是一个可以获取当前元素所有最终使用的CSS属性值。返回的是一个CSS样式声明对象([objectCSSStyleDeclaration]),只读
//读到计算样式
computedStyle=getComputedStyle(element,'')
//设置样式
if(typeofproperty=='string')//字符串
//优先读行内样式,再读计算样式,行内样式级别最高?TODO:似乎有bug,如果设置了!important呢
returnelement.style[camelize(property)]||computedStyle.getPropertyValue(property)
elseif(isArray(property)){//数组
varprops={}
$.each(property,function(_,prop){//遍历读取每一条样式,存入JSON,返回
props[prop]=(element.style[camelize(prop)]||computedStyle.getPropertyValue(prop))
})
returnprops
}
}
//如果是写
varcss=''
if(type(property)=='string'){
if(!value&&value!==0)//null,undefined时,删掉样式
this.each(function(){
//删除dasherize是将字符串转换成css属性(background-color格式)
this.style.removeProperty(dasherize(property))
})
else
//‘-’格式值+px单位
css=dasherize(property)+":"+maybeAddPx(property,value)
}else{
for(keyinproperty)//是对象时
if(!property[key]&&property[key]!==0)
//当property[key]的值为null/undefined,删除属性
this.each(function(){this.style.removeProperty(dasherize(key))})
else
//‘-’格式值+px单位
css+=dasherize(key)+':'+maybeAddPx(key,property[key])+';'
}
//设值//TODO:this.style.cssText+=未考虑去重了
returnthis.each(function(){this.style.cssText+=';'+css})
},
判断只传了一个参数:arguments.length<2或者1inarguments,
流程大致如下:
1:判断参数,如果是一个参数则为只读模式
1.2:如果property为字符串,则直接获取元素的css属性值
1.3:如果property为数组,则this.each遍历数组,获取每个属性的value值并形成props对象返回
2:若有2个参数,为写模式
2.1:如果property为字符串,则style.cssText+=property:value(这里的处理没有去重,但本人测了一下,这并不影响页面的渲染)
2.2:如果property为对象,则循环遍历property
这里有几个函数要提一下:
camelize()将带“—”的转为驼峰命名例如“background-color”转为“backgroundColor”,对象属性是必须驼峰命名的。
dasherize()将“backgroundColor”转为“background-color”,内部实现是用正则表达式匹配
style.removeProperty删除style中的某个属性
style.setProperty(property,value,priority)设置style中的某个属性,priority可取“important”,(不太明白为什么zepto不用这个方法,望高人指教)
maybeAddPx(property,value):根据property类型给value加上“px”后缀
html:
/**
*处理arg为函数/值
*为函数,返回函数返回值
*为值,返回值
*@paramcontext
*@paramarg
*@paramidx
*@parampayload
*@returns{*}
*/
functionfuncArg(context,arg,idx,payload){
returnisFunction(arg)?arg.call(context,idx,payload):arg
}
/**
*读写元素HTML内容
*原理通过innerHTML读内容,append()写内容
*@paramhtml
*@returns{*|string|string|string|string|string}
*/
html:function(html){
return0inarguments?
this.each(function(idx){
varoriginHtml=this.innerHTML//记录原始的innerHTMl
//如果参数html是字符串直接插入到记录中,
//如果是函数,则将当前记录作为上下文,调用该函数,且传入该记录的索引和原始innerHTML作为参数
$(this).empty().append(funcArg(this,html,idx,originHtml))
}):
(0inthis?this[0].innerHTML:null)
},
html():不传参数则获取元素的innerHTML,
html("<div></div>"):设置元素的innerHTML
html(function(){....}):可传入方法,返回值设置为元素的innerHTML
这里的funcArg的功能是判断html为函数则以this为上下文,以idx,originHtml为参数执行函数
text:
/**
*读写元素文本内容
*原理:通过textContent读写文本
*@paramtext
*@returns{*}
*/
text:function(text){
return0inarguments?
this.each(function(idx){//传参遍历写入
varnewText=funcArg(this,text,idx,this.textContent)
this.textContent=newText==null?'':''+newText
}):
(0inthis?this[0].textContent:null)//未传参读
},
相关文章推荐
- js 处理Json 时间带T 时间格式
- Web 基础学习之 JS ,循环练习
- JSONP(跨域请求) —— 一种非官方跨域数据交互协议
- onBlur事件与onfocus事件(js)
- 纯JS回显form各种表单数据
- 匈牙利算法 cojs.tk 搭配飞行员
- js arguments.caller arguments.callee分析
- 《Pro Express.js》学习笔记——Express框架常用设置项
- 《Pro Express.js》学习笔记——Express服务启动常规七步
- JSP隐式对象的类,及其相关的方法介绍
- 《Pro Express.js》学习笔记——概述
- js获取表单域的三种方式
- ArcGIS API for JavaScript使用中出现的BUG(1)
- ArcGIS API for JavaScript使用中出现的BUG(1)
- js 生成 yyyy-mm-dd 格式
- js测试单选按钮
- js测试复选按钮
- jsp的base属性
- JS题
- JS题