這裡記錄工作中遇到的技術點,以及自己對生活的一些思考,周三或周五釋出。
封面圖

背景
業務代碼的開發過程中,我們有時候會遇到一些很小,但是很精緻的需求。
标題中描述的場景适用于表單内容項很多,比如幾十或者上百條的時候,需要我們滾動表單内容才能找到我們要想要修改的表單項。
也有可能是表格一次展示了百十條資料,需要前端搜尋某一項,滾動該項到可視區域内。
大緻的圖形描述如下:
比如上圖中
dog
超出了在可視區域的下方,則需要填寫該資料時,在頁面上進行搜尋,讓
dog
顯示到可視容器内。
技術分析
元素滾動
滾動到指定位置,必然要用到
ELEMENT.scrollTop
或者
ELEMENT.scrollTo(X,Y)
。
鑒于我們這裡隻需要進行上下滾動,是以選中
element.scrollTop
屬性進行設定即可。
需要注意的是
:
scrollTop
屬性隻能設定在本身包含滾動條的元素上,否則不起作用。因為包含滾動條的容器,含有
overflow:scroll
或者
overflow:auto
屬性。
比如有如下代碼:
<div class="scroll-wrapper">
<div class="scroll-content">
<div class="scroll-inner">
<div class="test-area"></div>
</div>
</div>
</div>
<style>.scroll-wrapper{
width:400px;
height:500px;
overflow:hidden;
}
.scroll-content{
width:100%;
height:500px;
overflow:auto;
}
.scroll-inner{
width:100%;
height:1000px;
}
</style>
則設定
scrollTop
屬性時,需要設定在class名為
scroll-content
的dom元素上。設定在
scroll-inner
上,則不起作用。
vue3選中真實dom
選中真實dom有兩種方式。
一種是用原生JS,
document.getElemtById()
或者
document.getElmentByClassName()
以及
document.getElementByTagName()
。
另外外一種是用vue3的
ref
屬性。需要結合
getCurrentInstance()
方法使用。
getCurrentInstance()
用來擷取目前的元件執行個體。
需要注意的是:
getCurrentInstance()
隻能在 setup 或生命周期鈎子中調用。
計算位置
位置計算需要我們擷取滾動容器的位置資訊,以及我們查詢到的元素的位置資訊,分不同的情況進行計算。
情況一,查詢元素位于滾動容器之下:
這時候需要滾動容器向上滾動,滾動的距離計算方式大緻是:
let {height} = scrollContent.getBoundingClientRect()
const
getBoundingClientRect()
用來擷取元素的大小及其相對于視口的位置。
情況二,查詢元素位于滾動容器之上:
這時候需要滾動容器向下滾動,滾動的距離計算方式大緻是:
// 目前滾動容器的scrollTop - 查詢元素超出容器的高度
let currentScrollTop = scrollContent.scrollTop
const
距離的計算,可以根據具體的需要進行合适的計算即可。
其他需要注意的問題
因為我們在進行業務開發時,經常使用第三方UI元件庫。當我們用
ref
直接設定到元件庫中的元件時,比如
Button
,ref擷取到的其實是這個元件對象,并非直接擷取到真實的DOM元素。
是以,在綁定時,需要我們在外面多加一層
div
,用來擷取真實的DOM。然後通過執行個體的
refs
屬性,比對到我們查詢的
key
即可。
import {getCurrentInstance} from 'vue
const instance = getCurrentInstance()
const searchAction = (searchVal) => {
let searchDom = instance.refs[`${searchVal}`]
let scrollContent= instance.refs.scrollContent
let currentScrollTop = scrollContent.scrollTop
const searchDomDistanceInfo = searchDom.getBoundingClientRect()
const scrollContenDistanceInfo = scrollContent.getBoundingClientRect()
if(頂部超出){
// 計算距離 設定scrollContent.scrollTop屬性
}else if(底部超出){
// 計算距離 設定scrollContent.scrollTop屬性
}
...
}