datagridview滚动条自动滚动_掘金上摸鱼的新发现,无限滚动(infinitescroll)

前言

上班摸鱼,下班摸鱼,一直摸一直爽。在一次调试的过程中,我按下了F12刚好是掘金的页面,然后把代码输入到控制台之后,顺手滚动了几下右侧的滚动条,发现个问题如下图所示:

92459a27a1edd3ca89dea1fadaa8c920.gif

‍‍‍‍‍‍‍‍‍‍掘金官网的滚动条当你拖动到底部的时候会自动回弹到一定的位置。顺着这个问题,我想着使用 vue-cli3.0 和 TS 实现以下这个功能。

技术栈

  • vue-cli3.0
  • ts
  • axios

搭建环境

npm install -g @vue/cli
vue create

之后根据提示选择需要的配置项即可

(*) Babel
(*) TypeScript
( ) Progressive Web App (PWA) Support
( ) Router
( ) Vuex
(*) CSS Pre-processors
(*) Linter / Formatter

支持 TS

搭建好环境之后项目会生成shims-vue.d.tsshims-tsx.d.ts两个文件

  • shims-vue.d.ts 默认 ts 不认识 vue
declare module '*.vue' {
import Vue from 'vue'
export default Vue //让ts识别.vue文件
}
  • shims-tsx.d.ts这个声明文件是允许在 vue 项目中写jsx代码,可以使用.tsx结尾的文件,如果在项目中不使用可以直接忽略。
import Vue, { VNode } from 'vue'

declare global {
namespace JSX {
// tslint:disable no-empty-interface
interface Element extends VNode {}
// tslint:disable no-empty-interface
interface ElementClass extends Vue {}
interface IntrinsicElements {
[elem: string]: any
}
}
}

Element-ui 的无限滚动(tsx 版本)

ts 版本和之前的 js 版本差距不适合很大,写法类似于 react,采用了 class 类声明变量和声明方法的时候直接用即可。使用count模拟初始数据,滚动到底部的时候触发 load 方法通过 push 方法模拟滚动请求回来的数据。

<div id="app"><img alt="Vue logo" src="./assets/logo.png"><div class="infinite-list" v-infinite-scroll="load" style="overflow:auto;height:200px"><ElementScroll :count="count"/>div>div>template><script lang="ts">import { Component, Vue } from 'vue-property-decorator';import ElementScroll from './components/ElementScroll';
@Component({components: {
ElementScroll
},
})export default class App extends Vue {
public count = [1, 2, 3, 4, 4, 5];
public num = 0;/**
* load
*/
public load() {this.count.push(this.num++)
}
}script>

tsx中通过@Component 来注册组件,@Prop 来属性传递和属性的校验,render 方法来渲染组件,因为不支持之前的 v-for 属性,采用了 map 方法代替

import { Component, Prop, Vue } from 'vue-property-decorator'
@Component
export default class ElementScroll extends Vue {
@Prop(Array) public count!: Array<Number>;
protected render() {
return (
<ul>
{
this.count.map(item => {
return <li class="infinite-list-item">{item}li>
})
}ul>
)
}
}

话不多说,看下效果图:6eb4c5b3b78475803d5c658685cceba5.gif

自己实现无滚动

首先看一下效果

f6885f09774348230daa41025edb5f4b.gif

后台接口数据格式

