jQuery maskedinput 触发器在粘贴时完成两次

jQuery maskedinput triggers completed twice on paste

我正面临 jQuery maskedinput 的这个错误。

在屏蔽输入上粘贴值会触发完成的事件两次。 这种行为可以在他们的官方网站上看到。

打开 this link 并单击 Demo。 Select Product Key 输入并键入 aa-999-a999。 之后,尝试在字段中粘贴相同的值。

还有一些其他问题与粘贴时不触发事件有关,但 none 帮助我解决了这个错误...

有人知道原因或遇到过类似问题吗?

提前致谢。

所以我尝试了一个像这样的最简单的案例(使用 this for maskedinput.js, though note that I edit it, below, and this 作为 jquery-1.11.2.js):

<html>
<body>
    <script type="text/javascript" src="./jquery-1.11.2.js"></script>
    <script type="text/javascript" src="./jquery.maskedinput.js"></script>

    <script type="text/javascript">
    jQuery(function($) {
          $.mask.definitions['~']='[+-]';
          $("#tin").mask("99-9999999",{completed:function(){alert("Now you typed: "+this.val());}});
       });
    </script>

    <table border="0">
    <tbody>
        <tr>
            <td>Tax ID</td>
            <td><input type="text" tabindex="5" id="tin"></td>
            <td>99-9999999</td>
        </tr>
    </tbody>
    </table>
</body>
</html>

我还稍微编辑了 maskedinput 源代码,看看什么时候触发,从哪里触发。 I'll paste.ee it here,但这里是主要部分...

  • 找到 .on("blur.mask")...
  • 请注意,它为 blurkeydowninputpaste 重复使用相同的函数。
  • 添加一个 console.log 来告诉您每次调试粘贴时触发的具体事件。

这是我所做的(请注意,如果您使用的是 IE8-,则需要 "protect" console.log 调用或 运行 打开开发工具):

}).on("blur.mask", blurEvent).on("keydown.mask", keydownEvent).on("keypress.mask", keypressEvent).on("input.mask", function() {
    console.log("mask called: " + arguments[0].type); // <<< New debugging line.
    input.prop("readonly") || setTimeout(function() {
        var pos = checkVal(!0);
        input.caret(pos);
        tryFireCompleted("mask");
    }, 0);
}), chrome && android && input.off("input.mask").on("input.mask", androidInputEvent),

当您粘贴内容时,会为 "same" 操作调用两个事件处理程序。

mask called: paste
mask called: input

它们最终都会调用 tryFireCompleted,这会触发我们在上面这行我们自己的代码中设置的 .completed 函数:

$("#tin").mask("99-9999999",{completed:function(){alert("Now you typed: "+this.val());}});

如果删除 paste.mask 事件处理程序,该问题就会消失。这是关键部分:

.on("input.mask paste.mask",
...变为...
.on("input.mask",
... 所以 paste.mask 不见了。 (当然,在发布到生产环境之前,删除 console.log 行。)

现在这可能完全独立了。粘贴正在发射 input,因此 paste 也可能有点矫枉过正。但在我将其用作永久修复之前,我会多检查一下。我确实尝试用鼠标右键单击粘贴,这个更改很好。不确定 paste 何时触发而 input 未触发。

如果 一个边缘情况,其中 paste 被调用而 input 不是(或者您真的想要 tryFireCompleted 触发两次),你需要找到一种方法来用更复杂的代码抑制第二个 tryFireCompleted

不过,如果没有 completed 函数,我认为触发两次不会是一个明显的问题,这就解释了为什么这可能会被忽略。好发现。