IntersectionObserver懒加载

/**
 * 将表单项错误提示移动到 label 上
 */
function moveMessage(elementId: string) {
  const element = document.getElementById(elementId)
  if (!element) return

  const { parentElement } = element
  if (!parentElement) return

  // 1、找到 label 内部的错误信息
  const labelElement = parentElement.querySelector('.arco-form-item-label-col')
  const messageError = labelElement?.querySelector(
    '.arco-form-item-message'
  ) as HTMLElement

  // 2、如果没有错误样式但是还残留提示,就移除它
  const hasError = parentElement.classList.contains('arco-form-item-error')
  if (!hasError && messageError) {
    messageError.remove()
  }

  // 3、将错误提示移动到兄弟元素(label)下
  const message = element.querySelector(
    '.arco-form-item-message'
  ) as HTMLElement
  const broElement = element.previousElementSibling

  if (message && broElement) {
    message.style.display = 'block'
    broElement.appendChild(message)
  }
}

// 监听元素集合
const observers: MutationObserver[] = []

// 停止监听
export const stopObserver = () => {
  observers.forEach((o) => o?.disconnect())
}

/**
 * 全局移动错误提示工具函数
 * @param elementIds 需要移动的表单元素id数组
 * @param foreId 表单Id,默认 my-form
 */
export const handleMoveMessagesFields = (
  elementIds: string[],
  foreId = 'my-form'
) => {
  nextTick(() => {
    elementIds.forEach((elementId) => {
      const fullId = `${foreId}-${elementId}`
      const element = document.getElementById(fullId)
      if (!element) return

      // 建立 MutationObserver 监听 DOM 变化
      const observer = new MutationObserver(() => {
        moveMessage(fullId)
      })

      observer.observe(element, {
        childList: true,
        subtree: true,
        attributes: true,
      })
      observers.push(observer)

      // 初始化执行一次,保证初始状态下也处理好
      moveMessage(fullId)
    })
  })
}

使用
onMount时期调用;onUnmounted停止

  onMounted(() => {
    // 特殊处理错误提示(移动提示到label上)
    handleMoveMessagesFields([
      'patientSource',
      'pathologyNumber',
      'serialNumber',
      'libraryName',
      'patientName',
      'sex',
      'age',
      'inspectionItemName',
      'fees',
      'transmitOther',
    ])
  })

onUnmounted(() => {
    // 停止监听
    stopObserver()
  })
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值