vue监听页面中的某个div的滚动事件并判断滚动的位置

vue监听页面中的某个div的滚动事件并判断滚动的位置

  在开发中常常会遇到这样一个vue页面,页面分为左右两部分,左边是目录树,右边是一个类名为xq-box的div,在xq-box中多个div上下并列布局,每个div中的内容就对应着左边目录树中的相应节点,现在的目标是,要监听这个xq-box滚动事件,右边一旦开始滚动,就要知道滚动到哪个子div,并让左边的目录树中对应的节点高亮显示。要怎么做呢?

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" > <!--这里渲染出目录内容--> <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元素,写一个函数handleScroll()获取滚动距离并判断滚动到哪两个子div之间,并在页面渲染完后监听这个xq-box的滚动事件。

export default { name: "menuList", data() { return { menuActive: 0, //左侧高亮的item menuList: [], //左侧目录树 xqConList: [] //右侧目录内容列表 } }, computed: { xqBox() { return this.$refs.xqBox; } }, mounted() { this.$nextTick(() => { // //监听这个dom的scroll事件 // this.xqBox.onscroll = () => { // console.log("on scroll"); // this.handleScroll(); // }; //监听这个dom的scroll事件 this.xqBox.addEventListener("scroll", this.handleScroll); }); }, methods: { handleScroll() { //获取dom滚动距离 const scrollTop = this.xqBox.scrollTop; //获取可视区高度 const offsetHeight = this.xqBox.offsetHeight; //获取滚动条总高度 const scrollHeight = this.xqBox.scrollHeight; //xqConList 为目录内容列表 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; //根据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) { // 把距离顶部的距离加上可视区域的高度 等于或者大于滚动条的总高度就是到达底部 // console.log("已滚动到底部"); if (this.menuActive < i) { this.menuActive = i; } } else { this.menuActive = i; } break; } } }, } };

       经查询得知,Vue组件在patch阶段结束时会把this.$el赋值为挂载的根dom元素,我们可以直接使用$el的querySelector, querySelectorAll等方法获取匹配的元素。因1中每个内容块子div已经绑定id,所以此处可以用 this.$el.querySelector("#xqItem" + i) 获取到每个子div。

       还有一个要注意的是,这里之所以要判断是否滚动到了底部,是因为xq-box一旦滚动到底部,就可以看到最后几个目录对应的子div,此时的滚动距离scrollTop只会落在这最后几个子div的第一个子div(序号即当前本次循环中的i)的离顶部距离位置上,这个时候如果左侧目录树高亮的正好是这最后几个目录的其中任意一个,则无需更改高亮;但是如果此时 this.menuActive 的值还比最后几个子div中的第一个的序号要小,即比本次循环的 i 要小,则需要更改为当前的 i 值。

4、如果要点击左边目录树,右边xq-box也要自动滚动到相应的目录内容,则要增加以下方法:

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; },

这样,“监听这个xq-box滚动事件,右边一旦开始滚动,就要知道滚动到哪个子div,并让左边的目录树中对应的节点高亮显示”这个功能便实现了。

到此这篇关于vue监听页面中的某个div的滚动事件并判断滚动的位置的文章就介绍到这了,更多相关vue监听div滚动事件 内容请搜索易知道(ezd.cc)以前的文章或继续浏览下面的相关文章希望大家以后多多支持易知道(ezd.cc)!

推荐阅读

    js设置div的边框|怎样给div设置边框

    js设置div的边框|怎样给div设置边框,,1. 怎样给div设置边框1、首先新建一个html文件,输入基本的内容,这里设置一个div,并把它的class设置为de

    确定java按钮响应事件的代码

    确定java按钮响应事件的代码,,* 阅读本文可以结合最后在java登录窗口界面下面是一个链接。 是定义的容器。 容器(CP =得到内容面板); / /

    vue项目一些常见问题

    vue项目一些常见问题,组件,样式,**样式污染问题**同样的样式不需要在每个组件都复制组件内单独的样式加外层class包裹。加scope。否则只是

    90后瓶门事件图片

    90后瓶门事件图片,,现在孩子们还太早,有些女孩子总是在门口等一会儿,最近发生了一次酒瓶门事件。 近日,山东一家寄宿学校的一名女生带着一瓶

    01-Vue项目实战-网易云音乐-准备工作

    01-Vue项目实战-网易云音乐-准备工作,网易,项目,前言在接下来的一段时间,我会仿照网易云音乐,利用Vue开发一个移动端的网易云音乐项目。在做

    01- 第一天 spring boot2.3.1 +vue3.0 后台管理系统的研发

    01- 第一天 spring boot2.3.1 +vue3.0 后台管理系统的研发,自己的,后台,后台框架一直想开发一套完全属于自己的后台,但是18年的时候,曾经答

    Vue项目中 App.vue文件

    Vue项目中 App.vue文件,文件,内容, 在App.vue文件中,定义了一个id为app的div,在这个div板块中放置Helloworld组件,文件内容如下图所示:在

    唐山打人事件视频源自哪里

    唐山打人事件视频源自哪里,华为,视频,唐山打人事件视频源自哪里唐山打人事件视频来源于哪里?为什么这个网友人敢于发出这个视频?不怕被威胁

    div设置阴影|html如何设置阴影

    div设置阴影|html如何设置阴影,,1. html如何设置阴影在HTML中设计水平线的方法如下 1 在网页设计过程中,如果随意利用缺省水平线,常常会出现

    Win7系统怎么打开事件查看器?

    Win7系统怎么打开事件查看器?,查看器,事件, win7系统中有一个事件查看器,事件查看器是重要的系统管理软件,通过它可以了解到某项功能配置、