高频事件(处理函数)
在DOM Event的世界中,以oninput、onscroll、onresize、mouseover、touch等为代表的高频触发事件显得有些与众不同。通常,DOM事件只有在明确的时间点才会被触发,比如被点击,比如XMLHttpRequest状态更改等等;而高频事件则是在整个动作时期内反复触发反复调用callback,为整个站点的流畅运行留下了性能隐患
这里以oninput为例(element-ui)。
业务场景:当在input输入相关的关键字时,请求后台 查询关键字所对应的列表信息。
方式一、使用setTimeout
输入后,停顿3s后输出;
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<script src="https://unpkg.com/vue@next"></script>
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-plus/lib/theme-chalk/index.css">
<!-- import JavaScript -->
<script src="https://unpkg.com/element-plus/lib/index.full.js"></script>
<title>Element Plus demo</title>
</head>
<body>
<div id="app">
<el-button>{{ message }}</el-button>
<el-input v-model="input" placeholder="请输入内容" @input="oninput"></el-input>
</div>
<script>
const App = {
data() {
return {
message: "Hello Element Plus",
input:'',
timeout:null
};
},
methods:{
oninput:function(input){
if(!this.timeout){
this.timeout = setTimeout(function(){
console.info(input)
},2000)
}else{
// 清除上个定时任务
clearTimeout(this.timeout);
this.timeout = setTimeout(function(){
console.info(input)
},2000)
}
}
}
};
const app = Vue.createApp(App);
app.use(ElementPlus);
app.mount("#app");
</script>
</body>
</html>
方式二、使用标识控制
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<script src="https://unpkg.com/vue@next"></script>
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-plus/lib/theme-chalk/index.css">
<!-- import JavaScript -->
<script src="https://unpkg.com/element-plus/lib/index.full.js"></script>
<title>Element Plus demo</title>
</head>
<body>
<div id="app">
<el-button>{{ message }}</el-button>
<el-input v-model="input" placeholder="请输入内容" @input="oninput"></el-input>
</div>
<script>
const App = {
data() {
return {
message: "Hello Element Plus",
input:'',
timeout:null,
startFlag : false
};
},
methods:{
oninput:function(input){
var _this = this;
if(_this.startFlag){
return
}else{
// 执行开始,设置flag
_this.startFlag = true;
// 模拟执行中......
setTimeout(function(){
console.log(input);
// 执行完毕,重置flag
_this.startFlag = false;
}, 2000);
}
}
}
};
const app = Vue.createApp(App);
app.use(ElementPlus);
app.mount("#app");
</script>
</body>
</html>