vue監(jiān)聽頁面中的某個div的滾動事件并判斷滾動的位置
在開發(fā)中常常會遇到這樣一個vue頁面,頁面分為左右兩部分,左邊是目錄樹,右邊是一個類名為xq-box的div,在xq-box中多個div上下并列布局,每個div中的內(nèi)容就對應著左邊目錄樹中的相應節(jié)點,現(xiàn)在的目標是,要監(jiān)聽這個xq-box滾動事件,右邊一旦開始滾動,就要知道滾動到哪個子div,并讓左邊的目錄樹中對應的節(jié)點高亮顯示。要怎么做呢?
1、首先,先寫好大概的頁面布局,這里要注意,右邊xq-box的子div要綁定"'xqItem'+序號"的id,為了下面用js能獲取到匹配的dom元素:
<template> <div class="container"> <div class="left-box"> <div class="menu-box"> <div class="menu-title"> <p>目錄</p> </div> <div class="menu-item" v-for="(menu, index) in menuList" :key="index" :class="{ 'active': menuActive === index }" @click="chooseMenu(menu.name, index)" > <img :src="menu.icon" class="menu-icon" /> <p>{{ menu.name }}</p> </div> </div> </div> <div class="right-box"> <div class="xq-box" ref="xqBox"> <div class="xq-item" :id="'xqItem' + index" v-for="(item, index) in xqConList" :key="index" > <!--這里渲染出目錄內(nèi)容--> <div class="xq-item-name"> {{ item.name }} </div> <div class="xq-item-con"> {{ item.content }} </div> </div> </div> </div> </div> </template>
2、然后,在css里給xq-box高度,設置其超出能滾動:
<style lang="stylus" scoped> .right-box height 600px .xq-box height 100% overflow-y auto <style>
3、接著,在計算屬性獲取到這個ref="xqBox"的dom元素,寫一個函數(shù)handleScroll()獲取滾動距離并判斷滾動到哪兩個子div之間,并在頁面渲染完后監(jiān)聽這個xq-box的滾動事件。
export default { name: "menuList", data() { return { menuActive: 0, //左側高亮的item menuList: [], //左側目錄樹 xqConList: [] //右側目錄內(nèi)容列表 } }, computed: { xqBox() { return this.$refs.xqBox; } }, mounted() { this.$nextTick(() => { // //監(jiān)聽這個dom的scroll事件 // this.xqBox.onscroll = () => { // console.log("on scroll"); // this.handleScroll(); // }; //監(jiān)聽這個dom的scroll事件 this.xqBox.addEventListener("scroll", this.handleScroll); }); }, methods: { handleScroll() { //獲取dom滾動距離 const scrollTop = this.xqBox.scrollTop; //獲取可視區(qū)高度 const offsetHeight = this.xqBox.offsetHeight; //獲取滾動條總高度 const scrollHeight = this.xqBox.scrollHeight; //xqConList 為目錄內(nèi)容列表 for (let i = 0; i < this.xqConList.length - 1; i++) { //offsetTop: 獲取當前元素到其定位父級(offsetParent)的頂部距離 let offset_before = this.$el.querySelector("#xqItem" + i).offsetTop; let offset_after = this.$el.querySelector("#xqItem" + (i + 1)) .offsetTop; //根據(jù)xqItem離頂部距離判斷滾動距離落在哪兩個item之間 if (scrollTop >= offset_before && scrollTop < offset_after) { // console.log("offset", offset_before, offset_after, scrollTop); // console.log("scrollHeight", scrollTop, offsetHeight, scrollHeight); //判斷是否滾動到了底部 if (scrollTop + offsetHeight >= scrollHeight) { // 把距離頂部的距離加上可視區(qū)域的高度 等于或者大于滾動條的總高度就是到達底部 // console.log("已滾動到底部"); if (this.menuActive < i) { this.menuActive = i; } } else { this.menuActive = i; } break; } } }, } };
經(jīng)查詢得知,Vue組件在patch階段結束時會把this.$el賦值為掛載的根dom元素,我們可以直接使用$el的querySelector, querySelectorAll等方法獲取匹配的元素。因1中每個內(nèi)容塊子div已經(jīng)綁定id,所以此處可以用 this.$el.querySelector("#xqItem" + i) 獲取到每個子div。
還有一個要注意的是,這里之所以要判斷是否滾動到了底部,是因為xq-box一旦滾動到底部,就可以看到最后幾個目錄對應的子div,此時的滾動距離scrollTop只會落在這最后幾個子div的第一個子div(序號即當前本次循環(huán)中的i)的離頂部距離位置上,這個時候如果左側目錄樹高亮的正好是這最后幾個目錄的其中任意一個,則無需更改高亮;但是如果此時 this.menuActive 的值還比最后幾個子div中的第一個的序號要小,即比本次循環(huán)的 i 要小,則需要更改為當前的 i 值。
4、如果要點擊左邊目錄樹,右邊xq-box也要自動滾動到相應的目錄內(nèi)容,則要增加以下方法:
chooseMenu(name, index) { this.menuActive = index; // //可以用scrollIntoView // document.querySelector("#xqItem" + index).scrollIntoView({ // block: "start", // behavior: "smooth" // }); let offsetTop = this.$el.querySelector("#xqItem" + index).offsetTop; console.log("#xqItem" + index + " offsetTop: " + offsetTop); this.xqBox.scrollTop = this.$el.querySelector( "#xqItem" + index ).offsetTop; },
這樣,“監(jiān)聽這個xq-box滾動事件,右邊一旦開始滾動,就要知道滾動到哪個子div,并讓左邊的目錄樹中對應的節(jié)點高亮顯示”這個功能便實現(xiàn)了。
到此這篇關于vue監(jiān)聽頁面中的某個div的滾動事件并判斷滾動的位置的文章就介紹到這了,更多相關vue監(jiān)聽div滾動事件 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解從零搭建 vue2 vue-router2 webpack3 工程
本篇文章主要介紹了詳解從零搭建 vue2 vue-router2 webpack3 工程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11Vue中實現(xiàn)v-for循環(huán)遍歷圖片的方法
這篇文章主要介紹了Vue中實現(xiàn)v-for循環(huán)遍歷圖片的方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08