vue3 组合式api监听元素滚动,去除滚动底部多次触发滚动事件副作用,以及在当前组件对浏览器进行滚动监听时,根据组件的挂载卸载,keep-alive组件的活跃和不活跃的状态,进行添加监听和移除监听

2023-11-05

import { onActivated, onDeactivated, onMounted, onUnmounted } from "vue";
import { throttle } from "underscore";
const scrollstate = {
  state: true,
  _state: true,
};

const handlefn = (fn, timeout = 1000, throttleTimeout = 200) => {
  Object.defineProperty(scrollstate, "state", {
    set: function (newVal) {
      if (newVal === false) {
        this._state = newVal;

        setTimeout(() => {
          this._state = true;
        }, timeout);
      } else {
        this.state = false;
        console.error(
          '如果你想阻止滚轮事件重复触发,请设置state为false(为了防止副作用,state已设置为false),"scrollstate.state"不被允许设置除false以外的其他值'
        );
      }
    },
    get: function () {
      return this._state;
    },
  });
  if (scrollstate.state) {   
    const stateboolean = fn(scrollstate);   
    if(stateboolean === false){
      scrollstate.state = stateboolean
    }else if(stateboolean){
      scrollstate.state = false
      console.error(
      '事件函数返回值被当做阻止时间重复触发的状态,只能返回false,为防止副作用,已默认将状态设置为 
       false,请及时修改代码'
      )
    }
  }
};
export function addScrollListener(fn, element = window, throttleTimeout = 200) {
  const temFn = throttle(() => handlefn(fn), throttleTimeout); 
  function ifwindow() {
    onActivated(() => {
      element.addEventListener("scroll", temFn);
    });
    onDeactivated(() => {
      element.removeEventListener("scroll", temFn);
    });

    onUnmounted(() => {
      element.removeEventListener("scroll", temFn);
    });
    onMounted(() => {
      element.addEventListener("scroll", temFn);
    });
  }
  if(element === window){
    ifwindow()
  }else{
    onMounted(() => {
    element.value.addEventListener("scroll", temFn);
  });
  }
}

以上是工具源代码,工具依赖于underscore进行节流处理,请以下命令进行下载

npm i underscore   

使用教程

// 1.通过此文件导出addScorllListener函数
import { addScrollListener } from './hooks/addScrollListener';





//2 函数传入四个参数
//2.1   第一个参数为滚动事件触发的函数,
//2.2   第二个为监听哪一个元素的滚动事件
//      如果不传默认设置为浏览器,并且在挂载组件或keep-alive时进入组件的时候添加监听,
//      卸载组件或keep-alive时离开组件的时间移除监听,防止影响其他组件正常功能
//2.3   第三个参数为节流间隔时间,默认为200毫秒
//2.4   第四个参数后面说
addScrollListener(fn,element,throttleTimeout,statetimeout)



//3  传入的第一个参数函数,也会接受一个参数,此参数为此工具状态
//   工具内部会时刻监听state值的变化,当state值变成false时,监听事件停止触发,并开启一个定时器
//   定时器结束时,才能将state状态改回为true,然后继续监听
//   addScrollListinner函数的第四个参数就是这个定时器的倒计时时间,默认为 1s
//   改变状态的方法有两种,如下面代码
const fn = (state)=>{
  //3.1 可以直接通过参数修改
  state = false
  //3.2  也可以通过return false 可以改变state为false
  return  false
}

//注意!!!!    在你认为会重复触发监听器时间的位置上将state改为false
//               比如监听到滚动到底部时,完成该事件,并将状态改为false,防止重复触发

//注意!!!!    不可以将state改为除false以外的任何值,会报错,报错的同时会将state修改为false,并开启定时器

//注意!!!!    使用ref对象传递dom时,请主要要传递ref对象,而不是ref.value
//               具体原因可以看我的另一篇文章《ref详解》

我的另一篇文章----ref详解

