标签的自定义属性
标签里有一个dataset属性
通过在标签里设置data-自定义来设置自定义属性
例: <div class="box " data-mybox="mybox1"> box1 </div>
预加载和懒加载
预加载:提前加载
let img = new Image();
img.src = 'https://img123'; //在触发事件前就加载完毕
let btn = document.querySelector('button');
let box = document.querySelector('.box');
btn.onclick = function(){
box.innerHTML = `<img src="https://img123" alt="">`;
}
懒加载:延迟加载
当访问一个页面的时候,先把img元素或是元素的背景图片路径替换成另一张图片的路径(这样就只需请求一次,俗称占位图),只有当图片出现在浏览器的可视区域内时,才设置图片真正的路径。
<img src="./img/load.png" alt="" data-src="./change1.png">
<img src="./img/load.png" alt="" data-src="./change2.png">
<img src="./img/load.png" alt="" data-src="./change3.png">
<script>
let allImg = document.querySelectorAll('img'); //获取所有img标签
window.onscroll = function(){ //window绑定滚动事件
if(allImg[0].getBoundingClientRect().y<window.innerHeight){//判断第一个img是否显示在用户视觉范围内
allImg.forEach(el=>el.src = el.dataset.src) //遍历每个img标签,将其src属性值改为自定义src属性值
}
}
</script>
防抖和节流
防抖:
针对于高频触发事件,让事件处理函数延迟一段时间执行,如果在这段时间内,再次触发事件,则重新开始计时,在重新计时的这段延迟时间内没有再次触发则执行事件处理函数。
let box = document.querySelector('.box');
let tid = 0;
box.onmousemove = function(){
if(tid) {
clearTimeout(tid);
}
tid = setTimeout(()=>{
console.log("逻辑代码");
tid = 0;
},1000);
}
节流:
针对于高频触发事件,让事件处理函数每隔一段时间执行一次,稀释执行频率。
let box = document.querySelector('.box');
let tid = 0;
box.onmousemove = function(){
if(tid){ //500ms内触发时tid有值
return ; //跳出,不再执行后续计时器代码
}
timeout = setTimeout(()=>{
console.log("逻辑代码");
tid = 0;
},500);
}
防抖和节流的函数封装
防抖 (Debounce)
function debounce(fn,wait){
let tid = 0;
return function () { //调用debounce函数返回一个事件处理函数
// console.log(111,this); //this为box标签
// console.log(222,event); //有一个事件处理对象event
let ev = event; //事件处理函数里的事件处理对象event保存到变量ev中。
if (tid) {
clearTimeout(tid);
}
tid = setTimeout(() => {
// console.log(222,this); //this为box标签
// console.log(444,event); //undeinfed,事件处理对象只在事件处理函数里,计时器函数里面没有事件处理对象event。
fn.call(this,ev); //调用fn(即传入的逻辑代码函数moveFn),修改fn里面的this指向box标签(不修改则this为window),并传入变量ev到逻辑代码函数moveFn中。
tid = 0;
}, wait);
}
}
box.onmousemove = debounce(moveFn,500); //绑定事件,调用debounce函数,传参逻辑代码函数moveFn和延迟时间
function moveFn(e){ //传入变量ev
console.log("逻辑代码");
console.log('this:',this); //打印box标签
console.log('event:',e); //打印ev为一个事件处理对象event
}
一般的逻辑问题无非就是以下三点
1.想一下this
2.声明一个变量
3.event(事件对象)
节流 (Throttle)
function throttle(fn,wait){
let tid = 0;
return function(){
let ev = event;
if(tid){
return ;
}
tid = setTimeout(()=>{
fn.call(this,ev);
tid = 0;
},wait);
}
}
box.onmousemove = throttle(moveFn,200);
function moveFn(e){
console.log("逻辑代码");
console.log('this:',this);
console.log('event:',e);
}