请问js 多个按钮防止连续点击,怎么封装

请问js 多个按钮防止连续点击,怎么封装,比如删除和提交和编辑在同一排

阅读 4.7k
4 个回答

对同一数据项的不同操作如果互斥的话,连续操作会带来一些问题,比如前脚刚删掉一项,后面又要改它。
对这个问题,最好的解决方案是前端也维护一个数据列表,所有的增删改查先经过这个列表处理,最后再发给后端,但是这个要从程序设计上就考虑到。
当然也有临时救场的方法,对同一数据项的操作,如果后端还没返回,阻塞后续的操作:

const lockedItems = {};

/**
 * @function checkLock - 检查操作的数据项是否可操作
 * @param {Number|String} id - 数据项的唯一 ID
 * @returns { Boolean } TRUE:可操作
 */
function checkLock(id){
    if(lockedItems[id]){
        return false
    }
    lockedItems[id] = true;
    return true
}

/**
 * @function genLockedFunc - 将操作函数包装,使对同一数据项的操作不连续触发
 * @param {Funciton} func - 操作函数
 * @returns {Funciton} 
 */
function genLockedFunc(func){
    return function(item){
        const id = { item };
        if(checkLock(id)){
            func(item);
        } else {
            // 如有必要,提示用户操作频繁
        }
    }
}

// 删除操作
const deleteItem = genLockedFunc(item => {
    axios.delete(id).then(() =>{
        lockedItems[id] = false;  // delete lockedItems[id]
    });
});

// 修改操作
const modifyItem = genLockedFunc(item => {
    axios.post('/modify', item).then(() =>{
        lockedItems[id] = false;  // delete lockedItems[id]
    });
});

这里在设计上还是有点缺陷,因为需要在 delete 和 modify 函数中手动换解除数据锁,可以进一步改进,不过这里已经够用,把 delete 和 modify 分别绑定对应的按钮就行了。
当然,仅仅是不允许频繁触发的话,讲节流和防抖的文章很多,也可以参考楼上的方法,我的方案会麻烦一点:

/**  
  * @const debounce - 防抖包装器生成器  
  *  
  * @return {Function} 
 */
 const debounce = () => {
    let debounceTimer = 0;  
  
    return (callback, duration = 100, context = undefined, args = []) => {  
        if(!!debounceTimer){  
            clearTimeout(debounceTimer);  
            debounceTimer = 0;  
        }  
        debounceTimer = setTimeout(() => {  
            callback.apply(context, args);
            debounceTimer = 0;
        }, duration);
  
    return null
  }
};

const modifyDebounce = debounce();  // 生成一个防抖函数包装器

// 经过防抖包装的 modify ,200ms 内只能执行一次
// 任意两个函数,经过同一个包装器包装之后,就不会连续执行它们
const modifyItem = deleteDebounce(item => {
    axios.post('/modify', item);
}, 200);

// 也可以这样防抖
const deleteItem = debounce()(function(){
    axios.delete(id);
});

用一个变量lock标记上锁,某个按钮被按下,先检查lock,如果为true,不进行后续操作,否则通常会向后端发起请求,这时候设置lock为true,后端请求结束则lock为false。

var btn = document.getElementById('btn1')
var timer;
    btn.addEventListener('click',function(){
        if(timer){
            clearTimeout(timer);
        }  
        timer = setTimeout(function(){
            console.log(btn.innerHTML); //触发change事件
        },300);//在300ms内连续点击的话,只触发一次change事件
    });

这样的话可以防止用户连续动作导致频繁触发事件,导致占用过多的资源
在一定时间内即使连续动作,也只触发一次事件
是事件节流的思想

debounce 防抖了解一下

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题