如果第一次网络请求成功之前,无列表数据,导致无法撑起浏览器窗口,会造成开始时就在浏览器底部,滚动事件会直接触发一次,解决方法可以通过settimeout,或者判断列表数据中是否有值等方式,延缓此函数执行(延缓添加监听)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3 组合式api监听元素滚动,去除滚动底部多次触发滚动事件副作用,以及在当前组件对浏览器进行滚动监听时,根据组件的挂载卸载,keep-alive组件的活跃和不活跃的状态,进行添加监听和移除监听 的相关文章

  • GWT - onClick 未触发

    我在表单上有一个非常奇怪的行为 有许多具有内联验证的文本字段 如果内容无效 则会在字段下方显示错误消息 验证在模糊时触发 页面底部有一个 下一步 按钮 单击后 将执行验证 如果一切正常 则提交表单 现在 如果当我单击按钮时强制空白字段具有焦
  • 欺骗或禁用页面可见性 API

    页面可见性 API https developer mozilla org en US docs Web Guide User experience Using the Page Visibility API开始普遍用于在选项卡未处于焦点时
  • 组织 jQuery/JavaScript 代码的最佳方式 (2013) [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 问题 这个答案之前已经回答过 但已经
  • 如何在回调函数之外使用 FB.api(JS SDK) 响应?

    我在登录甚至调用 api 方面没有任何问题 我只是在 api 回调之外获取响应时遇到问题 我知道它是异步运行的 所以我想将它放在一个返回响应的函数中 这是我的想法 What I would like to be able to do fun
  • Jquery:表单验证不起作用

    我对 Jquery 很陌生 希望你们能帮助我解决这个 jquery 验证问题 一直在尝试验证表单 但它根本没有验证 它接受我在字段中输入的任何内容 无论我设置什么限制 请帮忙 谢谢 这是我的代码
  • jQuery 输入焦点不起作用

    我正在尝试在表中创建数据的内联编辑 为此 我将单元格中的文本更改为输入 document ready function td edit on click function this html
  • 如何限制注册用户尝试投票两次[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我对 php 编码和网站设计非常陌生 我正在尝试开发一个在线投票系统 只允许注册用户投票 已完成所有操作并且工作正常 但我需要的帮助是
  • 无法设置未定义的属性“显示”

    我正在编写脚本来隐藏 显示菜单 但遇到了一些麻烦 function displayMenu var classMenu event target className classMenu Menu document getElementsBy
  • 获取顶部框架的 URL

    在 Facebook 应用程序中 我需要检查顶部框架 主窗口 URL 是什么 并相应地显示内容 我尝试使用以下内容 if top location toString toLowerCase indexOf facebook com lt 0
  • 确定是否单击了 Google Chrome 打印预览中的打印/取消按钮

    我一直在使用下面的代码打印我的页面 window print 下图是 Google Chrome 浏览器中的打印预览的样子 它有两个主要按钮 print and cancel 我想知道用户是否点击了print or cancel纽扣 我所做
  • 将图像嵌入 Chrome 扩展程序

    我正在构建一个 Google Chrome 扩展 它将 HTML 注入到真实的网页中 注入还包含图像 现在我想知道如何在扩展中引用图像 到目前为止 我只能在服务器上使用它们来引用它们http example com myimage png
  • 如何检查 Node.js 中是否定义了变量?

    我正在用node js 编写一个程序 它实际上是js 我有一个变量 var query azure TableQuery 看起来这行代码有时没有执行 我的问题是 我怎样才能做到这样的条件 if this variable is define
  • 在 Angularjs 中格式化输入值

    我正在尝试编写一个指令 自动格式化数字
  • fs.statSync 与缓冲区“错误:路径必须是没有空字节的字符串”

    我已经读入这样的文件缓冲区 let imageBuffer try imageBuffer fs readFileSync some path to image jpg catch e console log error reading i
  • 保持 WebSocket 连接处于活动状态

    我正在研究 WebSocket 协议 并尝试在后端使用 Python 实现一个简单的 ECHO 服务 它似乎工作正常 但连接建立后立即断开 这是我的客户
  • 使用 JS 从列表中删除最近的 元素的 URL

    所以我有一个网址列表 并且有删除按钮 图像按钮 当点击删除按钮时 按钮旁边的 url 必须从列表中删除 let list const remove document getElementById remove const view docu
  • Highcharts 异步服务器加载多个系列

    我正在尝试按照其示例使用 Highcharts 的延迟加载 http www highcharts com stock demo lazy loading http www highcharts com stock demo lazy lo
  • 为车把/余烬定义模板内的数组?

    我在 ember 应用程序中有一个车把模板 它接受一个数组 我目前像这样声明数组 模板 Gd radio input content radioContent value blue JavaScript App IndexControlle
  • CSS3 Marquee / Ticker 动画最后没有空格

    我正在用 2 个项目集合构建字幕 旋转木马效果 循环两者item collection跨越translateX并不难 这里是小提琴 http jsfiddle net k1k3h2p0 但我不喜欢每个循环末尾的空白区域 知道两个集合的宽度可
  • 按 Chartjs 条形图的键对对象进行分组

    我正在尝试使用 Chart js 创建条形图 我在尝试根据每个用户的状态创建分组条形图时陷入困境 这是数据 statusId 0 firstName Joe status appealed count 1 statusId 0 firstN

随机推荐