解决elementUI使用el-cascader组件报错 Blocked aria-hidden on an element because its descendant retaine focus.

Vue3 使用Element plus中的el-cascader组件时,点选选项控制台报错:Blocked aria-hidden on an element because its descendant retained focus. The focus must not be hidden from assistive technology users. Avoid using aria-hidden on a focused element or its ancestor. Consider using the inert attribute instead, which will also prevent focus. For more details, see the aria-hidden section of the WAI-ARIA specification at Accessible Rich Internet Applications (WAI-ARIA) 1.3.
Element with focus: <li.el-cascader-node is-active#cascader-menu-2096-2-2>
Ancestor with aria-hidden: <div.el-cascader__dropdown el-popper is-light is-pure el-zoom-in-top-leave-from el-zoom-in-top-leave-active#el-popper-5632>

这个错误虽然不影响正常使用,但是看到控制台有错误,估计咱们程序员都是无法忍受的。参考了很多大佬文章,终于找到终级解决办法:

解决办法:

在main.js添加指令removeAriaHidden

import { createApp } from 'vue'

const app = createApp(App)

// 全局注册移除 aria-hidden 属性的自定义指令
app.directive('remove-aria-hidden', {
  mounted (el) {
    // 使用 MutationObserver 监听 DOM 变化
    const observer = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        // 处理添加的节点
        if (mutation.addedNodes && mutation.addedNodes.length > 0) {
          mutation.addedNodes.forEach((node) => {
            if (node.nodeType === Node.ELEMENT_NODE) {
              // 处理级联选择器下拉面板
              if (node.classList && node.classList.contains('el-cascader__dropdown')) {
                node.removeAttribute('aria-hidden')
                const hiddenNodes = node.querySelectorAll('.el-cascader-node[aria-hidden="true"]')
                hiddenNodes.forEach(n => n.removeAttribute('aria-hidden'))
              }

              // 处理级联选择器节点
              if (node.classList && node.classList.contains('el-cascader-node') && node.hasAttribute('aria-hidden')) {
                node.removeAttribute('aria-hidden')
              }

              // 处理后代节点
              const hiddenDescendants = node.querySelectorAll('[aria-hidden="true"]')
              hiddenDescendants.forEach(descendant => {
                if (descendant.classList.contains('el-cascader-node')) {
                  descendant.removeAttribute('aria-hidden')
                }
              })
            }
          })
        }

        // 处理属性变化
        if (mutation.type === 'attributes' && mutation.attributeName === 'aria-hidden') {
          const target = mutation.target
          if (target.classList && (
            target.classList.contains('el-cascader__dropdown') ||
            target.classList.contains('el-cascader-node')
          )) {
            target.removeAttribute('aria-hidden')
          }
        }
      })
    })

    // 开始观察整个文档
    observer.observe(document.body, {
      childList: true,
      subtree: true,
      attributes: true,
      attributeFilter: ['aria-hidden']
    })

    // 初始处理
    const dropdowns = document.querySelectorAll('.el-cascader__dropdown[aria-hidden="true"]')
    dropdowns.forEach(dropdown => dropdown.removeAttribute('aria-hidden'))

    const nodes = document.querySelectorAll('.el-cascader-node[aria-hidden="true"]')
    nodes.forEach(node => node.removeAttribute('aria-hidden'))
  }
})

在组件中使用自定义指令

// ... 
<el-row>
  <el-col>
    <span>选择商品分类:</span>
    <div v-remove-aria-hidden class="cascader-container">
      <el-cascader 
        placeholder="请选择" 
        v-model="selectedOptions" 
        :options="options" 
        :props="cascaderProps"
        @change="handleChange" 
        clearable 
        ref="cascaderRef"
      />
    </div>
  </el-col>
</el-row>
// ... 

在修改onMounted钩子,手动处理可以存在的aria-hidden属性

onMounted(() => {

  // 组件挂载后,手动处理一次可能存在的 aria-hidden 属性
  setTimeout(() => {
    const dropdowns = document.querySelectorAll('.el-cascader__dropdown[aria-hidden="true"]');
    dropdowns.forEach(dropdown => dropdown.removeAttribute('aria-hidden'));
    
    const nodes = document.querySelectorAll('.el-cascader-node[aria-hidden="true"]');
    nodes.forEach(node => node.removeAttribute('aria-hidden'));
  }, 500);
})

在setup中添加对级联选择器引用

setup () {
    const cascaderRef = ref(null) // 添加对级联选择器的引用

    return {
        cascaderRef // 添加对级联选择器引用的返回
    }
}

更新css样式,确保级联选择器的可选择性

<style lang="less" scoped>
.el-alert {
  margin-bottom: 10px;
}

.cascader-container {
  display: inline-block;
}

/* 添加以下CSS来处理aria-hidden问题 */
:deep(.el-cascader-dropdown) {
  .el-cascader-node[aria-hidden="true"] {
    display: none;
  }
  
  /* 确保下拉面板是可见的 */
  &[aria-hidden="true"] {
    display: block !important;
    visibility: visible !important;
  }
}
</style>

到此完美解决,干净的控制台让人心情更舒坦!

PS:只注册自定义组件也可以修复,求稳我还是全部都要了,觉得对您有帮助,点个赞支持一下,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值