开发时遇到过这样的需求:
用一个textarea
控件录入一段长文本,它的placeholder
需要异步的动态设置。
怪异点在于,在ios移动设备上,如果初始时,文本框的value
和placeholder
都是空字符串。那么当异步设置placeholder
值时会出现设置失效的情况,需要你聚焦一下文本框,placeholder
才会出现。而PC端浏览器无此问题。
下面是可以复现bug的代码,也可以直接访问CodePen - Weirdness of the placeholder in textarea (cdpn.io)来查看
<div id="app">
<textarea :placeholder="placeholder"></textarea>
</div>
const app = new Vue({
el: "#app",
data: {
placeholder: ""
},
mounted() {
setTimeout(() => {
this.placeholder = "ph";
}, 1000);
}
});
经过测试发现,复现此问题还需要一个必要条件就是异步设置的placeholder
字符串足够短,没有超过文本域的高度。如果placeholder
字符串的长度够长的话也不会出现这个bug——比如说你设置一个This is a placeholder.This is a placeholder.This is a placeholder.This is a placeholder.This is a placeholder.This is a placeholder.This is a placeholder.This is a placeholder.This is a placeholder.This is a placeholder.This is a placeholder.
这种超过文本域高度的字符串。
为了再次排除是否是vue的原因,我还尝试用原生js来实现这个过程。结果是bug仍然存在。
<div id="app">
<textarea id="textarea" placeholder=""></textarea>
</div>
setTimeout(() => {
document.querySelector('#app').setAttribute('placeholder', 'ph')
}, 1000)
起初发现这个问题是我在用vant开发时发现的,以为是vant的bug,还向vant提了一个issue。但其实是原生textarea渲染的一个坑。
为了解决这个问题,可以利用一个hack:将初始的placeholder
值设置成' '
,一个空格字符串,就不会出现这个问题了。