jQuery - 如何确保一个函数在多个绑定和事件触发时只运行一次?

jQuery - How can I make sure a function only runs once with multiple bindings and events firing?

所以我正在使用 jQuery.payment 处理信用卡号文本输入字段。当用户输入任何第 4 个数字(4、8、12)时,插件会自动放入一个 space 以获得漂亮的外观。因此,只会触发 keyup 事件,不会触发 input 事件。但是,如果用户右键单击并粘贴一个值,则只会触发 input 事件。所以我们有这样的情况,其中一个或另一个,或两个事件都触发。

我为 change keyup input 绑定了一个匿名函数,以确保涵盖所有用例,但我希望该函数在每次按键时仅 运行 一次,但正常按键同时触发 keyupinput。 jQuery 的 .one() 不是一个选项,因为此功能需要 运行 不止一次,而不是一次按键两次。我怎样才能确保这个函数只有 运行s 一次,即使两个事件都是从一个按键触发的?

我知道我可以编辑 jQuery.payment 并触发 input 事件,但我不想修改供应商插件,以防我决定更改版本或其他东西.

我会使用 jQuery 更改事件并始终确保该事件之前未绑定。而且我不会遵循 "when user presses the 4th digit" 这样的逻辑。相反,我每次都会格式化整个文本。

function MyInputChanged(){
  var currentText = $("#myInput").val();
  var newText = someFunctionToFormatText(currentText);
  $("#myInput").val(newText);
}

$("#myInput").unbind("change", MyInputChanged);
$("#myInput").bind("change", MyInputChanged);

您可以整天使用 attaching/detaching 事件处理程序,但永远不会找到成功的公式。

如果您的事件处理程序是 idempotent(对于给定的输入状态),那么您无需担心会触发它两次。

如果处理程序不是天生幂等的,那么您可以包含一个条件,以确保具有相同输入值的第二次连续调用不执行任何操作。有点做作,但这也算是"forced idempotence".

为此,输入元素的 "last state"(其值)需要存储、回读和测试。

您可以将状态存储在某些 outer/global javascript var 中,但使用元素本身的 '.data()' 属性 更整洁(实际上是 100% js,没有推入DOM).

$(function() {
    $("#myInput").on("keyup input", function(e) {
        var $this = $(this),
            $lastState = $this.data('lastState') || '',//read back the element's previous state (or empty string if this is the first call)
            val = $this.val();//current state
        if(val !== $lastState) {//the all-important test.
            $this.data('lastState', val);//store current state to be read back at next call
            //here do whatever is required of your event handler.
        }
    });
});