前端开发
521
1、在开发中时长遇到按钮重复点击或者多次点击的情况
比如创建订单或者其他情况,当然也可以通过设置变量开关,禁止状态,这里就分享一个 节流的指令
VUE3好像指令的生命周期和组件的生命周期同步了 //立即执行版本,点击后会执行一次,然后进入定时器 export const throttle = { inserted: function(el, binding) { let timer = null el.addEventListener('click', handClick, false) function handClick() { if (timer) { return } // 当指令传参时 let arg = binding.arg binding.value(arg) timer = setTimeout(() => { clearTimeout(timer) timer = null }, 2000) } el._handClick_ = handClick }, unbind: function(el) { //销毁时 清除事件 if (el._handClick_) { el.removeEventListener('click', el._handClick_, false) el._handClick_ = null delete el._handClick_ } } }
2、使用 注册就不写了
<div v-throttle:1="toHandle" ></div> v-throttle:1 是传了个参数,当然可以不传 v-throttle="toHandle" v-throttle="toHandle(1)",这种写法是绑定了个表达式,不是函数
2、拖拽指令
export const drag = { inserted: function(el, binding) { const willChange = getComputedStyle(el).willChange const position = getComputedStyle(el).position const transform = getComputedStyle(el).transform // 盒子宽高 let width = el.offsetWidth let height = el.offsetHeight // 设备 宽高 getPageX,getPageY 为设备宽高 let pageWidth = getPageX() let pageHeight = getPageY() // 记录手指按下位置 let dX,dY if (['absolute', 'fixed'].indexOf(position) === -1) { el.style.position = 'absolute' } el.style.willChange = willChange === 'auto' ? 'left,top' : `${willChange},left,top` el.style.transform = transform === 'none' ? 'translateZ(0)' : `${transform} translateZ(0)` function start(e) { let box = el.getBoundingClientRect() let touchMsg = e.changedTouches[0] dX = touchMsg.pageX - box.left dY = touchMsg.pageY - box.top el.addEventListener('touchmove',move, false) el.addEventListener('touchcancel',cancel, false) } function move(eMove) { let moveMsg = eMove.changedTouches[0] let top = moveMsg.pageY - dY let left = moveMsg.pageX - dX // 边界值限定 let maxLeft = pageWidth - width let maxTop = pageHeight - height el.style.top = top > maxTop ? maxTop + 'px' : (top > 1 ? top + 'px' : '0px') el.style.left = left > maxLeft ? maxLeft + 'px' : (left > 1 ? left + 'px' : '0px') eMove.preventDefault() } function cancel() { el.removeEventListener('touchstart',start, false) el.removeEventListener('touchmove',move, false) el.removeEventListener('touchcancel',cancel, false) } el.addEventListener('touchstart',start,false) el.__dragTouchstartHandler__ = start }, unbind: function(el) { if (el.__dragTouchstartHandler__) { el.removeEventListener('touchstart', el.__dragTouchstartHandler__, false) el.__dragTouchstartHandler__ = null delete el.__dragTouchstartHandler__ } } }
整体思路: 1、移动端并没有手指按下点到父元素的距离(offsetTop),只有距离页面的 X,Y,所以 用按下点到页面的距离 - 元素距离顶部距离 = 按下点到父元素距离 2、移动时、用移动点位距离 - 按下点到父元素距离 = 定位位置 3、最后 preventDefault()阻止默认行为 4、后面就是指令解绑了