多标签互斥回车查询

253 阅读2分钟

回车查询一定很熟悉,就是window添加键盘监听器,key=”enter“就执行搜索函数

现在有个假设,这个页面内有多个标签页,回车查询都使用的window.addLiastener,这就会产生bug,其中一个标签页触发回车,其他标签页也会触发回车查询。

vue有个现成指令是”@keypress.enter="performSearch"“,但我用的JSX,只能自己用 JavaScript 的语法来实现。

addEventListener


首先得要了解addEventListener,我之前认为 window.addEventListener 是固定写法,其实不然。 贴上MDN对其定义。

developer.mozilla.org/zh-CN/docs/… EventTarget.addEventListener()  方法将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行。事件目标可以是一个文档上的元素 ElementDocument 和 Window,也可以是任何支持事件的对象(比如 XMLHttpRequest)。

回车查询


知道了addEventListener的原理后,就知道EventTarget不能选择window了,而是每个标签页的表单了。

我用的table组件是vxe,没有获取formConfig的函数,只能给个classname,原生获取了。有条件的可以使用Ref

UI代码

formConfig: {
    className: 'my-form-bar',
    titleWidth: 70,
    titleOverflow: true,
    titleAlign: 'left',
    collapseStatus: collapseStatus.value,
    data: {},
    items: [
      
      {
        field: 'create_time',
        title: '创建日期',
        folding: true,
        span: 6,
        itemRender: { name: 'FormItemDatePickerRange', props: { type: 'daterange' } }
      },
      {
        field: 'status',
        title: '状态',
        folding: true,
        span: 6,
        itemRender: {
          name: 'FormItemSelect',
          props: {
            options: statusOptions
          }
        }
      },
      {
        span: 24,
        align: 'right',
        className: collapseNodeSpan,
        collapseNode: true,
        slots: {
          default: () => {
            return renderFormBarAction()
          }
        }
      }
    ]
  }

JS代码

逻辑就是传入类名,获取到表单Element,然后给这个El添加回车事件,触发搜索

const methods = {
  /**
   * 处理搜索输入的键盘事件
   * @param {KeyboardEvent} event - 键盘事件.
   */
  handleSearchKeydown: (event: KeyboardEvent) => {
    console.log('handleSearchKeydown', event)
    if (event.key === 'Enter') {
      event.stopPropagation() // 阻止冒泡事件
      methods.setSearchParams()
    }
  },
  /**
   * 为指定类名的元素添加键盘事件监听器。
   * @param {string} className - 目标元素的类名。
   * @returns {() => void} 返回一个函数,用于移除事件监听器。
   */
  addKeydownListener: (className: string): (() => void) => {
    const element = document.querySelector(`.${className}`)
    console.log('Element:', element) // 打印获取到的元素

    // 类型判断
    if (element instanceof Element) {
      element.addEventListener('keydown', methods.handleSearchKeydown)
      // 返回移除监听器的函数
      return () => {
        element.removeEventListener('keydown', methods.handleSearchKeydown)
      }
    } else {
      console.warn('未找到元素或该元素不是一个有效的 Element')
      return () => {} // 返回一个空函数
    }
  },
  renderFormBarAction: () => {
    return (
      <div onKeydown={methods.handleSearchKeydown}>
        <ElButton type="primary" onClick={() => methods.setSearchParams()}>
          查询
        </ElButton>
        <ElButton type="info" onClick={() => methods.resetSearchParams()}>
          重置
        </ElButton>
      </div>
    )
  }
}