可以使用ResizeObserver来防止元素上的Onclcik事件

问题描述

我试图找出一种方法来检测TextArea的大小,以便防止其onClick事件被触发。原因是,在调整TextArea的大小时,它还会触发onClick事件。但是,onClick事件处理程序有一些逻辑,如果需要调整大小,则需要跳过。

我尝试使用ResizeObserver API来检测resize事件。但是,似乎无法找到“事件”,因此我可以对其执行preventDefault来跳过onClick事件。

不确定ResizeObserver是否可以这种方式使用。 是否有人使用REsizeObserver或任何其他方法满足了此类要求?

解决方法

不幸的是,除了窗口之外,元素上没有resize事件,但是我想说这是使用ResizeObserver API的可靠用例。

在这里,我尝试构建一些使用API​​的东西,并在每次调整大小时创建一个自定义事件。由于观察者将不断在每个调整大小的像素上触发,因此我在回调中添加了一个反跳功能。闲置200ms后将触发事件。

然后,它将使用调整大小观察器中的数据触发事件,您的字段可以监听该事件。

我并不是说您应该这样做,但是它说明了如何使用此API进行自己的 resize事件

const field = document.querySelector('.field');

field.addEventListener('click',event => {
  event.preventDefault();
});

field.addEventListener('textarearesize',event => {
  console.log('Resize triggered');
  const { contentRect } = event.detail;
  const { width,height } = contentRect;
  field.value = `width: ${Math.floor(width)},height: ${Math.floor(height)}`;
});

const onResizeCallback = (() => {
  let initial = true;
  let timeout;
  return entries => {
    if (initial) {
      initial = false;
      return;
    }
    clearTimeout(timeout)
    timeout = setTimeout(() => {
      for (const entry of entries) {
        const event = new CustomEvent('textarearesize',{
          detail: entry
        });
        entry.target.dispatchEvent(event);
      }
    },200);
  }
})()

const observer = new ResizeObserver(onResizeCallback);

observer.observe(field);
<textarea class="field" name="description">Hello,I'm a textarea</textarea>

或者,每次释放鼠标时,您都可以检查字段的高度或宽度是否发生了变化。与上面的示例相比,它不需要ResizeObserver,创建起来也不那么复杂,并且行为也更可预测。

const field = document.querySelector('.field');

const watchField = field => {

  let width = field.offsetWidth;
  let height = field.offsetHeight;
  
  const areDimensionsChanged = (newWidth,newHeight) => 
    width !== newWidth || height !== newHeight;

  field.addEventListener('mouseup',event => {
    const { target } = event;
    const { offsetWidth,offsetHeight } = target;
    if (areDimensionsChanged(offsetWidth,offsetHeight)) {
      width = offsetWidth;
      height = offsetHeight;
      const event = new CustomEvent('textarearesize');
      target.dispatchEvent(event);
    }
  });

}

field.addEventListener('textarearesize',event => {
  console.log('Resize triggered');
});

watchField(field);
<textarea class="field" name="description">Hello,I'm a textarea</textarea>