【问题标题】:How can a timeout be cancelled upon a button press?按下按钮后如何取消超时?
【发布时间】:2014-01-18 06:59:57
【问题描述】:

我正在创建一个删除函数来从系统中删除项目。基本上,管理员可以单击删除按钮并删除一个项目。问题出现是因为一些管理员很高兴或过于热情,因此需要撤消删除。

我建议的解决方案是在实际项目被删除之前显示 20 秒的撤消按钮,类似于 Gmail 实验室中的撤消发送电子邮件功能。

function deleteStuff(type,id){
    var element = $("#"+type+id);
    element.slideUp(500,function(){element.html("<button class='btn undoDelete' >UNDO</button>");});
    var timeout = window.setTimeout(element.slideDown(),20000);
    if($(".undoDelete").click()){
         clearTimeout(timeout);
         //replace the item
    } else {
         //delete the item with ajax
    }
}

我知道您可以使用stop()clearTimeout() 停止超时,但我想知道如何在函数中执行此操作。到目前为止,我已经考虑过每秒检查一次点击,直到 20 秒,但我不确定这是否是最有效的方法。

请记住,这个函数可能会被同时调用多次。

明确地说,我知道此功能不完整(例如,不会完全恢复),但这无关紧要。该函数的其余部分只是为超时部分设置上下文。

【问题讨论】:

    标签: javascript jquery timeout


    【解决方案1】:

    那里有一些问题。您使用 jQuery 对象(element.slideUp 的返回值)调用 setTimeout,但您应该给它一个函数。您也永远不会恢复按钮(如果用户单击撤消),并且实际上没有什么可以阻止删除发生。

    我对它做了一个简短的尝试:

    function deleteStuff(type,id){
        var element, timeout;
    
        element = $("#"+type+id);
        element.slideUp(500, function() {
            // Update button and slide down *immediately*
            element.html("<button class='btn undoDelete' >UNDO</button>")
                    .one("click", function() {
                        // Stop the delete
                        clearTimeout(timeout);
    
                        // Restore the button
                        // ...exercise for the reader...
                    },
                    .slideDown();
        });
        timeout = window.setTimeout(function() {
            // Delete item with ajax
        }, 20000);
    }
    

    即使对函数有多个重叠调用,只要 id 值不同,这仍然有效,因为每个调用都有自己的 timeout 变量。


    但是,如果用户删除了某些内容,然后导航离开页面怎么办?作为用户,我的期望是该东西会被删除,但您的删除代码永远不会运行。

    相反,我建议立即将信息发送到服务器,如果用户取消发送那个到服务器。服务器将负责在实际删除之前等待 20 秒。近伪代码:

    function deleteStuff(type,id){
        var element, timeout;
    
        // Send "pending delete" to server
        // ...
    
        // Update button
        element = $("#"+type+id);
        element.slideUp(500, function() {
            element.html("<button class='btn undoDelete' >UNDO</button>")
                    .one("click", function() {
                        // Cancel timer
                        clearTimeout(timeout);
    
                        // Send "cancel delete" to server
                        // ...
    
                        // Restore the button
                        // ...
                    },
                    .slideDown();
        });
        timeout = window.setTimeout(function() {
            // Remove or restore the button
            // ...
        }, 20000);
    }
    

    【讨论】:

    • 你在底部添加的好点。我从来没有想到这一点。最完整和最有帮助的答案。谢谢!
    【解决方案2】:

    Javascript 是单线程的,你不能“等待”一个事件。你必须在事件的处理程序中做你想做的事。

    function deleteStuff(type,id){
        var element = $("#"+type+id);
        timeout = window.setTimeout(function() { element.slideDown() },20000);
        element.slideUp(500,function(){element.html("<button class='btn undoDelete'  data-timeout='"+timeout+"'>UNDO</button>");});
    }
    $(document).on("click", ".undoDelete", function() {
        clearTimeout($(this).data('timeout'));
    });
    

    您需要对.on() 使用事件委托,因为它绑定到动态创建的元素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多