今天基本上就是zepto学习笔记的最后一篇了,介绍一下有关位置的函数,position, offset, scrollLeft, scrollTopjavascript
scrollLeftcss
若是所选取的包装集不存在,则直接返回。java
定义变量:ajax
var hasScrollLeft = 'scrollLeft' in this[0]
在zepto中用到了不少相似的特性检测的方法,判断浏览器是否支持scrollLeft这一特性,若是支持,则直接使用该特性,若是不支持,则利用其余方法来实现。浏览器
这里是在判断浏览器是否支持scrollLeft这一特性。函数
这以后就是实现函数的目的,获取当前水平滚动的距离,或者设置水平滚动的距离。post
if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset
若是没有传入参数,就表示获取滚动距离,依据hasScrollLeft的布尔值,决定获取的方法,若是hasScrollLeft为真,直接获取this[0].scrollLeft;不然获取this[0].pageXOffset。学习
pageXOffset 返回当前页面相对于窗口显示区左上角的 X 位置。this
return this.each(hasScrollLeft ? function(){ this.scrollLeft = value } : function(){ this.scrollTo(value, this.scrollY) })
设置水平滚动距离时,须要对包装集遍历,也须要依据hasScrollLeft,若是hasScrollLeft=true,则将传入的value直接赋值给this.scrollLeft;不然利用javascript的原生函数scrollTo(x, y),向左滚动将x改成value,y保持原有高度不变。spa
scrollTo() 方法可把内容滚动到指定的坐标。
scrollTop
该函数与scrollLeft彻底一致,惟一的区别就是将水平滚动,改成垂直滚动距离,再也不详细介绍。
offset
也属于获取和设置使用的同一个函数,依据是否传入参数,判断是获取仍是设置。
zepto的API解释:
得到当前元素相对于document的位置。返回一个对象含有: top
, left
, width
和height
当给定一个含有left
和top
属性对象时,使用这些值来对集合中每个元素进行相对于document的定位。
若是coodinates存在,即传入了参数,则表示设置,依据源码来看,只能设置当前包装集的left和top值,传入的参数是包含left和top属性的一个对象。
遍历包装集, 对包装集内的每个元素单独应用该方法。
var $this = $(this)
须要对传入的参数coodinates进一步处理,容许用户传入函数形式,利用funcArg函数,将其转换为咱们须要的格式。即便插入的参数是函数,最终返回结果也必须是包含top和left属性的对象。
coords = funcArg(this, coordinates, index, $this.offset()),
因为定位都是相对于最近的一个具备定位属性的父元素来设置位置的,因此这里必须获取最近的一个有定位的父元素的位置,以修正实际位置,使得该函数相对于document定位。
parentOffset = $this.offsetParent().offset(),
这里利用到了offset获取元素位置的功能,而offsetParent在上篇文章中刚刚介绍。
以后就是肯定须要设置的真正的left和top 的值,
props = { top: coords.top - parentOffset.top, left: coords.left - parentOffset.left }
因为目的是设置相对于document的定位,因此这里是修正实际须要给元素赋值的距离。
准备工做作完,就是设置的具体实现了,其实到了这里就已经很简单了,利用以前定义的css函数,$this.css(props),须要注意的是,要想使定位发生做用,就必须给元素设置position属性为relative, absolute, fixed这三者中的一个。因此在调用css函数以前,须要对当前元素的postion进行判断,若是是static,就必须将其改成relative。
若是没有传入有效参数,则是该函数的另一个须要实现的功能,获取当前包装集中第一个元素的位置信息,包括left,top,width,height。
判断包装集,若是包装集不存在,直接返回null。
判断包装集选择的是不是document对象,若是选中的是document对象,直接返回{top: 0, left: 0}
不然调用调用JavaScript原生函数 getBoundingClientRect(),该方法返回元素的大小及其相对于视口的位置。包含6个属性,left,top,right,bottom,width,height。
最后返回咱们须要的内容
return { left: obj.left + window.pageXOffset, top: obj.top + window.pageYOffset, width: Math.round(obj.width), height: Math.round(obj.height) }
因为咱们须要获取的是相对于document的位置,因此须要对left进行修正,加上window.pageXOffset或者window.pageYOffset。
pageXOffset 设置或返回当前页面相对于窗口显示区左上角的 X 位置。pageYOffset 设置或返回当前页面相对于窗口显示区左上角的 Y 。
position
获取对象集合中第一个元素的位置。相对于 offsetParent。与offset的区别:只做为获取对象集合中第一个元素的位置,即获取left和top值,实际上相似于css中的position定位的意思,可是这里只有获取功能,而不存在设置的功能。也没有width和height,不可混淆。
在理解了offset函数的基础上来看,这个函数相对容易理解不少,其实就是获取当前包装集中第一个元素的offset和offsetPrent的offset,二者相减便可。中间有对部分浏览器的offset的修正,我认为知道便可。
至此,zepto源码学习,基本上算是完成了,等到后面对JavaScript有更深一层次的把握以后,但愿有时间来回头从总体上从新整理一下zepto源码学习。
也还有不少本身并不理解的地方,学习笔记的最重要的目的,是记录本身对于zepto源码的一点点学习,若是有错误或者不详尽的地方,读者可以给予指正,不胜感激。
关于zepto插件部分的源码,一律没有涉及,包括zepto源码在最后面直接包含的插件部分,如ajax,事件处理等等,均未在这一阶段涉及。