防抖和節流,主要是用來防止過於平凡的執行某個操作,如瀏覽器窗口變化執行某個操作,監聽某個input輸入框keyup變化,瀑布流布局時Y軸滾動,圖片加載。
js函數的防抖
經過一段事件才執行某個操作,如果時間內又執行了該操作則延長時間重新開始計算
/* 不做處理input觸發keyup事件 */
/* 輸入快的話會出現輸出結果多次重復 */
window.onload = function () { let obj = document.getElementById('input') obj.addEventListener('keyup',()=>{ let val = obj.value; inputchange(val) },false) } function inputchange(val) { console.log(val) }
// 11 11 123 123 123456 123456 123456
使用防抖去處理
/* 使用防抖去處理input觸發keyup事件 */ /* 輸入快的話會也不會輸出多次重復結果 */ window.onload = function () { let obj = document.getElementById('input') let callback = inputchange() obj.addEventListener('keyup',()=>{ let val = obj.value; callback(val) },false) } // 高級函數的應用 // 閉包time為局部變量 但不會在inputchange 函數調用完后釋放 // 函數返回函數 function inputchange() { var time return function(val){ if(time) { clearTimeout(time) } time = setTimeout(() => { console.log(val) }, 200); } }
js函數節流
定義:執行某個操作后一段時間內不在不行該操作
/* 使用節流去處理input觸發keyup事件 */ /* 輸入快的話會也不會輸出多次重復結果 */ window.onload = function () { let obj = document.getElementById('input') let callback = inputchange() obj.addEventListener('keyup',()=>{ let val = obj.value; callback(val) },false) } // 使用閉包保存hasdone function inputchange() { var hasdone = false return function(val){ // 如果已經執行 hasdone = true 則直接返回 if(hasdone) { return; } // 設置已經執行 console.log(val) hasdone =true /* 一段時間后設置hasdone 為能夠再次執行 */ time = setTimeout(() => { hasdone = false }, 2000); } }
上面的節流,第一次輸入馬上執行,是最后輸入不執行。
還有就是第一次輸入不馬上執行,時間內最后執行
/* 使用節流去處理input觸發keyup事件 */ /* 輸入快的話會也不會輸出多次重復結果 */ window.onload = function () { let obj = document.getElementById('input') let callback = inputchange() obj.addEventListener('keyup',()=>{ let val = obj.value; callback(val) },false) } // 使用閉包保存hasdone /* 時間內不馬上執行,時間段內只執行一次 */ function inputchange() { var hasdone = false var time = null return function(val){ // 如果已經執行 hasdone = true 則直接返回 if(hasdone) { return; } // 設置已經執行 hasdone =true /* 一段時間后設置hasdone 為能夠再次執行 */ time = setTimeout(() => { console.log(val) hasdone = false }, 500); } }
js 實現瀏覽器滾動條滾動到最下面時,加載更多數據
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="./js/fangdouhejl.js"></script>
<style>
.box{
height:890px;
}
li{
height: 60px;
}
.loading{
width: 80px;
height: 40px;
margin: 0 auto;
margin-top:100px;
display: none;
}
.loading span{
display: inline-block;
width: 8px;
height: 100%;
border-radius: 4px;
background: lightgreen;
-webkit-animation: load 1s ease infinite;
}
@-webkit-keyframes load{
0%,100%{
height: 40px;
background: lightgreen;
}
50%{
height: 70px;
margin: -15px 0;
background: lightblue;
}
}
.loading span:nth-child(2){
-webkit-animation-delay:0.2s;
}
.loading span:nth-child(3){
-webkit-animation-delay:0.4s;
}
.loading span:nth-child(4){
-webkit-animation-delay:0.6s;
}
.loading span:nth-child(5){
-webkit-animation-delay:0.8s;
}
</style>
</head>
<body>
<ul id="box">
<li>baojia1</li>
<li>baojia2</li>
<li>baojia3</li>
<li>baojia4</li>
<li>baojia5</li>
<li>baojia6</li>
<li>baojia7</li>
<li>baojia8</li>
<li>baojia9</li>
<li>baojia10</li>
<li>baojia11</li>
<li>baojia12</li>
<li>baojia13</li>
<li>baojia14</li>
<li>baojia15</li>
<li>baojia16</li>
<li>baojia17</li>
<li>baojia18</li>
<li>baojia19</li>
<li>baojia20</li>
</ul>
<div class="loading" id="loading">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</body>
</html>
/* 瀏覽器滾動事件onsroll */ /* 實現瀏覽器滾動到最下面實現加載 */ var loadmore = loadmoreresource (); /* 模仿滾到最下面繼續加載數據 */ window.onscroll = function (e) { /* 判斷是否滾到最下面 */ /* 如果已經滾到最下面則執行某個操作 */ var e =e || window.event; // 為了兼容谷歌和火狐 document.body.scrollTop是谷歌上的 /* 滾動條的垂直位置 */ var scrolltop = document.documentElement.scrollTop||document.body.scrollTop; /* 整個頁面的正文高度 */ var scrollHeight = document.documentElement.scrollHeight||document.body.scrollHeight; /* 可見區域高度 */ var clientHeight = document.documentElement.clientHeight||document.body.clientHeight; /* 當scrolltop加clientHeight 等於scrollHeight */ if(scrollHeight === (scrolltop+clientHeight)) { loadmore(); } } /* 往下拉時加載的數據 */ /* 使用函數節流優化加載,否則會出現一次性加載很多次 */ function loadmoreresource () { let i = 21; /* 定義是否已經加載 */ let isloading = false; return function () { /* 假如已經在加載中了則直接返回 */ if(isloading) { return; } /* 出現加載動畫 */ loadingimg() let obj = document.getElementById('box'); /* 代碼片段 用於插入多個標簽 */ let docfragment = document.createDocumentFragment(); for(let j=0;j<5;j++){ let li = document.createElement('li') li.append('baojia'+i) docfragment.appendChild(li) i++; } /* 設置當前加載的狀態為true */ isloading = true; /* 使用setTimeout 模擬從api加載數據 */ setTimeout(() => { obj.appendChild(docfragment) loadingimg() /* 將加載狀態設置為false */ isloading = false }, 3000); } } /* 加載動畫 */ function loadingimg() { let loading = document.getElementById('loading'); if(loading.style.display==='block') { loading.style.display = 'none'; } else { loading.style.display = 'block'; } }
