javascript – 如何在显示的DOM元素之前使focus()工作
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript – 如何在显示的DOM元素之前使focus()工作,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2939字,纯文字阅读大概需要5分钟。
内容图文
更新:事实证明在DOM渲染完成之前无法直接将焦点应用于文本框
我想知道为什么focus()函数不能对隐藏元素起作用.
例如(我正在使用Vue.js):
var vm = new Vue({
el: "#app",
data:{
showtext: false
},
methods: {
showTxt(ev){
this.showtext = true
var vm = this;
// if I uncomment setTimeout, then the textbox can set focus
//setTimeout(function(){
vm.$refs.textbox.focus()
//}, 0)
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<button @click="showTxt">
Show Textbox and SetFocus on it
</button>
<div v-show="showtext">
<input ref="textbox" type="text" />
</div>
</div>
我想要做的是单击该按钮并显示文本框并将焦点放在文本框中,但是目前,如果我直接调用.focus(),则文本框无法获得焦点.它只适用于我在它周围包装一个setTimeout(我想在下一个事件循环上运行).我想知道是否有任何方法可以让焦点在没有setTimeout的情况下工作?
谢谢
解决方法:
最好使用vm.$nextTick或Vue.nextTick(我们不需要关心nextTick甚至实际使用setTimeout,Vue会保证nextTick会完成它的工作,即使将来nextTick可能会使用其他方法实现相同的目标).
正如Vue API: nextTick所说,
Defer the callback to be executed after the next DOM update cycle. Use
it immediately after you’ve changed some data to wait for the DOM
update.
你也可以查看Vue Guide: Async Update Queue
对于您的情况,当单击按钮以显示输入时,它将执行this.showtext = true,然后执行element.focus.但实际上Dom元素仍然是不可见的(VNode已更改,但Vue没有重新渲染和补丁).
所以你必须使用vm.$nextTick或Vue.nextTick在Vue重新渲染输出后执行.focus.
查看下面的演示:
Vue.config.productionTip = false
var vm = new Vue({
el: "#app",
data:{
showtext: false
},
methods: {
showTxt(ev){
this.showtext = true
var vm = this;
console.log('Current:', this.$el.innerHTML)
this.$nextTick(()=>{
vm.$refs.textbox.focus()
console.log('Nexttick:', this.$el.innerHTML)
})
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<button @click="showTxt">
Show Textbox and SetFocus on it
</button>
<div v-show="showtext">
<input ref="textbox" type="text" />
</div>
</div>
为什么setTimeout有效:
因为setTimeout(,0)将一个任务添加到任务队列.但它将在下一个事件循环中执行,但渲染将在当前事件循环中执行微任务后执行.
检查HTML SPEC: event loop processing model (请查看步骤7),在当前任务(包括this.showtext为true,数据反应性触发重新渲染)已经执行后(它将从任务队列中删除),系统将在弹出一个任务之前先渲染(如果setTimeout(,0)task是队列中最早的任务,则可能是setTimeout(,0).
但是Promise是微任务,它不会起作用,因为它会在渲染之前执行(请看上面的事件循环处理模型:步骤6).
Vue.config.productionTip = false
var vm = new Vue({
el: "#app",
data:{
showtext: false
},
methods: {
showTxt(ev){
this.showtext = true
var vm = this;
new Promise((resolve, reject)=>{
vm.$refs.textbox.focus()
resolve()
}).then(()=>{
vm.$refs.textbox.focus()
})
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<button @click="showTxt">
Show Textbox and SetFocus on it
</button>
<div v-show="showtext">
<input ref="textbox" type="text" />
</div>
</div>
或者你可以看看这个Youtube Video,它会比我的描述更好.
内容总结
以上是互联网集市为您收集整理的javascript – 如何在显示的DOM元素之前使focus()工作全部内容,希望文章能够帮你解决javascript – 如何在显示的DOM元素之前使focus()工作所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。