摘要:而和則表示該容器中頁面視圖區的大小減去邊框寬度。語法實際上,返回的值是一個雙精度浮點值,指示文檔當前從原點垂直滾動的像素數,其中正值表示向上滾動。除此之外,舊版本不支持這些屬性,必須通過檢查其他非標準屬性來解決。
博客地址:https://guitong.github.io/blo...
上一節中,我們分析了 jQuery lazyload 源碼,其中有這么一段:
/* 在jQuery命名空間內定義了便捷的方法,判斷圖片是否在容器視口范圍內 */ $.belowthefold = function (element, settings) {...} $.rightoffold = function (element, settings) {...} $.abovethetop = function (element, settings) {...} $.leftofbegin = function (element, settings) {...} $.inviewport = function (element, settings) {...}
說實話,這才是我最感興趣的內容。那么實現一個lazyload,應該怎樣判斷圖片與瀏覽器可見區域的相對位置呢,現在以$.belowthefold方法為例,看一下其實現方式:
$.belowthefold = function(element, settings) { var fold; if (settings.container === undefined || settings.container === window) { fold = (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop(); } else { fold = $(settings.container).offset().top + $(settings.container).height(); } return fold <= $(element).offset().top - settings.threshold; };
首先這段代碼的目的是判斷當前元素(圖片)是否在瀏覽器視口的下方。
變量fold我理解為當前文檔已“折疊”的高度,也就是當前瀏覽器視口的最底部至文檔最頂部的距離。與fold變量值相比較的值是$(element).offset().top - settings.threshold,那么這個值代表什么呢?
seetings.threshold是我們上節提到過的臨界值,默認為0,這里我們可以先將其忽略。jQuery對象的offset()方法定義如下:
Get the current coordinates of the first element in the set of matched elements, relative to the documents.
也就是當前元素相對于文檔的坐標。它的top值即為元素到文檔頂部的距離。
那么也就不難理解,如果這個值大于等于文檔已“折疊”的高度值,它的位置就在瀏覽器視口的下方。
然而這些jQuery方法也是封裝過的方法,我們還需要探究它們的實現方式。
一、如何得到瀏覽器視口(即可見區域)的大小以下內容參考自大紅本 — 《JavaScript高級程序設計》,第三版,第八章
跨瀏覽器確定一個窗口的大小不是一件簡單的事。IE9+、Firefox、Safari、Opera和Chrome均為此提供了4個屬性:innerWidth 、innerHeight、outerWidth、outerHeight。在IE9+、Safari和Firefox中,outerWidth和outerHeight返回瀏覽器窗口本身的尺寸(無論是最外層的window對象還是從某個框架訪問)。在Opera中,這兩個屬性的值表示頁面視圖容器(這里所謂的“頁面視圖容器”指的是Opera中單個標簽頁對應的瀏覽器窗口)的大小。而innerWidth和innerHeight則表示該容器中頁面視圖區的大小(減去邊框寬度)。在Chrome中,outerWIdth和outerHeight與innerWidth、innerHeight返回相同的值,即視口(viewport)大小而非瀏覽器窗口大小。
IE8及更早版本沒有提供取得當前瀏覽器窗口尺寸的屬性;不過,它通過DOM提供了頁面可見區域的相關信息。
在IE、Firefox、Safari、Opera和Chrome中,document.documentElement.clientWidth和document.documentElement.clientHeight中保存了頁面視口的信息。在IE6中,這些屬性必須在標準模式下才有效;如果是混雜模式,就必須通過document.body.clientWidth和document.body.clientHeight取得相同信息。而對于混在模式下的Chrome,則無論通過document.documentElement還是document.body中的clientWidth和clientHeight屬性,都可以取得取得視口的大小。
(跑題了?? )
雖然最終無法確定瀏覽器窗口本身的大小,但卻可以取得頁面視口的大小,如下所示:
var pageWidth = window.innerWidth, pageHeight = window.innerHeight; if (typeof pageWidth != "number") { if (document.compatMode == "CSS1Compat") { pageWidth = document.documentElement.clientWidth; pageHeight = document.documentElement.clientHeight; } else { pageWidth = document.body.clientWidth; pageHeight = document.body.clientHeight; } }
這段代碼很好理解,值得注意的是document.compatMode這個屬性。該值表明當前文檔的渲染模式為“混雜模式”還是“標準模式”。當值為"CSS1Compat"代表標準規范模式;當值為"BackCompat"代表混雜模式。
二、如果得到文檔在在垂直/水平方向滾動的距離這里以垂直方向為例。
先來看一個stackoverflow上的回答,翻譯如下:
獲取滾動距離的標準方法為window.scrollY。Chrome、Firefox、Opera、Safari及IE Edge(或更高版本)均支持此方法。如果您僅需要支持這些瀏覽器,使用這個屬性即可。
IE >= 9 支持一個類似的屬性window.pageYOffset,為了保證兼容性,在現代瀏覽器中會返回與window.scrollY相同的值,盡管它可能在某些時候被棄用。
使用document.documentElement.scrollTop或document.body.scrollTop的問題是,它們并不是總是都被定義了滾動。例如,Chrome和Safari將滾動定義在元素,而Firefox則定義在了document.documentElement返回的元素上。這不是標準化的,并且在未來版本的瀏覽器中可能會發生變化。然而,如果scrollY和pageYOffset不存在,則這是獲取滾動位置的唯一方法。
遂總結如下:
window.scrollY || window.pageYOffset || document.body.scrollTop + (document.documentElement && document.documentElement.scrollTop || 0)
經過測試,這個方法是可行的。不過,正如文中所說,果然在未來版本的瀏覽器中發生了變化。在最新的Chrome、Safari、Firefox中測試發現,Chrome與Firefox表現相同,document.documentElement.scrollTop返回滾動值,而document.body.scrollTop返回0,Safari則與它們相反。
再來看一下MDN上對window.scrollY的解釋。
window接口的只讀屬性值scrollY返回文檔當前垂直滾動距離的像素值。這個值在現在瀏覽器中是亞像素精準的,這意味著它不一定是一個整數。您可以從scrollY屬性獲取文檔水平滾動的像素值。
# 語法
var y = window.scrollY實際上,返回的值是一個雙精度浮點值,指示文檔當前從原點垂直滾動的像素數,其中正值表示向上滾動。如果文檔在子像素精準的設備上呈現,則返回的值也是子像素精準的,并且可能包含一個小數分量。如果文檔沒有向上或向下滾動,則滾動值是 0 。
如果你需要一個整型值,可以使用Math.round()方法
用更技術的話說,scrollY返回當前視口頂邊的Y坐標,如果沒有視口,則返回 0 。
# 示例
// make sure and go down to the second page if (window.scrollY) { window.scroll(0, 0); // 重置滾動條位置 } window.scrollByPages(1);(這個示例 出現在這里感覺怪怪的)
# 注意事項
使用此屬性來檢查使用相對滾動方法時(如;scrollBy()、scrollByLines()、scrollByPages())文檔是否尚未滾動。
pageYOffset屬性是scrollY屬性的別名:
window.pageYOffset == window.scrollY // always true考慮到跨瀏覽器兼容性,使用window.pageYOffset替代window.scrollY。除此之外,舊版本 IE(< 9)不支持這些屬性,必須通過檢查其他非標準屬性來解決。完全兼容的的例子如下:
var supportPageOffset = window.pageXOffset !== undefied; var isCSS1Compat = ((document.compatMode || "") === "CSS1Compat"); var scrollX = supportPageOffset ? window.pageXOffset : isCSS1Compat ? document.documentElement.scrollLeft : document.body.scrollLeft; var scrollY = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.document.scrollTop : document.body.scrollTop;# 規范
CSS Object Model (CSSOM) View ModuleThe definition of "window.scrollY" in that specification.
==================== 太平洋分割線=======================
那么可以總結一下了。
要獲得頁面當前的滾動值,window.scrollY是基于標準的方法。然而考慮到跨瀏覽器兼容性,應該使用window.pageYOffset,該屬性是window.scrollY的別名,被絕大多數現代瀏覽器所支持。對于低版本IE瀏覽器(< 9),可以判斷渲染模式(標準or混雜)來選擇使用document.documentElement.scrollTop/Left或document.body.scrollTop/Left方法。
推薦:
var supportPageOffset = window.pageXOffset !== undefined; var isCSS1Compat = ((document.compatMode || "") === "CSS1Compat"); var scrollX = supportPageOffset ? window.pageXOffset : isCSS1Compat ? document.documentElement.scrollLeft : document.body.scrollLeft; var scrollY = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop;三、???
發現跑題了,不是要看一下jQuery方法的源碼嗎???不過應該大同小異。
明白了上面兩個重要的方法,實現一個兼容性良好lazyload就變得輕而易舉。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89441.html
摘要:今天開始帶型帶秀專題。專題第二節會深入到源碼。在可視圖片加載后,瀏覽器將處于就緒狀態。只需要將該容器元素作為對象傳遞。默認地,循環會在找到第一個視口外的圖像時停止。但是某些頁面的布局不符合該假設。最差的情況是該值為實際圖片的數量。 今天開始帶型帶秀專題 -- Lazy Load。先從使用比較廣泛的 jQuery Lazy Load 插件開始,逐步深入。該插件已經開發到了第二版,有興趣的...
摘要:參考文章使用及源碼分析關于插件的基本介紹和使用請看上一篇文章。顯示方法默認為,也可以設置為,源碼中隱藏了一個配置屬性,用于設置動畫運行的時間。是否忽略隱藏的元素設置為時會忽略處理隱藏的元素。在觸發事件時執行的回調。 參考文章:jQuery.lazyload使用及源碼分析 關于 jQuery lazyload 插件的基本介紹和使用請看上一篇文章。(水水一章啦-。-) Overview 讓...
摘要:專題系列第十五篇,講解惰性函數需求我們現在需要寫一個函數,這個函數返回首次調用時的對象,注意是首次。解決四惰性函數不錯,惰性函數就是解決每次都要進行判斷的這個問題,解決原理很簡單,重寫函數。 JavaScript 專題系列第十五篇,講解惰性函數 需求 我們現在需要寫一個 foo 函數,這個函數返回首次調用時的 Date 對象,注意是首次。 解決一:普通方法 var t; functio...
摘要:初始化我們知道容器初始化后會對容器中非懶加載的,單例的以及非抽象的定義進行的初始化操作,所以我們分析源碼的入口也就是在容器初始化的入口,分析容器初始化后在什么地方開始第一次的初始化。 前言 Spring IOC容器在初始化之后會對容器中非懶加載的,單例的以及非抽象的bean定義進行bean的初始化操作,同時會也涉及到Bean的后置處理器以及DI(依賴注入)等行為。對于Bean的初始化,...
摘要:粗讀近來沒什么特別要做的事,下班回來的空閑時間也比較多,所以抽空看看懶加載是怎么實現的,特別是看了下的庫的實現。之先別關注,按他給注釋說測試用。之是組件綁定事件時會觸發的函數。 react-lazy-load粗讀 近來沒什么特別要做的事,下班回來的空閑時間也比較多,所以抽空看看懶加載是怎么實現的,特別是看了下 react-lazy-load 的庫的實現。 懶加載 這里懶加載場景不是路由...
閱讀 824·2021-09-07 09:58
閱讀 2682·2021-08-31 09:42
閱讀 2855·2019-08-30 14:18
閱讀 3086·2019-08-30 14:08
閱讀 1831·2019-08-30 12:57
閱讀 2758·2019-08-26 13:31
閱讀 1299·2019-08-26 11:58
閱讀 1052·2019-08-23 18:06