日报列表滚动到哪里、哪里就自动变成已读状态

背景

有一个日报的列表,领导要查看,假如列表是个很长的滚动区域,领导的鼠标滚动到哪里、哪里就自动设置为已读状态,这个该怎么实现呢?

思路

关键点在于监听页面的滚动事件,即某一个日报的区域、是否完全显示在可视区域内。那么要分为以下两种情况:

  • 1.列表有滚动:列表数据多、有滚动条了,这时又要分为两种情况
    • 1.1 滚动区域之内的数据:默认有些数据是完全显示在屏幕内的,需要设置为已读
    • 1.2 滚动区域之外的数据:有些数据不显示在屏幕内,需要滚动后才能看到,滚动到完全显示了自动设置为已读
  • 2.列表无滚动:初始时,数据不多,不产生滚动条

实现过程

说明

本文以vue2 + element-ui为例

过程

先写一个固定高度的div,超出高度后滚动的样式

javascript 复制代码
<div class="content-right" ref="scrollRef">
</div>

.content-right {
  width: 100%;
  height: calc(100vh - 290px); // 或者写固定高度
  overflow-y: auto;
}

本项目以逻辑引导为主,所以样式代码暂时不贴出来了,只把关键的js代码贴出来,详见注释:

javascript 复制代码
<script>

import { debounce } from "@/utils";
import { listWorkReport, workReportSetRead } from '@/api/bigEvent'

export default {
  data() {
    return {
      reportList: [], // 报告列表
      loading: false,
    }
  },
  mounted() {
    this.getList()
  },
  methods: {
    /**
     * 是否添加滚动监听
     * 1.先判断是否有滚动;
     * 2.如果没有滚动,直接列表内容设置为已读状态
     * 3.如果有滚动,添加滚动监听
     *    3.1  把未读假设为已读状态
     *    3.2  把可视区域内的内容设置为已读状态
     */
    isAddScrollListen() {
      const parentHeight =  this.$refs.scrollRef.offsetHeight; // 父级(固定高度的部分)
      const sonHeight =  this.$refs.sonRef.offsetHeight; // 子级 (可滚动区域的列表)
      // 子级高度大于父级高度,说明有滚动条,添加滚动监听
      if(sonHeight > parentHeight) {
        // 添加滚动监听(滚动时触发的事件)
        this.$refs.scrollRef.addEventListener('scroll', this.handleScroll);
        // 默认把可视区域内的内容自动设置为已读状态
        this.$nextTick(() => {
          this.boxScroll()
        })
      } else {
        // 否则,直接设置为已读状态
        setTimeout(() => {
          for(let i = 0; i < this.reportList.length; i++) {
            this.reportList[i].status = 1
            workReportSetRead({
              id: this.reportList[i].id
            }).then(res => {})
          }
        }, 1000)
      }
    },

    // 监听滚动
    handleScroll: debounce(function() {
      this.$nextTick(() => {
        this.boxScroll()
      })
    }, 400),

    // 获取列表
    getList() {
      this.loading = true
      listWorkReport().then(res => {
        this.reportList = res.rows
        this.loading = false
        // 列表有值时添加监听事件
        if(res.rows.length > 0) {
          this.$nextTick(() => {
            this.isAddScrollListen()
          })
        }
      })
    },

    // 监听滚动,出现滑块的情况
    boxScroll() {
      const items = this.$refs.ctxRef || []; // ctxRef:滚动列表里的每一项,监听底部完全显示时标记为已读
      Array.from(items).forEach((item, index) => {
        // 只考虑未读状态,把未读状态标记为已读状态,
        const itemData = this.reportList[index]
        if(itemData.status == 0) {
          const rect = item.getBoundingClientRect();
          // 计算某项在可视区域的top值 + 该项的高度 < 窗口可视区域的高度 - 56
          // 此处根据具体需要修改值
          if(rect.top + rect.height < window.innerHeight - 56) {
            workReportSetRead({
              id: itemData.id
            }).then(res => {
              console.log(`第${index + 1}条已读`)
            })
          }
        }
      });
    },
  }
}
</script>
相关推荐
崔庆才丨静觅17 分钟前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60611 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了1 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅1 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅2 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅2 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment2 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼2 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax