Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/423.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript jQuery';s One-使用多个事件类型触发一次_Javascript_Jquery_Events - Fatal编程技术网

Javascript jQuery';s One-使用多个事件类型触发一次

Javascript jQuery';s One-使用多个事件类型触发一次,javascript,jquery,events,Javascript,Jquery,Events,是否有一种方法可以在引发任何事件时触发单个函数一次 例如,如果我有以下函数:() $('input').one('mouseup keyup',函数(e){ console.log(e.type); }); 我只想调用函数一次,不管是哪个事件触发了它 但是根据for.one(): 如果第一个参数包含多个以空格分隔的事件类型,则为每个事件类型调用一次事件处理程序 因此,当前该函数将针对每种事件类型触发一次。使用并手动删除绑定,而不是使用 小提琴: 使用名称空间可以更优雅地实现这一点: $('i

是否有一种方法可以在引发任何事件时触发单个函数一次

例如,如果我有以下函数:()

$('input').one('mouseup keyup',函数(e){
console.log(e.type);
});
我只想调用函数一次,不管是哪个事件触发了它

但是根据for
.one()

如果第一个参数包含多个以空格分隔的事件类型,则为每个事件类型调用一次事件处理程序

因此,当前该函数将针对每种事件类型触发一次。

使用并手动删除绑定,而不是使用

小提琴:


使用名称空间可以更优雅地实现这一点:

$('input').on('mouseup.foo keyup.foo', function(e){
    console.log(e.type);
    $(this).off('.foo');
});
这允许我们使用单个标识符(foo)删除任意数量的绑定,并且不会影响元素可能具有的任何其他mouseup或keyup绑定


Fiddle:

您只需添加
$('input').off()到函数的末尾。

回答得很好!为了将它们封装到函数中,这里有一个基于当前答案的jQuery扩展:

//The handler is executed at most once per element for all event types.
$.fn.once = function (events, callback) {
    return this.each(function () {
        $(this).on(events, myCallback);
        function myCallback(e) {
            $(this).off(events, myCallback);
            callback.call(this, e);
        }
    });
};
然后这样称呼:

$('input').once('mouseup keyup', function(e){ 
    console.log(e.type);
});
//The handler is executed at most once for all elements for all event types.
$.fn.only = function (events, callback) {
    var $this = $(this).on(events, myCallback);
    function myCallback(e) {
        $this.off(events, myCallback);
        callback.call(this, e);
    }
    return this
};
奖金:这有一个额外的好处,即只需通过传入来分离此特定函数的处理程序。否则,您将需要自定义名称空间

另外,如果您希望处理程序在任何元素触发任何事件时只触发一次,然后立即分离自身,则只需从扩展中删除
每个
,如下所示:

$('input').once('mouseup keyup', function(e){ 
    console.log(e.type);
});
//The handler is executed at most once for all elements for all event types.
$.fn.only = function (events, callback) {
    var $this = $(this).on(events, myCallback);
    function myCallback(e) {
        $this.off(events, myCallback);
        callback.call(this, e);
    }
    return this
};

要触发一次并继续触发,可以使用以下代码段:

它的工作原理是使用
internalCallback
函数临时禁用事件,然后异步(
setTimeout
)再次启用它


此线程中的大多数其他建议禁用目标上的所有未来事件。然而,虽然OP似乎对以前的答案感到满意,但他的问题并没有提到永久禁用事件。

一种简单的方法是临时存储以前的值并进行快速比较:如果没有任何更改,则不要运行函数的其余部分

jQUERY

$('input').on('keyup paste input change', function(e){ 
    var oldValue = $(e.target).data('oldvalue');
    var newValue = $(e.target).val();

    if (oldValue === newValue) //nothing has changed
        return;

    $(e.target).data('oldvalue',newValue); //store the newly updated value

    //proceed with the rest of the function
});
请注意,我使用的是附加事件,而不是

纯JAVASCRIPT

对于纯JavaScript解决方案,需要单独添加侦听器,因为不可能将多个事件传递给


假设您想监听输入框中的更改,我建议不要使用
mouseup
来检测可能的右键单击>粘贴,因为鼠标可以在其他地方释放,而不一定在输入框内。为了安全起见,您最好使用
键控
粘贴
输入
更改
,就像我在上面的代码中所做的那样。

我的思想和培根被保存了!非常感谢你。在多个转换事件中使用.off会使我的瓜扭曲,因为它会为每个事件开火(请注意,请阅读完整的文档)。嘿,Juan,谢谢分享。我认为这并不能真正回答这里提出的问题。如果我有一个
mouseup
keyup
事件,并且我只想处理一次,不管触发了哪一个,比较
oldValue===newValue
并不能达到目的。因此,记下答案并发布您自己的问题来阐明您试图解决的问题可能是值得的。您可以使用anwser中显示的语法以及
$(“#someParent”)。once('keyup etc','someChildrenOfParent'),function(e){doStuff();})?@Drew,如在使用委托时?可能,想先试试吗?这就是我的方法,但我不确定“范围”应该放在哪里,因此函数的行为类似于jQuery的.one()。嗯,我不确定原来的解决方案是否有效,因为我希望在这个测试中,每次按键都会打开/关闭橙色背景:
var selector = document.querySelector('input')
selector.addEventListener('keyup', updateElement);
selector.addEventListener('paste', updateElement);
selector.addEventListener('input', updateElement);
selector.addEventListener('change', updateElement);

function updateElement(e){
    var oldValue = e.target.getAttribute('oldvalue');
    var newValue = e.target.value;

    if (oldValue === newValue) //nothing has changed
       return; 
    console.log (newValue);
    e.target.setAttribute('oldvalue', newValue); //store the newly updated value

    //proceed with the rest of the function
}