element
element copied to clipboard
[Bug Report] Cascader 级联选择器连续多次点击浏览器卡死
Element UI version
2.11.1
OS/Browsers version
win10/chrome 103版本64 位
Vue version
2.3.3
Reproduction Link
https://codepen.io/517399251/pen/bGvgvqB?editors=1100
Steps to reproduce
连续多次的点击多选可搜索的示例,界面会出现卡死的现象,cpu占用超过100%
What is Expected?
浏览器界面不卡死
What is actually happening?
界面卡死无法操作
试了你提供的demo,并没有复现。会不会是你浏览器插件导致?
我也出现了这个问题 ,我的element 版本是 2.13.2,多次选择后浏览器渲染进程卡住,cpu占用到100,其他tab不受影响。我的chrome是104
我的也出现了浏览器卡死现象,但无法稳定复现 element-ui: 2.13.2 chome: 104.0.5112.79
我的是层级比较深时浏览器卡死,但是无法稳定复现 element-ui:2.11.0
我也遇到了 但是无法必现
经过测试,是chrome104版本比较容易重现。但是也只有部分的用户会出现。不是全部用户都能重现,
原因是使用了 aria-owns
属性,我在最新的测试中,删除了.el-cascader-node
节点的这个属性,能解决这个问题
我的也出现了,快速多次点击展开然后失焦! element-ui: 2.14.1,chome: 104.0.5112.82
我也遇到了,还以为是数据量太大,但是数据少量的时候也会出现; element-ui: 2.13.2版本,chrome 104.0.5112.102
经过测试,是chrome104版本比较容易重现。但是也只有部分的用户会出现。不是全部用户都能重现, 原因是使用了
aria-owns
属性,我在最新的测试中,删除了.el-cascader-node
节点的这个属性,能解决这个问题
我这边也遇到了类似的问题,按照这个方式解决了,但不清楚具体的原因,能解释一下么? @luomu172
@zeelq 您好,能说下具体实现细节吗?我尝试把"el-cascader-node": false 置为false发现有样式问题以及change事件总是选到最后一个!
更改图片:
@zeelq 您好,能说下具体实现细节吗?我尝试把"el-cascader-node": false 置为false发现有样式问题以及change事件总是选到最后一个! 更改图片:
我是参考了 @luomu172 提供的解决思路,通过操作dom方式解决的,没更改组件源码,你可以参考下:
const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns"))
在Cascader组件的.el-cascader-node 元素生成后移除aria-owns属性。
好的,我尝试一下;谢谢。@zeelq
经过测试,是chrome104版本比较容易重现。但是也只有部分的用户会出现。不是全部用户都能重现, 原因是使用了
aria-owns
属性,我在最新的测试中,删除了.el-cascader-node
节点的这个属性,能解决这个问题我这边也遇到了类似的问题,按照这个方式解决了,但不清楚具体的原因,能解释一下么? @luomu172
mdn查看这个属性,是给渲染提供关系指导。具体为什么会卡死,和浏览器对这块的实现有关系,如果在深入 的话,需要去看浏览器的实现原理,这块我了解不足,所以无法告知你具体的原理。有兴趣的话,你可以在深挖一下,如有结论,希望能告知我一下
这个问题很严重啊 我这边是一直稳定出现,无论数据有几个都会出现 就是官方的demo
在win10系统chrome/edge,在编辑/新增几次后稳定出现卡顿问题,mac就不会出现该问题 一些自己的原因导致element-ui不好升级版本,头痛
好的,我尝试一下;谢谢。@zeelq
在Cascader组件的.el-cascader-node 元素生成后移除aria-owns属性。 请问如何知道.el-cascader-node生成了? 我遇到的一个情况为只有个别人点击级联选择器就会导致页面崩溃,但是其他人使用起来正常,想请教下 const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns")); 这两行代码在什么情况下运行?我不知道在什么样的情况下使用这个方法,换句话说,这个应该需要一个函数触发吧,就像@click函数这样触发,能写个demo吗 ———————————— 另一个issue上给我的回答是在mounted上运行,但是我的理解是此时级联选择器子节点还没有出现,应该拿不到el-cascader-panel .el-cascader-node这个节点吧
这是他的代码 mounted () { const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns")); };
我在mounted中打印console.log($el)是这样的结果
使用的vue版本是3.1.2
element-plus版本是1.0.2-beta.52
好的,我尝试一下;谢谢。@zeelq
在Cascader组件的.el-cascader-node 元素生成后移除aria-owns属性。 请问如何知道.el-cascader-node生成了? 我遇到的一个情况为只有个别人点击级联选择器就会导致页面崩溃,但是其他人使用起来正常,想请教下 const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns")); 这两行代码在什么情况下运行?我不知道在什么样的情况下使用这个方法,换句话说,这个应该需要一个函数触发吧,就像@click函数这样触发,能写个demo吗 ———————————— 另一个issue上给我的回答是在mounted上运行,但是我的理解是此时级联选择器子节点还没有出现,应该拿不到el-cascader-panel .el-cascader-node这个节点吧
这是他的代码 mounted () { const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns")); };
我在mounted中打印console.log($el)是这样的结果
使用的vue版本是3.1.2 element-plus版本是1.0.2-beta.52
可以试试在 option赋值以后
this.$nextTick(() => { // 添加这段代码 const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns")); })
@zeelq 您好,能说下具体实现细节吗?我尝试把"el-cascader-node": false 置为false发现有样式问题以及change事件总是选到最后一个! 更改图片:
我是参考了 @luomu172 提供的解决思路,通过操作dom方式解决的,没更改组件源码,你可以参考下:
const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns"))
在Cascader组件的.el-cascader-node 元素生成后移除aria-owns属性。
我参考了上述方法,可以在main.js 文件直接监听 dom 处理。所有组件都生效,可以不用再去组件中处理了。 如果怕污染全局变量,可以包裹在一个函数中执行。
var observer = new MutationObserver(function (mutations, observer) {
mutations.forEach(function (mutation) {
mutation.addedNodes.forEach(node => {
if (node.nodeType === 1) {
const $el = node.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute('aria-owns'))
}
})
})
})
observer.observe(document.body, {
characterData: false,
childList: true,
attributes: false,
subtree: true
})
测试了一下 可在级联框绑定的@change事件中添加 handlChange(value) { // 修复级联选择器连续多次点击浏览器卡死 cpu占用超过100%bug const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns")); }
我只是用了最基本的联级组件,数据量也不大,部分用户频繁点击几下就会卡死且稳定复现,cpu占用超过100%,页面无响应
测试了一下 可在级联框绑定的@change事件中添加 handlChange(value) { // 修复级联选择器连续多次点击浏览器卡死 cpu占用超过100%bug const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns")); }
谢谢,我们项目组有额外封装,在 CascasderPanel 显示出来的时候,将DOM中元素处理掉就好了
您好我已收到您的邮件!!看到后立马回复
目前发现Mac系统的Chrome必现,win的还好,但是CPU确实飙高。 飙高的情况再我的笔记本上必现,由于组件开启了搜索过滤,直接点击右侧下拉有几率不stuck,只要点击搜索部分必然stuck,CPU1 100% 临时解决方案
@visible-change="e => cascaderVisable(e, item)"
cascaderVisable (e, item) {
// 根据ElementUI的BUG提示 https://github.com/ElemeFE/element/issues/22060
const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]')
Array.from($el).map(item => item.removeAttribute('aria-owns'))
if (item.visible !== undefined && item.visibleChange) {
item.visibleChange(e)
}
},
环境
chrome:版本 109.0.5414.119(正式版本) (arm64)
系统:
测试了一下 可在级联框绑定的@change事件中添加 handlChange(value) { // 修复级联选择器连续多次点击浏览器卡死 cpu占用超过100%bug const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns")); }
谢谢,我们项目组有额外封装,在 CascasderPanel 显示出来的时候,将DOM中元素处理掉就好了
您好,想请问一下这个具体是怎么处理的呀,目前使用上述的这个方法还是解决不了问题@IvanChen008
测试了一下 可在级联框绑定的@change事件中添加 handlChange(value) { // 修复级联选择器连续多次点击浏览器卡死 cpu占用超过100%bug const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns")); }
您好,你使用了这个方法就不会出现卡顿现象了吗,我使用同样的方法但是客户的电脑卡顿任然出现,我和客户使用的都是Chrome109.0.5414.120版本,我的电脑从来都没出现卡顿现象。远程连接客户的电脑,只有一点击级联选择的input就会出现卡顿
@YihaoCCC @sanfenredu cascader的级联元素是点击后才加载的,所以监听change方法不怎么管用。可以参考我的方法
@zeelq 您好,能说下具体实现细节吗?我尝试把"el-cascader-node": false 置为false发现有样式问题以及change事件总是选到最后一个! 更改图片:
我是参考了 @luomu172 提供的解决思路,通过操作dom方式解决的,没更改组件源码,你可以参考下:
const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns"))
在Cascader组件的.el-cascader-node 元素生成后移除aria-owns属性。我参考了上述方法,可以在main.js 文件直接监听 dom 处理。所有组件都生效,可以不用再去组件中处理了。 如果怕污染全局变量,可以包裹在一个函数中执行。
var observer = new MutationObserver(function (mutations, observer) { mutations.forEach(function (mutation) { mutation.addedNodes.forEach(node => { if (node.nodeType === 1) { const $el = node.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute('aria-owns')) } }) }) }) observer.observe(document.body, { characterData: false, childList: true, attributes: false, subtree: true })
目前发现Mac系统的Chrome必现,win的还好,但是CPU确实飙高。 飙高的情况再我的笔记本上必现,由于组件开启了搜索过滤,直接点击右侧下拉有几率不stuck,只要点击搜索部分必然stuck,CPU1 100% 临时解决方案
@visible-change="e => cascaderVisable(e, item)" cascaderVisable (e, item) { // 根据ElementUI的BUG提示 https://github.com/ElemeFE/element/issues/22060 const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]') Array.from($el).map(item => item.removeAttribute('aria-owns')) if (item.visible !== undefined && item.visibleChange) { item.visibleChange(e) } },
环境
chrome:版本 109.0.5414.119(正式版本) (arm64) 系统:
再给大家提供一种自己项目的修复思路,由于使用的地方实在太多了,所以在项目中换了一种方案
- 重新定义一个组件
ElCascaderFixed.vue
<script>
import {
Cascader
} from 'element-ui'
import elfix from '@/components/global/el-cascader-fixer'
export default {
extends: Cascader,
name: 'ElCascader',
mounted () {
this.$on('visible-change', elfix)
}
}
</script>
<style lang="less">
.el-scrollbar {
overflow: hidden;
position: relative;
}
</style>
- 在组件引用的时候替换成这个新的组件
// 去掉原来的element-ui中的Cascader引用
import {
...
// Cascader,
...
} from 'element-ui'
import Cascader from '@/components/global/ElCascaderFixed'
Vue.use(Cascader)
PS:补充一下
.el-scrollbar
这个样式在组件集成之后被未被展示,应该是样式隔离的问题,可以自己在补全下,否则会出现滚动条
目前发现Mac系统的Chrome必现,win的还好,但是CPU确实飙高。 飙高的情况再我的笔记本上必现,由于组件开启了搜索过滤,直接点击右侧下拉有几率不stuck,只要点击搜索部分必然stuck,CPU1 100% 临时解决方案
@visible-change="e => cascaderVisable(e, item)" cascaderVisable (e, item) { // 根据ElementUI的BUG提示 https://github.com/ElemeFE/element/issues/22060 const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]') Array.from($el).map(item => item.removeAttribute('aria-owns')) if (item.visible !== undefined && item.visibleChange) { item.visibleChange(e) } },
环境
chrome:版本 109.0.5414.119(正式版本) (arm64) 系统:
再给大家提供一种自己项目的修复思路,由于使用的地方实在太多了,所以在项目中换了一种方案
- 重新定义一个组件
ElCascaderFixed.vue
<script> import { Cascader } from 'element-ui' import elfix from '@/components/global/el-cascader-fixer' export default { extends: Cascader, name: 'ElCascader', mounted () { this.$on('visible-change', elfix) } } </script> <style lang="less"> .el-scrollbar { overflow: hidden; position: relative; } </style>
- 在组件引用的时候替换成这个新的组件
// 去掉原来的element-ui中的Cascader引用 import { ... // Cascader, ... } from 'element-ui' import Cascader from '@/components/global/ElCascaderFixed' Vue.use(Cascader)
PS:补充一下
.el-scrollbar
这个样式在组件集成之后被未被展示,应该是样式隔离的问题,可以自己在补全下,否则会出现滚动条
请问import elfix from '@/components/global/el-cascader-fixer'的el-cascader-fixer内容是什么?
就是ElCascaderFixed.vue
这个,写在reply里了
好的,我尝试一下;谢谢。@zeelq
在Cascader组件的.el-cascader-node 元素生成后移除aria-owns属性。 请问如何知道.el-cascader-node生成了? 我遇到的一个情况为只有个别人点击级联选择器就会导致页面崩溃,但是其他人使用起来正常,想请教下 const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns")); 这两行代码在什么情况下运行?我不知道在什么样的情况下使用这个方法,换句话说,这个应该需要一个函数触发吧,就像@click函数这样触发,能写个demo吗 ———————————— 另一个issue上给我的回答是在mounted上运行,但是我的理解是此时级联选择器子节点还没有出现,应该拿不到el-cascader-panel .el-cascader-node这个节点吧
这是他的代码 mounted () { const $el = document.querySelectorAll('.el-cascader-panel .el-cascader-node[aria-owns]'); Array.from($el).map(item => item.removeAttribute("aria-owns")); };
我在mounted中打印console.log($el)是这样的结果
使用的vue版本是3.1.2 element-plus版本是1.0.2-beta.52
有2个时机可以触发这段代码:①watch options属性有值时;②组件的@expand-change事件触发时。 记得放到nextTick内执行,保证运行的时候.el-cascader-node节点已经生成了。
Chrome 105.0.5195.54
Element 2.13.0
仍存在此bug 笔记本稳定触发
借用楼上 @RandyZ 的代码 直接放在一个cascaderFix.vue
文件里了 应该可以直接cv去用了
@/components/cascaderFix.vue
<script>
import { Cascader } from "element-ui";
function cascaderVisable(e, item) {
const $el = document.querySelectorAll(
".el-cascader-panel .el-cascader-node[aria-owns]"
);
Array.from($el).map((item) => item.removeAttribute("aria-owns"));
if (item && item.visible !== undefined && item.visibleChange) {
item.visibleChange(e);
}
}
export default {
extends: Cascader,
name: "CascaderFix",
mounted() {
this.$on("visible-change", cascaderVisable);
},
};
</script>
<style lang="less">
.el-scrollbar {
overflow: hidden;
position: relative;
}
</style>
用法
import CascaderFix from "@/components/cascaderFix.vue";
//省略
components: {
CascaderFix,
}