替换的超时事件触发两次或两次以上(有时)

Replaced timeout event fires twice or more (sometimes)

本文关键字:两次 有时 超时 替换 事件      更新时间:2023-09-26

我有一段内容,用户可以在双击后对其进行编辑。如果用户更改了内容,然后停止2秒,则更新后的内容将发送到服务器以进行保存。

为此,我将一个input事件侦听器绑定到开始2秒倒计时的部分,如果已经有倒计时,则前者将被取消,而新的倒计时将开始。在倒计时结束时,将向服务器发送一个带有新数据的http POST请求。

问题是,有时在倒计时结束时,我会看到发送了2个或多个请求,就好像在插入新的倒计时之前没有取消倒计时一样,我不知道为什么。

有问题的代码如下:

//this function is bound to a double-click event on an element
function makeEditable(elem, attr) {
    //holder for the timeout promise
    var toSaveTimeout = undefined;
    elem.attr("contentEditable", "true");
    elem.on("input", function () {
        //if a countdown is already in place, cancel it
        if(toSaveTimeout) {
            //I am worried that sometimes this line is skipped from some reason
            $timeout.cancel(toSaveTimeout);
        }
        toSaveTimeout = $timeout(function () {
            //The following console line will sometimes appear twice in a row, only miliseconds apart
            console.log("Sending a save. Time: " + Date.now());
            $http({
                url: "/",
                method: "POST",
                data: {
                    action: "edit_content",
                    section: attr.afeContentBox,
                    content: elem.html()
                }
            }).then(function (res) {
                $rootScope.data = "Saved";
            }, function (res) {
                $rootScope.data = "Error while saving";
            });
        }, 2000);
    });
    //The following functions will stop the above behaviour if the user clicks anywhere else on the page
    angular.element(document).on("click", function () {
        unmakeEditable(elem);
        angular.element(document).off("click");
        elem.off("click");
    });
    elem.on("click", function (e) {
        e.stopPropagation();
    });
}

事实证明(在上面评论员的帮助下)函数makeEditable被调用了不止一次。

在函数开头添加以下两行代码修复了问题:

//if element is already editable - ignore
if(elem.attr("contentEditable") === "true")
    return;