简体   繁体   English

为什么在父元素上的事件之后触发了按钮上的事件?

[英]Why are my events on button fired after events on parent elements?

Intro 介绍

I am extending photoswipe with my own button & modal dialog, similar to built in share dialog. 我使用自己的按钮和模式对话框扩展了photowipe,类似于内置的共享对话框。

I already made code that worked, but then followed these modifications to photoswipe: https://github.com/dimsemenov/PhotoSwipe/issues/1209 我已经编写了有效的代码,但随后对photoswipe进行了以下修改: https : //github.com/dimsemenov/PhotoSwipe/issues/1209

Now it doesn't work anymore. 现在,它不再起作用了。 Issue is that photoswipe's event handlers get called before mine, so it appears as if user clicked on photoswipe controls and photoswipe hides image, controls & everything and only my modal is visible. 问题在于,photoswipe的事件处理程序会在我的事件之前被调用,因此看起来好像用户单击了photowipe控件,而photowipe隐藏了图像,控件和所有内容,只有我的模态可见。

Diagnostics 诊断程序

I have modified onControlsTap and onGlobalTap and my button click to log to console and I see they are fired in this order: 我修改了onControlsTaponGlobalTap并单击了按钮以登录控制台,我看到它们按此顺序被触发:

onControlsTap
onGlobalTap
Settings button click

Html on the other hand looks like this: HTML看起来像这样:

<div id="globalTapContainer">
  <div id="controlTapContainer">
    <button id="myButton"></button>
  </div>
</div>

And events are registered using addEventListener(..., false) 使用addEventListener(..., false)注册事件

Code

This is my code which binds to click event 这是我的代码,绑定到click事件

  $("#pswp__settings__dropdown_background, .pswp__button--settings")
    .click(function(ev) {
        console.log('Settings button click');
        ev.stopPropagation();
        toggleSettings();
  });

This is photoswipe code that binds events. 这是绑定事件的photowipe代码。

  _controls = framework.getChildByClass(pswp.scrollWrap, 'pswp__ui');
  // ...
  framework.bind(_controls, 'pswpTap click', _onControlsTap);
  framework.bind(pswp.scrollWrap, 'pswpTap', ui.onGlobalTap);

var framework = {
    // ...
    bind: function(target, type, listener, unbind) {
        var methodName = (unbind ? 'remove' : 'add') + 'EventListener';
        type = type.split(' ');
        for(var i = 0; i < type.length; i++) {
            if(type[i]) {
                target[methodName]( type[i], listener, false);
            }
        }
    }
}

My button and modal are one of child nodes of pswp__ui . 我的按钮和模式是pswp__ui的子节点之一。

Question

How is it possible that their events are called before mine when I have registered click event to a specific button? 当我将点击事件注册到特定按钮时,如何在我的事件之前调用他们的事件?

What to do to make photoswipe events not fire when you click on my controls? 当您单击我的控件时,如何使光擦事件不触发?

I'm not familiar with photoswipe, but its events use a custom event called pswpTap , not click . 我不熟悉photowipe,但是其事件使用名为pswpTap的自定义事件,而不是click Presumably this fires when an element is tapped or when the mouse button is pressed. 大概是在点按元素或按下鼠标按钮时触发。 click events don't fire until the mouse button is released, so that would explain why their events are firing before yours. 在释放鼠标按钮之前, click事件不会触发,因此可以解释为什么它们的事件在您之前触发。

Example: 例:

 $('#outerdiv').on('mousedown', function() { console.log('outer mousedown'); }); $('#innerdiv').on('click', function() { console.log('inner click'); }); 
 #outerdiv { width: 100px; height: 100px; background-color: blue; } #innerdiv { width: 40px; height: 40px; background-color: red; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="outerdiv"> <div id="innerdiv"></div> </div> 

You should presumably be able to prevent this by having your element handle and cancel the mousedown event. 您大概应该能够通过拥有元素句柄并取消mousedown事件来防止这种情况。 You may also need to add an event handler for tap events if they work differently from mousedown (I'm not sure whether they are). 如果点击事件与mousedown工作方式不同(可能不确定),则可能还需要为点击事件添加事件处理程序。

 $('#outerdiv').on('mousedown', function() { console.log('outer mousedown'); }); $('#innerdiv').on('mousedown', function(event) { console.log('inner mousedown'); event.stopPropagation(); }); $('#innerdiv').on('click', function() { console.log('inner click'); }); 
 #outerdiv { width: 100px; height: 100px; background-color: blue; } #innerdiv { width: 40px; height: 40px; background-color: red; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="outerdiv"> <div id="innerdiv"></div> </div> 

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

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