代码之家  ›  专栏  ›  技术社区  ›  Dan

在元素外部设置html点击处理程序点击后立即触发

  •  0
  • Dan  · 技术社区  · 2 年前

    我有一个日历图标,上面有 onclick 处理程序,它显示一个弹出日历,我想设置它,以便点击日历弹出窗口之外的任何位置都可以解除它。

    但是,它会立即取消弹出窗口。

    示例代码演示了这个问题:

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width">
      <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
    </head>
    
    <body>
    <img src='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png' width='100px' onclick='fire()' />
    
    <script>
    function fire() {
      console.log('fire');
    
      $('body').on('click', (e) => {
        console.log('clicked outside');
        
        $('body').off('click');
      });
    }
    </script>
    </body>
    </html>

    所以运行上面的代码片段,输出“fire”,然后立即“点击外部”。。。但是为什么,我只在中附加处理程序 fire 功能,那么它怎么能立即启动?

    1 回复  |  直到 2 年前
        1
  •  1
  •   clang_clang    2 年前

    代码中的问题是,当您点击图标时,日历图标点击事件和正文点击事件都会被触发。

    看见 https://api.jquery.com/event.stopPropagation/

    在一个元素上触发的事件传播到其父元素。 在您的情况下,图标单击事件会立即传播到主体元素。

    您可以停止日历图标事件的传播:

    function fire(event) {
      console.log("fire");
      // Stop the event from spreading
      event.stopPropagation();
    
      // Listen to clicks on the body
      $("body").on("click", function () {
        console.log("clicked outside");
        // Remove the listener after it has been triggered
        $("body").off("click");
      });
    }
    

    然后,修改HTML以将事件对象传递给fire()函数:

    <img src='https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png' width='100px' onclick='fire(event)' />
    

    日历图标上的点击事件不会传播到主体,只有在日历图标外部点击时才会触发主体上的点击活动!