【问题标题】:How to specify the order of a focusout and a click event?如何指定焦点和点击事件的顺序?
【发布时间】:2018-05-14 09:23:27
【问题描述】:

我有一个带有 JS focusout 事件的输入字段。在我的输入字段下,我有一个带有建议的自动完成弹出窗口。但是当我点击一个建议时,它会在点击自动完成的事件监听器之前播放焦点!关于如何解决此冲突的任何线索?

输入及其自动完成的图片:

click 事件:

resultsFrom.addEventListener('click', (event) => {
  let e;
    e = event.target.parentNode;
  inputFrom.value = e.getAttribute('data-display');
});

focusout 事件:

inputFrom.addEventListener('focusout', () => {
  const list = document.querySelector('#results-from');
  let first = list.firstChild;
  inputFrom.value = first.getAttribute('data-display');
  resultsFrom.innerHTML = '';
});

【问题讨论】:

  • click 事件中尝试event.stopPropagation()。或者添加一些变量作为标志(例如var clicked = false)并在click 事件和focusout 中将其设置为真,检查变量是真还是假。然后设置为 false。
  • @KrzysztofJaniszewski 这可能行不通,因为这两个是单独的事件。 stopPropagation() 阻止事件冒泡 DOM 树
  • @MátéSafranka 是的,你是对的

标签: javascript dom-events


【解决方案1】:

focusout eventrelatedTarget 的事件对象上有一个属性 - 这是将获得焦点的元素,在这种情况下,它将是您单击的元素。

您需要检查该元素是否在您的结果中,如果是,请不要将其清除。像这样的:

inputFrom.addEventListener('focusout', (e) => {
  const list = document.querySelector('#results-from');
  if (!list.contains(e.relatedTarget)) {
    //the target is not in the list, continue as before
    //otherwise allow the click to function by not clearing out resultsFrom
    let first = list.firstChild;
    inputFrom.value = first.getAttribute('data-display');
    resultsFrom.innerHTML = '';
  }
});

【讨论】:

  • 感谢您的回答。我试图实现relatedTarget,但它还没有工作。当我放一个 console.log(e.relatedTarget);在if (!list.contains(e.relatedTarget)) {...} 上,每次聚焦发生时都表示为空。我做错了什么?
  • 我认为您可能必须使用无法获得焦点的元素-您使用什么来获得结果?也许他们需要是<a>标签,这样他们才能在点击时获得焦点。
  • 他们是<li>...</li>
  • 好的-然后查看this related answer-除了我上面的答案之外,您还需要这样做,以便您单击的元素可以获得焦点。通过使用默认情况下可以接收焦点的元素,或者该答案表明将tabindex="0" 添加到您的<li>s 也应该有效。
  • 非常感谢你是对的。它就像 tabindex="0" 的魅力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多