vue中如何动态获取剩余区域的滚动高度
vue动态获取剩余区域的滚动高度
需求
通过获取屏幕的高度,减去【固定】高度,剩下的高度为【内容】滚动高度。
我们通过下面代码获取屏幕高度:
document.documentElement.clientHeight || document.body.clientHeight;
所谓的固定高度,应该是一直停留在屏幕可见范围中,不根据内容进行滚动。
如果这个固定高度是一些静态资源时,我们只需通过设置 ref 获取元素的高度。
<div class="index-banner-img"> <img :src="bannerImg" ref="imgSize" alt=""> </div>
let imgHeight = this.$refs['imgSize'].height
那么这样就很容易的获取到内容的滚动高度,代码如下:
getScollerHeight() { setTimeout(() => { let clientHeight = document.documentElement.clientHeight || document.body.clientHeight; let imgHeight = this.$refs['imgSize'].height this.scrollHeight = (clientHeight - imgHeight) + 'px' }, 100) } mounted() { this.getScollerHeight() },
vue获取元素高度总是不准确问题
打算用一个websocket写一个简易的聊天系统。
后端代码很容易就写好,但是前端是真的难搞,遇到一个很严重的问题:
当发送一条消息或者是收到一条消息,消息展示界面不能滑到最下面,展示最新消息,于是,经过一段时间的修改,发送新消息时,滚动条虽然能下滑,但是滑不到最底部,于是我添加了一个按钮,使用按钮,将滚动条滑到最底部是可行的。又使用debug调试,发现:vue会先执行你的其它方法,再渲染页面,导致总是只能滑到上一条消息展示的高度。
于是我再百度,发现:重置数据后,获取dom元素高时,dom元素还未渲染完毕,(可能这就是为什么只能滑到上一条消息展示的地方)
解决办法
this.$nextTick()函数 :在下次DOM更新循环结束之后执行延迟回调
this.$nextTick(()=>{ this.goBottom(); // 滚动条滑到底部的方法 })
补充: 使用vue获取一个指定的元素的高度,可以使用vue的ref
当ref加在普通的元素上,使用this.ref.name获取到的是dom元素
下面是聊天的html代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>微聊</title> <script src="../static/js/vue.js"></script> <style> .cheet-box{ width: 592px; height: 160px; } .box{ /*margin: 0 auto;*/ /*overflow:auto;*/ overflow-y: auto; overflow-x: hidden; font-family: "微软雅黑 Light"; width: 600px; height: 300px; background-color: #ecece9; border: none; box-shadow: aliceblue; margin-bottom: 20px; padding: 50px; } .to,.me{ word-wrap:break-word; display: block; width: 50%; padding: 26px; border-radius: 10px; background-color: #fff; margin: 5px 0 10px 0; } .system-log{ padding: 5px 0; color: darkgrey; text-align: center; } .to{ float: left; } .me{ float: right; } </style> </head> <body onbeforeunload="checkLeave()"> <div id="app"> <div class="box" id="box" ref="getHeight"> <div v-for="item in messageArray"> <!-- <div class="system-log">连接成功...</div>--> <div class="to" v-if="item.username != message.username" v-text="item.text"> </div> <div class="me" v-else v-text="item.text"> aaaaaa </div> </div> </div> <div> <input type="text" v-model="message.username"> </div> <div> <textarea type="text" v-model="message.text" class="cheet-box"></textarea> <input @click="sendMessage()" type="button" value="发送"/> <input @click="goBottom()" type="button" value="底部"/> </div> </div> <script> function checkLeave(){ sessionStorage.setItem('key','hello'); localStorage.setItem('2','3') } var websocket ; var vm = new Vue({ el:'#app', created(){ this.initWebSocket(); }, data:{ message:{ username:'', text:'', }, messageArray:[ ], }, methods:{ initWebSocket(){ if (typeof (WebSocket)=="undefined"){ alert('浏览器不支持WebSocket') }else { console.log('浏览器支持websocket') websocket = new WebSocket("ws://localhost:8080/ws/asset"); //连接打开事件 websocket.onopen = function() { console.log("Socket 已打开"); var obj = { text:'', username: '', log:'连接成功!' } websocket.send(JSON.stringify(obj)); }; //收到消息事件 websocket.onmessage = function(msg) { vm.pushArray(msg.data) }; //连接关闭事件 websocket.onclose = function() { console.log("Socket已关闭"); }; //发生了错误事件 websocket.onerror = function() { alert("Socket发生了错误"); } //窗口关闭时,关闭连接 window.unload=function() { websocket.close(); }; } }, sendMessage(){ websocket.send(JSON.stringify(this.message)); this.message.text = '' }, pushArray(msg){ let message = JSON.parse(msg); console.log(message) if (message.username!='' && message.text!=''){ this.messageArray.push(message) this.$nextTick(()=>{ this.goBottom(); }) } }, goBottom(){ let box = document.getElementById('box'); box.getBoundingClientRect().height box.scrollTo(0,box.scrollHeight-box.clientHeight) } } }) </script> </body> </html>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
最新评论