防抖与节流(vue-自定义指令)
防抖
- 解释:触发事件后,一段时间内没有再次触发则执行,若此时间段内再次触发重新延时!
v-antiShake
// 实现
Vue.directive('antiShake', {
// 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
/**
* el 指令所绑定的元素,可以用来直接操作 DOM 。
* binding 一个对象,包含绑定的值
*/
inserted: function(el, binding) {
const { callback, time } = binding.value
el.callback = callback
el.time = time
el.timeCall = null
el.addEventListener('click', () => {
clearTimeout(el.timeCall)
el.timeCall = setTimeout(() => {
el.callback()
}, el.time || 500)
})
},
// 所在组件的 VNode 更新时调用
update: function(el, binding) {
console.log('update')
const { callback, time } = binding.value
el.callback = callback
el.time = time
},
})
- 核心原理
const { callback, time } = binding.value
el.callback = callback
el.time = time
el.timeCall = null
el.addEventListener('click', () => {
clearTimeout(el.timeCall)
el.timeCall = setTimeout(() => {
el.callback()
}, el.time || 500)
})
- 通过定时器setTimeout延时执行click回调,当el.time || 500 时间内,再次触发时 clearTimeout(el.timeCall)关闭定时器,再次重新延时
- el.callback = callback 和 el.time = time 挂在el上是为了,当v-antiShake绑定的值更新后,事件触发更新后的callback
update: function(el, binding) {
console.log('update')
const { callback, time } = binding.value
el.callback = callback
el.time = time
},
使用
- 指令的值testClick未做深watch,只有对象整体改变才会触发指令中update钩子函数
<button v-antiShake="testClick">click</button>
// testClick
testClick: {
time: 1000,
callback: () => {
console.log(1111)
console.log(this.test)
}
}
节流
- 一段时间内首次触发时立即执行,此时间段内再次触发,不会执行!
// 实现
Vue.directive('throttling', {
// 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
inserted: function(el, binding) {
const { callback, time } = binding.value
el.callback = callback
el.time = time
el.addEventListener('click', () => {
const nowTime = new Date().getTime()
if (!el.preTime || nowTime - el.preTime > el.time) {
el.preTime = nowTime
el.callback()
}
})
},
update: function(el, binding) {
console.log('update')
const { callback, time } = binding.value
el.callback = callback
el.time = time
}
})
- el.preTime 记录上次触发事件,每次触发比较nowTime(当前时间) 和 el.preTime 的差是否大于指定的时间段!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。