今天基本上就是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,事件處理等等,均未在這一階段涉及。