简体   繁体   English

Javascript:如何确保仅在先前事件完成后才触发onClick事件?

[英]Javascript: How to ensure that onClick events are only triggered once prior events have completed?

I've written code that colors points on a canvas when the user clicks them. 我编写了在用户单击画布时为画布上的颜色着色的代码。 Points are colored by way of a fade-in animation, so it takes a certain amount of time to color a given point. 通过淡入淡出动画为点着色,因此给指定点着色需要花费一定的时间。 Problems occur if the user clicks a new point while a prior point is still being colored: anomalous colors are produced, fade-in animations continue indefinitely without stopping, etc. 如果用户在仍在着色前一个点的同时单击新点,则会出现问题:产生异常的颜色,淡入动画无限期地继续播放等。

I would like is to make it so that, when the user clicks on a point, any subsequent clicks are ignored until the function coloring that point has completed. 我希望这样做,以便当用户单击某个点时,所有后续单击都将被忽略,直到为该点着色的功能完成为止。 Upon completion, the user should be able to click another point to color it (ie the onClick coloring functionality should be restored). 完成后,用户应能够单击另一个点对其进行着色(即应恢复onClick着色功能)。

In searching for solutions to this problem, I mostly found code designed for events that are only executed once. 在寻找该问题的解决方案时,我主要发现了为仅执行一次的事件而设计的代码。 However, this is not quite what I need. 但是,这并不是我所需要的。 My user should be able to be able to trigger an arbitrary number of coloring events--I just don't want any of these events to ever happen concurrently, as it were. 我的用户应该能够触发任意数量的着色事件-我只是不希望这些事件中的任何一个能够同时发生。 Thanks for any help! 谢谢你的帮助!

You can use locking, like: 您可以使用锁定,例如:

var block = false;
element.addEventListener("click", function () {
    if (block === true) {
        return;
    }
    block = true;
    doOperation("params", function () {
        block = false;
    });
});

function doOperation(input, callback) {
    setTimeout(callback, 1000);
}

This blocks clicks for about 1 second. 这会阻止点击约1秒钟。

Commonly you'll use promises instead of the callback: 通常,您将使用promise而不是回调:

var block_promise = null;
element.addEventListener("click", function () {
    if (block_promise === null || block_promise.is_resolved() === false) {
        return;
    }
    block_promise = doOperation("params");
});

function doOperation(input, callback) {
    var promise = new Promise();
    setTimeout(function () {
        promise.resolve();
    }, 1000);
    return promise.promise();
}

Note that Promises are not (yet) natively supported in JavaScript. 请注意,JavaScript目前尚未支持Promises。 Use your favorite library. 使用您喜欢的库。

If you have a way of setting a flag when painting is occurring, you could try this. 如果您可以在绘画时设置标志,可以尝试一下。 Here I set a flag to true when painting starts and false when it is done. 在这里,我将绘画开始时设置为true,完成时设置为false。 In the buttonClick() function, I immediately exit if painting is true. 在buttonClick()函数中,如果绘画正确,则立即退出。

<!DOCTYPE html>
<html>

<head>
<title>Button Test</title>
</head>

<body>
<script>
var painting = false;
var clicks = 0;

function buttonClick() {

    //if painting, immediately exit buttonClick
    if (painting)
        return;

    //display click count whenever we enter here
    clicks++;
    var obj = document.getElementById("clicks");
    obj.value=clicks;

    //simulate painting
    painting = true;
    document.getElementById("status").innerHTML = "painting in progress";
    setTimeout(function() { colorPoint()}, 10000 /* 10 seconds */ );

}

function colorPoint() {
    //simulated painting
    painting = false; //allows button to be clicked again
    document.getElementById("status").innerHTML = "painting done";
}

</script>

<button onclick="buttonClick()">Click me</button>
Button clicks: <input type="text" name="clicks" id="clicks">
<div id="status"> </div>

</body>
</html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM