[Textarea] 设置autosize+切换页面后会多出一个textarea
tdesign-vue-next 版本
1.9.7
重现链接
https://github.com/origin-coding/Alacrity
重现步骤
复现步骤
- 下载最新版Alacrity,可以使用Windows的MIS或Exe安装包(手动编译运行需要Rust环境,搭建比较耗时)安装(运行需要至少需要Win10操作系统,这是Tauri的限制,与TDesign无关)。
- 打开Alacrity,选择任意一个带有Textarea的插件(比如文本哈希),然后悬浮在Textarea上。
- 在保持Focus的状态下浏览器后退(这一步可以使用鼠标的左侧按钮,部分鼠标左侧按钮有后退的功能)。
- 此时页面左下角就会有一个额外的
textarea元素。
复现注意事项
- 需要有Hover或者聚焦行为行为,没有的话直接后退不会复现,而且在后退时候需要保持这种状态,因此需要使用。
- 发现问题的元素的
autosize属性需要设置为对象,不设置或者设置为true都不会触发。这一点在文本哈希里面有体现,页面右下角的Textarea在获取聚焦并后退之后不会触发上述问题。
期望结果
页面切换后不再显示这个Textarea,或者设置为display: none之类的属性让它不再显示
实际结果
No response
框架版本
Vue(3.4.31)
浏览器版本
No response
系统版本
No response
Node版本
No response
补充说明
No response
👋 @origin-coding,感谢给 TDesign 提出了 issue。 请根据 issue 模版确保背景信息的完善,我们将调查并尽快回复你。
这个额外的textarea元素是在calcTextareaHeight.ts文件的calcTextareaHeight函数中创建:
if (!hiddenTextarea) {
hiddenTextarea = document.createElement('textarea');
document.body.appendChild(hiddenTextarea);
}
销毁语句如下:
hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea);
hiddenTextarea = null;
而且在autosize属性设置为true或者不设置时没有问题,在textarea.tsx文件中,相关代码在adjustTextareaHeight函数中:
const adjustTextareaHeight = () => {
if (props.autosize === true) {
textareaStyle.value = calcTextareaHeight(refTextareaElem.value); // autosize设置为true时调用只有一个参数
} else if (props.autosize && typeof props.autosize === 'object') {
const { minRows, maxRows } = props.autosize;
textareaStyle.value = calcTextareaHeight(refTextareaElem.value, minRows, maxRows); // autosize设置为对象时调用参数有3个
} else if (attrs.rows) {
textareaStyle.value = { height: 'auto', minHeight: 'auto' };
} else if (attrs.style && refTextareaElem.value?.style?.height) {
textareaStyle.value = { height: refTextareaElem.value.style.height };
}
};
可以回过头,再次查看calcTextareaHeight函数,它的函数签名如下:
function calcTextareaHeight(
targetElement: HTMLTextAreaElement, minRows: RowsType = 1, maxRows: RowsType = null,
)
调用参数只有一个时,minRows不为null,maxRows为null;调用参数有三个时,minRows和maxRows都不为null。 所以问题可能出在这一部分:
if (maxRows !== null) {
let maxHeight = singleRowHeight * maxRows;
if (boxSizing === 'border-box') {
maxHeight = maxHeight + paddingSize + borderSize;
}
height = Math.min(maxHeight, height);
}
不过我并不是特别确定是不是这里的问题,我对于页面样式这部分不太了解。
我在开发环境又尝试了一次,发现了下面的报错:
TDesign Vue Next的文档官网上面也可以复现这个bug,只不过textarea没有显示,元素实际存在,而且也有报错。
可以复现的Textarea元素是基础多文本输入框的第三个Textarea元素,Hover之后按动鼠标后退键仍然能复现。
谢谢反馈和提供思路 我们具体再排查下
我这里在开发环境又试了一次,找到了调用堆栈:
相关代码如下:
const emitBlur = (e: FocusEvent) => {
adjustTextareaHeight();
focused.value = false;
props.onBlur?.(innerValue.value, { e });
formItem?.handleBlur();
};
那么是不是可以在函数执行之前判断一下,如果target不存在的时候就不处理这个事件呢?:
const emitBlur = (e: FocusEvent) => {
if (!e.target) return;
adjustTextareaHeight();
focused.value = false;
props.onBlur?.(innerValue.value, { e });
formItem?.handleBlur();
};