编程语言
首页 > 编程语言> > javascript – 单个元素上的多个JS事件处理程序

javascript – 单个元素上的多个JS事件处理程序

作者:互联网

我正在使用现有的Web应用程序,在应用程序中有不同形式的各种提交按钮,一些使用常规http帖子,一些定义onClick函数,一些js事件处理程序使用类上的类绑定到按钮元件.

我想要做的是,通过向按钮添加一个类将另一个事件处理程序绑定到这些按钮,但我想要确定的是新事件处理程序是否会被保证执行,或者表单提交动作之一可能发生在它意味着我的新功能没有被击中之前.

示例场景是我想为这些按钮添加一个类,将它们全部变为一个常见的js函数,该函数只是将使用情况记录到某个api.是否存在因为表单提交已离开页面而未调用日志记录功能的风险?

我没有做过大量的js开发,我可以对它进行100次测试,只是幸运地解雇它.

下面是我为其中一个示例测试过的一些代码 – 再次,我不是要问如何绑定多个事件,问题是关于我对规范的理解以及是否保证所有处理程序的执行.

$(document).ready(function(){
    $('.testingBtn').click(function() {
        window.location.replace("https://stackoverflow.com");
    });
    $( ".testingBtn" ).click(function(){
        alert('submitting!');
    });
});


<input class="testingBtn" type="submit" id="submitform" value="Complete Signup" />

如上所示,我可以绑定多个事件,在这个例子中,只是指向另一个url,但这可能是一个form.submit()等.在我的测试中,警报总是首先触发,但我只是幸运在竞争条件下?

解决方法:

在JS中,您实际上无法控制事件处理程序的调用顺序,但是通过仔细的委派和良好的侦听器,它是可能的.

委派是事件模型最强大的功能之一.您可能知道或者可能不知道:在JS中,事件被传递到dom的顶部,从那里传播到应该应用事件的元素.因此,有理由认为,附加到全局对象的事件侦听器将在已附加到元素本身的侦听器之前调用其处理程序.

window.addEventListener('click',function(e)
{
    e = e || window.event;
    var target = e.target || e.srcElement;
    console.log('window noticed you clicked something');
    console.log(target);//<-- this is the element that was clicked
}, false);//<-- we'll get to the false in a minute

重要的是要注意我们实际上可以访问处理程序中的事件对象.在这种情况下,我们保持事件对象不变,所以它将继续向下传播到目标,在它向下的路上,它可能遇到这样的事情:

document.getElementById('container').addEventListener('click', function(e)
{
    e = e || window.event;
    var target = e.target || e.srcElement;
    if (target.tagName.toLowerCase() !== 'a' || target.className.match(/\bclickable\b/))
    {
        return e;//<return the event, unharmed
    }
    e.returnValue = false;
    if (e.preventDefault)
    {
        e.preventDefault();
    }
}, false);

现在,在窗口级别的侦听器调用其帮助程序之后,将调用此处理程序.这次,如果被点击的元素没有可点击的类,或者元素是链接,则会更改事件.该事件被取消,但它依旧存在.该事件仍然可以在dom中进一步传播,因此我们可能遇到类似的事情:

document.getElmentById('form3').addEventListener('click',function(e)
{
     e = e || window.event;
     if (e.returnValue === false || e.isDefaultPrevented)
     {//this event has been changed already
         //do stuff, like validation or something, then you could:
         e.cancelBubble = true;
         if (e.stopPropagation)
         {
             e.stopPropagation();
         }
     }
}, false);

在这里,通过调用stopPropagation,事件被终止.除非事件已被改变,否则它不能沿着dom进一步传播到其目标.如果没有,事件对象将沿着DOM进一步向下移动,就好像什么都没发生一样.

一旦到达目标节点,事件就进入第二阶段:泡沫阶段.它不是向下传播到DOM的深处,而是向上爬回到顶层(一直到全局对象,它被派遣到那里……从那里来的所有这一切).

在泡沫阶段,所有相同的规则都适用于传播阶段,只是相反.事件对象将首先遇到最接近目标元素的元素,并且最后会遇到全局对象.

There’s a lot of handy, and clear diagrams for this here.我不能把它比任何好的’ol quirksmode更好,所以我建议你阅读他们在那里说的话.

结论:当处理2个事件监听器时,将它们连接在不同的级别上,以便按照您喜欢的方式对它们进行排序.

如果要保证两者都被调用,只能阻止事件在最后调用的处理程序中传播.

当你有两个监听器,连接到同一个事件的同一个元素/对象时,我从来没有遇到过第一个被连接的监听器的情况.

就是这样,我上床睡觉,希望我有道理

标签:javascript,jquery,jquery-events,dom-events
来源: https://codeday.me/bug/20190930/1834571.html