vue2.0滚动条防抖节流单元测试。

海星吧 2020-12-22 5500

好家伙,我特么直接好家伙,技术讨论区都被干掉了。那我就只能来茶馆了。

最近都在工作ing,业务代码写不完。

测试防抖节流的时候用在了scroll事件上,发现了一些问题。

1、无法正常的被销毁。

2、节流无法正常工作。

3、this指向问题,不是vue的实例。而且在scroll的事件上传参就只会执行一次很是蛋疼。

花了个把小时思考,整理了一下节流的工作,防抖同理可以这样写。


throttle:节流

在一个时间段内只会执行一次。

你跳绳一分钟只能跳一下。


debounce:防抖

在一个时间段内,只会执行最后一次。

你call女朋友电话,无论call多少次,她都只会接你最后一次call。


要是还不理解我也没办法了。

下面是代码。

<template>
	<div class="index"></div>
</template>
<script>
/*
    为了方便观看,这俩函数直接丢到script标签里好了。
*/
function throttle(fn, delay = 100) {
    var timer = null;
    return function () {
        if (timer) return;
        timer = setTimeout(() => {
            fn.apply(this, arguments);
            timer = null
        }, delay)
    }
}
function debounce(fn, delay = 100) {
    var timer = null;
    return function () {
        if (timer) clearTimeout(timer)
        timer = setTimeout(() => {
            fn.apply(this, arguments);
            timer = null
        }, delay)
    }
}
let a = 0;
export default {
    data() {
        return {
            value:123,
            scrollFunc:null,//在data中保存一个实例
        };
    },
    mounted() {
        this.scrollFunc = ()=>{
            this.better_scroll(this)//这里给真正要用到的函数附上this来使用vue的实例
        }
        window.addEventListener('scroll',this.scrollFunc)
    },
    updated() {
        window.removeEventListener('scroll',this.scrollFunc)
    },
    beforeDestroy() {
        window.removeEventListener('scroll',this.scrollFunc)
    },
    methods: {
        /*
            触发了滚动事件 1 124
            触发了滚动事件 2 125 -->这里跳到另一个路由,updated销毁了当前组件的滚动事件。
            触发了滚动事件 3 124 -->跳回来之后发现,当前组件的value值重置了,而在script标签中定义的a还是之前的。
            触发了滚动事件 4 125
            
            由此可见,函数可以正常工作。
        */
        better_scroll:throttle((that) => {
            a++;
            that.value++;
            console.log('触发了滚动事件',a,that.value)
        }, 1000),
        /*
        better_scroll:debounce((that) => {
 			a++;
 			that.value++;
 			console.log('触发了滚动事件',a,that.value)
 		}, 1000)
 		*/
    }
};
</script>
<style scoped="scoped">
.index {
    height: 300vh;
    width: 100vw;
}
</style>




既然各位这么想要H情节,那我就用H情节来解释一下吧。


throttle:节流

你在撸铁,一秒钟上下一次。

但是不能一秒钟一次以上。

限制了你撸铁的速度,跟听音声被小姐姐蛇精管理一样。


debounce:防抖

你还是在撸铁,但是无论你撸多少次都只会在你最后一次放手的时候蛇精。

只要你还在撸就不会蛇精。就像磕了威哥一样。


我这样说你们懂了吗?

如果这样还不懂那我就要把你们的包皮扯到你们脖子上勒死你们这群老色批


最后于 2020-12-29 被海星吧编辑 ,原因:
弱鸡程序员年底还在加班
最新回复 (5)
  • 海星吧 2020-12-22
    0 2
    联盟X 辛苦了
    这不辛苦。。对你有用的话尽管拿去用。
    弱鸡程序员年底还在加班
  • 海星吧 2020-12-29
    0 3
    云云 这是花了多长时间写的这么多对我来说完全没有用的或许你轻轻松松就写出来的废话呢?具体作用可以说明一下么?也许对我有用
    你觉得防抖节流的作用是什么呢?
    弱鸡程序员年底还在加班
  • 海星吧 2020-12-29
    0 4
    讲道理这只是我测试用的,之后要写东西就搬一下,修修改改。
    具体业务还得看需求嘛。
    弱鸡程序员年底还在加班
  • 海星吧 2020-12-29
    0 5
    云云 这是花了多长时间写的这么多对我来说完全没有用的或许你轻轻松松就写出来的废话呢?具体作用可以说明一下么?也许对我有用
    防抖节流最常见的用处还是我这篇文章里面写的滚动条事件。
    滚动条事件触发是很频繁的,用这样的方法是为了减少浏览器的消耗,不至于卡顿。
    当然现在的浏览器性能大多都很不错,不过为了代码能更好的使用,还是多思考一下比较好。
    弱鸡程序员年底还在加班
  • 海星吧 2020-12-29
    0 6
    这个是我昨天做的返回顶部插件,其实也就是这样的使用防抖节流。
    在滚动条到300px的时候就显示,没到就隐藏。
    如果不做防抖节流你可以打印一下日志,滚动条往下拉,看看这个事件触发的到底有多频繁。
    而使用throttle函数控制可以达到很好的效果。

    <template>
           <div v-show="back" class="Backtop" @click="backTop()"><img src="@/assets/image/detail/Backtop.png" alt="图片加载失败" /></div>
    </template>
    <script>
    function throttle(fn, delay = 1000) {
           var timer = null;
           return function() {
                   if (timer) return;
                   timer = setTimeout(() => {
                           fn.apply(this, arguments);
                           timer = null;
                   }, delay);
           };
    }
    export default {
           data() {
                   return {
                           back:false,
                           scrollFunc: ()=>{}
                   };
           },
           props:{
                   top:{
                           type:Number,
                           default:300
                   },
                   delay:{
                           type:Number,
                           default:200
                   }
           },
           mounted() {
                   let that = this;
                   this.scrollFunc = throttle(() => {
                           let scrollTop = that.getScrollTop() //这里给真正要用到的函数附上this来使用vue的实例
                           // console.log(scrollTop)
                           that.back = scrollTop>=that.top?true:false;
                   }, that.delay)
                   window.addEventListener('scroll', this.scrollFunc);
           },
           beforeDestroy() {
                   window.removeEventListener('scroll', this.scrollFunc);
           },
           methods: {
                   backTop() {
                           scrollTo(0,0)
                   },
                   getScrollTop() {
                           return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
                   }
           }
    };
    </script>
    <style lang="scss" scoped="scoped">
    .Backtop {
           position: fixed;
           right: 24px;
           bottom: 60px;
           img {
                   height: 120px;
                   cursor: pointer;
           }
    }
    </style>
    弱鸡程序员年底还在加班
    • ACG里世界
      7
          
返回
发新帖