【问题标题】:How to execute click function before the blur function如何在模糊功能之前执行点击功能
【发布时间】:2017-01-19 05:31:34
【问题描述】:

我有一个简单的问题,但我似乎找不到任何解决方案。

基本上我有一个输入可以在聚焦时切换下拉列表,当它不再聚焦时它应该关闭下拉列表。

但是,问题是如果你点击下拉列表中的某个项目,blur函数会在该项目的click函数之前执行,导致click函数从下拉列表开始根本不运行在点击注册之前关闭。

我该如何解决这个问题?

<input onFocus="showDropdown()" onBlur="hideDropdown()">
<ul>
  <li onClick="myClickFunc()">item</li>
</ul>

【问题讨论】:

    标签: javascript html css dom dom-events


    【解决方案1】:

    将您的点击事件替换为 (mousedown)。 Mousedown 事件称为 before 模糊。此代码应该可以正常工作:

    <input (focus)="showDropdown()" (blur)="myBlurFunc()">
    <ul>
      <li *ngFor="let item of dropdown" (mousedown)="myClickFunc()">{{item.label}}</li>
    </ul>
    

    看起来点击事件的优先级比模糊低,因此模糊事件首先触发是可预测的行为。

    【讨论】:

    • 这对我来说一直是个问题。感谢您的回答。
    • 但是他们已经抓住了它,如果我们右键单击它也会生效
    • 这是一个简单的修复方法,但它带有一堆奇怪的边缘情况。有更好的选择:stackoverflow.com/a/57983847/202875
    • @AkhilRJ 在这种情况下,您可以使用MouseEvent.button 来查看按下了哪个按钮以忽略该事件。
    【解决方案2】:

    在可以接收焦点的下拉元素中设置选项 - 使用 &lt;a&gt;&lt;button&gt; 或设置 tabindex="-1"。然后,在您的onBlur 处理程序中,检查event.relatedTarget。在onBlur 处理程序中,relatedTarget 是接收焦点的元素(如果有)。如果它是您的下拉列表中的选项之一,那么您知道此时不要隐藏这些选项。

    这比从onClick 切换到onMouseDown 更可取,因为实际点击并不总是紧跟鼠标按下。如果您按下鼠标,将光标移开,然后鼠标向上,您将触发鼠标按下,而不会触发点击。

    const elToggle = document.querySelector('.toggle');
    const elMenu = document.querySelector('.menu');
    elToggle.onfocus = (event) => {
      elMenu.classList.add('open');
    };
    elToggle.onblur = (event) => {
      const didClickMenu = elMenu.contains(event.relatedTarget);
      if (!didClickMenu) {
        elMenu.classList.remove('open');
      }
    };
    .menu {
      display: none;
    }
    .menu.open {
      display: block;
    }
    <button class="toggle">menu</button>
    <ul class="menu">
      <li tabIndex="-1" onClick="console.log('tacos')">tacos</li>
      <li tabIndex="-1" onClick="console.log('burgers')">burgers</li>
    </ul>

    【讨论】:

    • 不一定可以将选项更改为可聚焦元素。
    • 如果不清楚:添加tabindex="-1" 将确保您的元素出现在relatedTarget 中,无论它是什么元素。所以这应该是任何方式的首选答案,因为它不会改变点击行为。
    【解决方案3】:

    这是解决这个问题的另一种方法,它不需要JS:

    .menu {
      display: none;
    }
    .toggle:focus + .menu,
    .toggle + .menu:active {
      display: block;
    }
    <button class="toggle">menu</button>
    <ul class="menu">
      <li onClick="console.log('tacos')">tacos</li>
      <li onClick="console.log('burgers')">burgers</li>
    </ul>

    秘诀在于不仅针对.toggle:focus 状态,还针对.menu:active 状态。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多