如何在一个元素上使用 'click' 和 'dbclick' 事件?

How do I use 'click' and 'dbclick' events on one element?

我有一个网页标签元素。单击一次时,执行一种逻辑,单击两次时,执行另一种逻辑。但是,DOM 只响应一次单击并立即触发,无论您尝试以多快的速度触发双击事件。

如何在一个元素上使用这两个事件?

export const createTag = (name) => {
  const tag = document.createElement('span');
  tag.innerHTML = name;

  tag.addEventListener('dblclick', () => {
    tags.removeChild(tag);
    storeTags.splice(storeTags.indexOf(name), 1);
  });

  tag.addEventListener('click', () => {
    search.value = tag.innerHTML;
    const keyboardEvent = new KeyboardEvent('keypress', {
      code: 'Enter',
      key: 'Enter',
      charCode: 13,
      keyCode: 13,
      view: window,
      bubbles: true,
    });
    storeTags.splice(storeTags.indexOf(name), 1);
    storeTags.unshift(name);
    search.dispatchEvent(keyboardEvent);
  });

  return tag;
};

实现此目的的基本思路是为 click 操作添加一些小延迟,并在收到 dblclick 时取消延迟。这确实会导致您的 UI 的响应速度降低,因为您的应用程序现在必须以一种“观望”的方式明确区分单击和双击。这也可能是不可靠的,因为用户可以在其设备的辅助功能设置中将任意时间长度设置为双击阈值。

但是,如果认为这些问题还不够令人担忧,那么“最好中最坏”的方法就是手动执行双击检查。

export const createTag = (name) => {
  const tag = document.createElement('span');
  tag.innerHTML = name;

  const clickHander = () => {
    search.value = tag.innerHTML;
    const keyboardEvent = new KeyboardEvent('keypress', {
      code: 'Enter',
      key: 'Enter',
      charCode: 13,
      keyCode: 13,
      view: window,
      bubbles: true,
    });
    storeTags.splice(storeTags.indexOf(name), 1);
    storeTags.unshift(name);
    search.dispatchEvent(keyboardEvent);
  };

  const dblClickHandler = () => {
    tags.removeChild(tag);
    storeTags.splice(storeTags.indexOf(name), 1);
  };

  let clickTimer;
  tag.addEventListener('click', () => {
    if( clickTimer) {
      clearTimeout(clickTimer);
      dblClickHandler();
      clickTimer = null;
    }
    else {
      clickTimer = setTimeout(() => {
        clickHandler();
        clickTimer = null;
      }, 500);
    }
  });

  return tag;
};

根据您的需要调整计时器。较小的数字会导致更灵敏的点击,但会使行动不便的人更难双击。

我真的强烈建议在这里使用不同的 UI。以这种方式重载点击通常是一个非常糟糕的主意。