懶加載其實就是延遲加載,是一種對網頁性能優化可方式,比如當訪問一個頁面的時候,優先顯示可視區域的圖片而不一次性加載所有圖片,當需要顯示的時候再發送圖片請求,避免打開網頁時加載過多資源。
當頁面中需要一次性載入很多圖片的時候,往往都是需要用懶加載的。
我們都知道HTML中的 <img>標簽是代表文檔中的一個圖像。。說了個廢話。。
<img>標簽有一個屬性是 src,用來表示圖像的URL,當這個屬性的值不為空時,瀏覽器就會根據這個值發送請求。如果沒有 src屬性,就不會發送請求。
嗯?貌似這點可以利用一下?
我先不設置 src,需要的時候再設置?
nice,就是這樣。
我們先不給 <img>設置 src,把圖片真正的URL放在另一個屬性 data-src中,在需要的時候也就是圖片進入可視區域的之前,將URL取出放到 src中。
<div class="container">
<div class="img-area">
<img class="my-photo" alt="loading" data-src="./img/img1.png">
</div>
<div class="img-area">
<img class="my-photo" alt="loading" data-src="./img/img2.png">
</div>
<div class="img-area">
<img class="my-photo" alt="loading" data-src="./img/img3.png">
</div>
<div class="img-area">
<img class="my-photo" alt="loading" data-src="./img/img4.png">
</div>
<div class="img-area">
<img class="my-photo" alt="loading" data-src="./img/img5.png">
</div>
</div>
仔細觀察一下, <img>標簽此時是沒有 src屬性的,只有 alt和 data-src屬性。
alt 屬性是一個必需的屬性,它規定在圖像無法顯示時的替代文本。 data-* 全局屬性:構成一類名稱為自定義數據屬性的屬性,可以通過 HTMLElement.dataset來訪問。
方法一
網上看到好多這種方法,稍微記錄一下。
然后判斷②-③<①是否成立,如果成立,元素就在可視區域內。
方法二(推薦)
通過 getBoundingClientRect()方法來獲取元素的大小以及位置,MDN上是這樣描述的:
The Element.getBoundingClientRect() method returns the size of an element and its position relative to the viewport.
這個方法返回一個名為 ClientRect的 DOMRect對象,包含了 top、 right、 botton、 left、 width、 height這些值。
MDN上有這樣一張圖:
可以看出返回的元素位置是相對于左上角而言的,而不是邊距。
我們思考一下,什么情況下圖片進入可視區域。
假設 constbound=el.getBoundingClientRect();來表示圖片到可視區域頂部距離; 并設 constclientHeight=window.innerHeight;來表示可視區域的高度。
隨著滾動條的向下滾動, bound.top會越來越小,也就是圖片到可視區域頂部的距離越來越小,當 bound.top===clientHeight時,圖片的上沿應該是位于可視區域下沿的位置的臨界點,再滾動一點點,圖片就會進入可視區域。
也就是說,在 bound.top<=clientHeight時,圖片是在可視區域內的。
我們這樣判斷:
function isInSight(el) {
const bound = el.getBoundingClientRect();
const clientHeight = window.innerHeight;
//如果只考慮向下滾動加載
//const clientWidth = window.innerWeight;
return bound.top <= clientHeight + 100;
}
這里有個+100是為了提前加載。
頁面打開時需要對所有圖片進行檢查,是否在可視區域內,如果是就加載。
function checkImgs() {
const imgs = document.querySelectorAll('.my-photo');
Array.from(imgs).forEach(el => {
if (isInSight(el)) {
loadImg(el);
}
})
}
function loadImg(el) {
if (!el.src) {
const source = el.dataset.src;
el.src = source;
}
}
這里應該是有一個優化的地方,設一個標識符標識已經加載圖片的index,當滾動條滾動時就不需要遍歷所有的圖片,只需要遍歷未加載的圖片即可。
在類似于滾動條滾動等頻繁的DOM操作時,總會提到“函數節流、函數去抖”。
所謂的函數節流,也就是讓一個函數不要執行的太頻繁,減少一些過快的調用來節流。
基本步驟:
function throttle(fn, mustRun = 500) {
const timer = null;
let previous = null;
return function() {
const now = new Date();
const context = this;
const args = arguments;
if (!previous){
previous = now;
}
const remaining = now - previous;
if (mustRun && remaining >= mustRun) {
fn.apply(context, args);
previous = now;
}
}
}
這里的 mustRun就是調用函數的時間間隔,無論多么頻繁的調用 fn,只有 remaining>=mustRun時 fn才能被執行。
可以看出此時僅僅是加載了img1和img2,其它的img都沒發送請求,看看此時的瀏覽器
第一張圖片是完整的呈現了,第二張圖片剛進入可視區域,后面的就看不到了~
當我向下滾動,此時瀏覽器是這樣
此時第二張圖片完全顯示了,而第三張圖片顯示了一點點,這時候我們看看請求情況
img3的請求發出來,而后面的請求還是沒發出~
當滾動條滾到最底下時,全部請求都應該是發出的,如圖
方法三 IntersectionObserver
經大佬提醒,發現了這個方法
先附上鏈接:
jjc大大:
https://github.com/justjavac/the-front-end-knowledge-you-may-dont-know/issues/10
阮一峰大大:
http://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html
API Sketch for Intersection Observers:
https://github.com/WICG/IntersectionObserver
IntersectionObserver可以自動觀察元素是否在視口內。
var io = new IntersectionObserver(callback, option);
// 開始觀察
io.observe(document.getElementById('example'));
// 停止觀察
io.unobserve(element);
// 關閉觀察器
io.disconnect();
callback的參數是一個數組,每個數組都是一個 IntersectionObserverEntry對象,包括以下屬性:
屬性描述time可見性發生變化的時間,單位為毫秒rootBounds與getBoundingClientRect()方法的返回值一樣boundingClientRect目標元素的矩形區域的信息intersectionRect目標元素與視口(或根元素)的交叉區域的信息intersectionRatio目標元素的可見比例,即intersectionRect占boundingClientRect的比例,完全可見時為1,完全不可見時小于等于0target被觀察的目標元素,是一個 DOM 節點對象
我們需要用到 intersectionRatio來判斷是否在可視區域內,當 intersectionRatio>0&&intersectionRatio<=1即在可視區域內。
代碼
function checkImgs() {
const imgs = Array.from(document.querySelectorAll(".my-photo"));
imgs.forEach(item => io.observe(item));
}
function loadImg(el) {
if (!el.src) {
const source = el.dataset.src;
el.src = source;
}
}
const io = new IntersectionObserver(ioes => {
ioes.forEach(ioe => {
const el = ioe.target;
const intersectionRatio = ioe.intersectionRatio;
if (intersectionRatio > 0 && intersectionRatio <= 1) {
loadImg(el);
}
el.onload = el.onerror = () => io.unobserve(el);
});
});
源自:segmentfault
聲明:文章著作權歸作者所有,如有侵權,請聯系小編刪除。
我們進入到某個頁面的時候,會有許多的圖片,有些圖片可能在下面,當我們點進頁面但沒有滑動全部展示時,其實下面的圖片是沒有作用的,這個時候如果說加載了也相當于白加載,而且還降低了網頁的加載速度。滾動加載就是不需要展示的圖片可以先不展示,滾動到指定位置的時候再加載;今天跟大家分享二種方式,一是滾動條到底部時去加載對應的數據,二是使用懶加載;
實現效果圖
一、怎么實現滾動條到底部時去加載?
實現原理以及代碼展示:
1)先請求第一頁的數據
$.ajax({
type:'get', //請求類型
url:'http://127.0.0.1:8088/ list?page =1', //接口文檔
dataType:'json',//返回值類型
//data:data,
success:function(data){
$.each(data,function(index,item){ //index 索引 item 當前元素
$(".index-main ul").append('<li class="lists">'+
'<img src="'+item. img_url+'" width="150" height="150">'+
'<label>'+
'<b class="discount">'+item. uprice+'</b>'+
'<span class="price-text">'+item. price+'</span> '+
'</label> '+
'</li>')
});
},
error:function(error){
console.log(error)
}
});
2)當滾動條移至底部時觸發請求下一頁的數據
$(window).scroll(function(){
var scrollTop = $(this).scrollTop(); //滾動條距離頂部的高度
var scrollHeight = $(document).height(); //當前頁面的總高度
var clientHeight = $(this).height(); //當前可視的頁面高度
if(scrollTop + clientHeight >= scrollHeight){ //距離頂部+當前高度 >=頁面總高度 即滾動條到達底部
//再請求對應的數據
});
這樣就可以實現鼠標移至底部加載下一頁的數據~~~
二、懶加載
1、為什么要使用懶加載
懶加載就是只有滾動到可視區域時才加載當前的圖片,也就是說不是一次性加載所有的圖片,從而在一程度減少服務端的請求及帶寬;
2、懶加載的優點:
提高前端性能,圖片在需要的時候才加載,減輕服務的負擔,提高頁面的加載速度,能夠減少帶寬
3、實現原理
圖片的加載是由src的值引起的,當對src賦值時瀏覽器會請求圖片資源,基于這個,可以利用html5的屬性data-xxx來保存圖片的路徑,當我們需要加載圖片的時候才將data-xxx的值賦予src,就能實現圖片的按需加載,也就是懶加載了;
懶加載的方法有很多,這里推薦使用jquery圖片延遲加載jquery.lazyload
1)使用方法
引用jquery和jquery.lazyload.js到你的頁面
<script src="js/jquery-1.11.1.min.js"></script>
<script src="js/jquery.lazyload.js"></script>
2)html圖片調用方法
為圖片加入樣式lazy 圖片路徑引用方法用data-original
1. 將圖片路徑寫入data-original屬性
<img data-original="img/1.jpg" />
2. 選擇所有要lazyload的圖片(img.lazy),執行lazyload();
$("img").lazyload();
3、常用方法設置
1)提前加載——Threshold
lazyload默認是當滾動到該圖片位置時,加載該圖片。但是可以通過設置Threshold參數來實現滾到距離其xx px時就加載。
$("img.lazy").lazyload({
threshold :20
});
2)設定效果——Effects
插件默認的加載效果是 show() ,你可以使用任何你想要的效果。下面的代碼使用了 fadeIn()
$("img.lazy").lazyload({
effect : "fadeIn"
});
4、當前實例的具體代碼如下:
//按需加載
$.ajax({
type:'get', //請求類型get post put delete
url:'http://127.0.0.1:8088/ list’, //接口文檔
dataType:'json',//返回值類型
//data:data,
success:function(data){
$.each(data,function(index,item){
$(".index-main ul").append('<li class="lists">'+
'<img data-original="'+item.product_img_url+'" width="150" height="150">'+
'<label>'+
'<b class="discount">'+item.product_uprice+'</b>'+
'<span class="price-text">'+item.product_price+'</span> '+
'</label> '+
'</li>')
});
//懶加載
$(".index-main ul img").lazyload({
effect:'fadeIn' //淡入效果
})
},
error:function(error){
console.log(error)
}
});
注:如果想添加加載動畫
轉發+關注我吧,每天更新web前端干貨知識,原創需要大家的支持,你們的支持是我更新最大的動力!
頁跨屏幕自適配已經成為網站的不二之選,跨屏幕適配是幫助傳統網站快速抓住移動互聯網這根稻草的有效解決方案,切圖公司首個推出網頁跨屏幕適配項目:跨無憂。并且揭露技術上網頁適配的實現原理。
允許網頁寬度自動調整
“自適應網頁設計”到底是怎么做到的?其實并不難。跨無憂(www.Kuawuyou.com)為您剖析網頁跨屏幕適配的技術實現原理:
首先,在網頁代碼的頭部,加入一行viewport元標簽。
viewport是網頁默認的寬度和高度,上面這行代碼的意思是,網頁寬度默認等于屏幕寬度(width=device-width),原始縮放比例(initial-scale=1)為1.0,即網頁初始大小占屏幕面積的100%。
所有主流瀏覽器都支持這個設置,包括IE9。對于那些老式瀏覽器(主要是IE6、7、8),需要使用css3-mediaqueries.js。
三、不使用絕對寬度
由于網頁會根據屏幕寬度調整布局,所以不能使用絕對寬度的布局,也不能使用具有絕對寬度的元素。這一條非常重要。
具體說,CSS代碼不能指定像素寬度:
width:xxxpx;
只能指定百分比寬度:
width:xx%;
或者
width:auto;
四、相對大小的字體
字體也不能使用絕對大小(px),而只能使用相對大小(em)。
body{
font:normal100%Helvetica,Arial,sans-serif;
}
上面的代碼指定,字體大小是頁面默認大小的100%,即16像素。
h1{
font-size:1.5em;
}
然后,h1的大小是默認大小的1.5倍,即24像素(24/16=1.5)。
small{
font-size:0.875em;
}
small元素的大小是默認大小的0.875倍,即14像素(14/16=0.875)。
五、流動布局(fluidgrid)
“流動布局”的含義是,各個區塊的位置都是浮動的,不是固定不變的。
.main{
float:right;
width:70%;
}
.leftBar{
float:left;
width:25%;
}
float的好處是,如果寬度太小,放不下兩個元素,后面的元素會自動滾動到前面元素的下方,不會在水平方向overflow(溢出),避免了水平滾動條的出現。
另外,絕對定位(position:absolute)的使用,也要非常小心。
六、選擇加載CSS
“自適應網頁設計”的核心,就是CSS3引入的MediaQuery模塊。
它的意思就是,自動探測屏幕寬度,然后加載相應的CSS文件。
media=”screenand(max-device-width:400px)”
href=”tinyScreen.css”/>
上面的代碼意思是,如果屏幕寬度小于400像素(max-device-width:400px),就加載tinyScreen.css文件。
media=”screenand(min-width:400px)and(max-device-width:600px)”
href=”smallScreen.css”/>
如果屏幕寬度在400像素到600像素之間,則加載smallScreen.css文件。
除了用html標簽加載CSS文件,還可以在現有CSS文件中加載。
七、CSS的@media規則
同一個CSS文件中,也可以根據不同的屏幕分辨率,選擇應用不同的CSS規則。
@mediascreenand(max-device-width:400px){
.column{
float:none;
width:auto;
}
#sidebar{
display:none;
}
}
上面的代碼意思是,如果屏幕寬度小于400像素,則column塊取消浮動(float:none)、寬度自動調節(width:auto),sidebar塊不顯示(display:none)。
八、圖片的自適應(fluidimage)
除了布局和文本,”自適應網頁設計”還必須實現圖片的自動縮放。
這只要一行CSS代碼:
img{max-width:100%;}
這行代碼對于大多數嵌入網頁的視頻也有效,所以可以寫成:
img,object{max-width:100%;}
老版本的IE不支持max-width,所以只好寫成:
img{width:100%;}
此外,windows平臺縮放圖片時,可能出現圖像失真現象。這時,可以嘗試使用IE的專有命令:
img{-ms-interpolation-mode:bicubic;}
或者,EthanMarcotte的imgSizer.js。
addLoadEvent(function(){
varimgs=document.getElementById(“content”).getElementsByTagName(“img”);
imgSizer.collate(imgs);
});
最好還是做適配分辨率的圖片。有很多方法可以做到同樣效果,服務器端和客戶端都可以實現。
關注切圖網公眾微信:qietuwang
*請認真填寫需求信息,我們會在24小時內與您取得聯系。