{
"code": 0,
"data": [
{
"href": "https://mmbiz.qpic.cn/mmbiz_gif/ciclmTicgVuW6iaPXwMnCJVwu4oXnlxV0sNiayhYLsejBUXWaETtG81XHTkTsmBvHDZAoJd4icgNWmonk0g24QCE5Ag/0?wx_fmt=gif",
"name": "完美解决JavaScript的深浅拷贝"
},
{
"href": "https://mmbiz.qpic.cn/mmbiz_gif/ciclmTicgVuW6iaPXwMnCJVwu4oXnlxV0sNiayhYLsejBUXWaETtG81XHTkTsmBvHDZAoJd4icgNWmonk0g24QCE5Ag/0?wx_fmt=gif",
"name": "理解装饰器是怎么使用的"
},
{
"href": "https://mmbiz.qpic.cn/mmbiz_gif/ciclmTicgVuW6iaPXwMnCJVwu4oXnlxV0sNiayhYLsejBUXWaETtG81XHTkTsmBvHDZAoJd4icgNWmonk0g24QCE5Ag/0?wx_fmt=gif",
"name": "浪漫七夕一举俘获美人心"
},
{
"href": "https://mmbiz.qpic.cn/mmbiz_gif/ciclmTicgVuW6iaPXwMnCJVwu4oXnlxV0sNiayhYLsejBUXWaETtG81XHTkTsmBvHDZAoJd4icgNWmonk0g24QCE5Ag/0?wx_fmt=gif",
"name": "深入分析Vue-Router原理,彻底看穿前端路由"
}
]
}

思路

设定页面可以展示 n 条数据,我们首屏分页向后台请求 n 条,当滚动条滚动到某个位置的时候再次发送接口向后台再请求 n 条数据以此类推。

首先需要获取滚动条的位置,即可视区的高度和内容区域底部距离可视区页面顶部的距离,如果他们相等此时浏览器的滚动条当好滚动到页面底部,如果相差是负数说明浏览器的滚动条还没有到达页面底部。e0b87350a61ad4b7c64d16a4c43ca5ed.png

  • 获取可视区高度 clientWidth
function getView(container: HTMLElement): any {
return {
width: Math.max(container.clientWidth, window.innerWidth || 0),
height: Math.max(container.clientHeight, window.innerHeight || 0),
};
}
  • 元素的大小及其相对于视口的位置 getBoundingClientRect[1]
function getHeight(container: HTMLElement, el: any): number {
return getView(container).height - el.getBoundingClientRect().bottom;
}

通过addEventListener监听scroll事,如果getHeight()的值到达某个设定的值时,我们就可以触发我们自己需求去调用接口等

优化页面

这里的想法是当我们的浏览器滚动条滚动之后,滚动上去的内容不显示在页面上,只显示可视区域的,减少页面的负载,先看一下效果

f5193c9d68d9bd5731171921145c4715.gif

当滚动条滚动回去的效果:

b709d13ba4dd4a3c60afa8062e46d160.gif

思路:通过监听内容区上部超出可视区域的高度和设置每一个目录的高度的比值计算出超出的条数,判断渲染数据的下标和条数的大小来展示。

<div class="scroll"><ul ref="list"><li v-for="(item,index) in lists" :key="index"><a :href="item.href" v-if="index+10>=num">{{item.name}}a>li>ul>div>
</template>

出现的问题:设置样式的时候,我们需要在li上设置不能给a设置,如果给a设置高度之后,判断不显示a之后计算超出的条数时就会出现问题,如图所示

235f08bec1634b572dfea8466e86dd30.gif

为了防止用户快速拖动滚动条,这里可以添加防抖函数和最后要移除事件监听。
public debounce(fn: any, wait: number): any {
let timeout: any = null;
return function () {
if (timeout != null) clearTimeout(timeout);
timeout = setTimeout(fn, wait);
};
}

源码已放到 github 上:https://github.com/clown-Jack/vue-scroll

总结

回顾一下上面的所想的,其实无限滚动也简单,就是能不能想到这个点子上,如果想不到那肯定就是天方夜谭了,这里面也有很多不足的地方需要改进,欢迎留言探讨和指点,毕竟这里的水很深,不小心鞋就湿了。

❤️ 交流讨论 欢迎关注公众号 秋风的笔记,主要记录日常中觉得有意思的工具以及分享开发实践,保持深度和专注度。回复"好友"可加微信,秋风的笔记常年陪伴你的左右。

67fa16275a3833c1448c79a815714a72.png

「点赞、在看、分享是对作者最大的支持❤️

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值