返回顶部
首页 > 资讯 > 后端开发 > Python >Python简洁且有趣的无限下拉的实现方法是什么
  • 634
分享到

Python简洁且有趣的无限下拉的实现方法是什么

2023-06-01 23:06:57 634人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

本篇内容介绍了“python简洁且有趣的无限下拉的实现方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!不知你是否从上面这张图中注意到

本篇内容介绍了“python简洁且有趣的无限下拉的实现方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

Python简洁且有趣的无限下拉的实现方法是什么

不知你是否从上面这张图中注意到了什么,比如只是渲染了可视区域的部分 DOM ,滚动过程中只是外层容器的 padding 在改变?

前一点很好理解,我们考虑到性能,不可能将一个长列表(甚至是一个无限下拉列表)的所有列表元素都进行渲染;而后一点,则是本文所介绍方案的核心之一!

不卖关子,提前告诉你该方案的要素就是两个:

  • Intersection Observer

  • padding

说明了要素,也许你可以尝试着开始思考,看你是否能猜到具体的实现方案。

方案介绍

Intersection Observer

基本概念

一直以来,检测元素的可视状态或者两个元素的相对可视状态都不是件容易事。传统的各种方案不但复杂,而且性能成本很高,比如需要监听滚动事件,然后查询 DOM , 获取元素高度、位置,计算距离视窗高度等等。

这就是 Intersection Observer 要解决的问题。它为开发人员提供一种便捷的新方法来异步查询元素相对于其他元素或视窗的位置,消除了昂贵的 DOM 查询和样式读取成本。

兼容性

主要在 Safari 上兼容性较差,需要 12.2 及以上才兼容,不过还好,有 polyfill 可食用。

一些应用场景
  • 页面滚动时的懒加载实现。

  • 无限下拉(本文的实现)。

  • 监测某些广告元素的曝光情况来做相关数据统计。

  • 监测用户的滚动行为是否到达了目标位置来实现一些交互逻辑(比如视频元素滚动到隐藏位置时暂停播放)。

padding 方案实现

基本了解 Intersection Observer 之后,接下来就看下如何用 Intersection Observer + padding 来实现无限下拉。

先概览下总体思路:

  • 监听一个固定长度列表的首尾元素是否进入视窗;

  • 更新当前页面内渲染的第一个元素对应的序号;

  • 根据上述序号,获取目标数据元素,列表内容重新渲染成对应内容;

  • 容器 padding 调整,模拟滚动实现。

核心:利用父元素的 padding 去填充随着无限下拉而本该有的、越来越多的 DOM 元素,仅仅保留视窗区域上下一定数量的 DOM 元素来进行数据渲染。

1、监听一个固定长度列表的首尾元素是否进入视窗
// 观察者创建
this.observer = new IntersectionObserver(callback, options);

// 观察列表第一个以及最后一个元素
this.observer.observe(this.firstItem);
this.observer.observe(this.lastItem);

我们以在页面中渲染固定的 20 个列表元素为例,我们对第一个元素和最后一个元素,用 Intersection Observer 进行观察,当他们其中一个重新进入视窗时,callback 函数就会触发:

const callback = (entries) => {
   entries.forEach((entry) => {
       if (entry.target.id === firstItemId) {
           // 当第一个元素进入视窗
       } else if (entry.target.id === lastItemId) {
           // 当最后一个元素进入视窗
       }
   });
};
2、更新当前页面渲染的第一个元素对应的序号 (firstIndex)

拿具体例子来说明,我们用一个数组来维护需要渲染到页面中的数据。数组的长度会随着不断请求新的数据而不断变大,而渲染的始终是其中一定数量的元素,比如 20 个。那么:

  • 最开始渲染的是数组中序号为 0 - 19 的元素,即此时对应的 firstIndex 为 0;

  • 当序号为 19 的元素(即上一步的 lastItem )进入视窗时,我们就会往后渲染 10 个元素,即渲染序号为 10 - 29 的元素,那么此时的 firstIndex 为 10;

  • 下一次就是,当序号为 29 的元素进入视窗时,继续往后渲染 10个元素,即渲染序号为 20 - 39 的元素,那么此时的 firstIndex 为 20,以此类推。。。

// 我们对原先的 firstIndex 做了缓存
const { currentIndex } = this.domDataCache;

// 以全部容器内所有元素的一半作为每一次渲染的增量
const increment = Math.floor(this.listSize / 2);

let firstIndex;

if (isScrollDown) {
   // 向下滚动时序号增加
   firstIndex = currentIndex + increment;
} else {
   // 向上滚动时序号减少
   firstIndex = currentIndex - increment;
}

总体来说,更新 firstIndex,是为了根据页面的滚动情况,知道接下来哪些数据应该被获取、渲染。

3、根据上述序号,获取对应数据元素,列表重新渲染成新的内容
const renderFunction = (firstIndex) => {
   // offset = firstIndex, limit = 10 => getData
   // getData Done =>  new dataitems => render DOM
};

这一部分就是根据 firstIndex 查询数据,然后将目标数据渲染到页面上即可。

4、padding 调整,模拟滚动实现

既然数据的更新以及 DOM 元素的更新我们已经实现了,那么无限下拉的效果以及滚动的体验,我们要如何实现呢?

想象一下,抛开一切,最原始最直接最粗暴的方式无非就是我们再又获取了 10 个新的数据元素之后,再塞 10 个新的 DOM 元素到页面中去来渲染这些数据。

但此时,对比上面这个粗暴的方案,我们的方案是:这 10个新的数据元素,我们用原来已有的 DOM 元素去渲染,替换掉已经离开视窗、不可见的数据元素;而本该有更多 DOM 元素进一步撑开容器高度的部分,我们用 padding 填充来模拟实现。

Python简洁且有趣的无限下拉的实现方法是什么

  • 向下滚动

// padding的增量 = 每一个item的高度 x 新的数据项的数目
const remPaddingsVal = itemHeight * (Math.floor(this.listSize / 2));

if (isScrollDown) {
   // paddingTop新增,填充顶部位置
   newCurrentPaddingTop = currentPaddingTop + remPaddingsVal;

   if (currentPaddingBottom === 0) {
       newCurrentPaddingBottom = 0;
   } else {
       // 如果原来有paddingBottom则减去,会有滚动到底部的元素进行替代
       newCurrentPaddingBottom = currentPaddingBottom - remPaddingsVal;
   }
}

Python简洁且有趣的无限下拉的实现方法是什么

Python简洁且有趣的无限下拉的实现方法是什么

  • 向上滚动

// padding的增量 = 每一个item的高度 x 新的数据项的数目
const remPaddingsVal = itemHeight * (Math.floor(this.listSize / 2));

if (!isScrollDown) {
   // paddingBottom新增,填充底部位置
   newCurrentPaddingBottom = currentPaddingBottom + remPaddingsVal;

   if (currentPaddingTop === 0) {
       newCurrentPaddingTop = 0;
   } else {
       // 如果原来有paddingTop则减去,会有滚动到顶部的元素进行替代
       newCurrentPaddingTop = currentPaddingTop - remPaddingsVal;
   }
}

Python简洁且有趣的无限下拉的实现方法是什么

Python简洁且有趣的无限下拉的实现方法是什么

  • 最后是 padding 设置更新以及相关缓存数据更新

// 容器padding重新设置
this.updateContainerPadding({
   newCurrentPaddingBottom,
   newCurrentPaddingTop
})

// DOM元素相关数据缓存更新
this.updateDomDataCache({
   currentPaddingTop: newCurrentPaddingTop,
   currentPaddingBottom: newCurrentPaddingBottom
});

思考总结

方案总结:

利用 Intersection Observer 来监测相关元素的滚动位置,异步监听,尽可能得减少 DOM 操作,触发回调,然后去获取新的数据来更新页面元素,并且用调整容器 padding 来替代了本该越来越多的 DOM 元素,最终实现列表滚动、无限下拉。

相关方案的对比

这里和较为有名的库 - iScroll 实现的无限下拉方案进行一个基本的对比,对比之前先说明下 iScroll infinite 的实现概要:

  • iScroll 通过对传统滚动事件的监听,获取滚动距离,然后:

  • 设置父元素的 translate 来实现整体内容的上移(下移);

  • 再基于这个滚动距离进行相应计算,得知相应子元素已经被滚动到视窗外,并且判断是否应该将这些离开视窗的子元素移动到末尾,从而再对它们进行 translate 的设置来移动到末尾。这就像是一个循环队列一样,随着滚动的进行,顶部元素先出视窗,但又将移动到末尾,从而实现无限下拉。

  • 相关对比:

    • 实现对比:一个是 Intersection Observer 的监听,来通知子元素离开视窗,只要定量设置父元素 padding 就行;另一个是对传统滚动事件的监听,滚动距离的获取,再进行一系列计算,去设置父元素以及子元素的 translate。显而易见,前者看起来更加简洁明了一些。

    • 性能对比:我知道说到对比,你脑海中肯定一下子会想到性能问题。其实性能对比的关键就是 Intersection Observer。因为单就 padding 设置还是 translate 设置,性能方面的差距是甚小的,只是个人感觉 padding 会简洁些?而 Intersection Observer 其实抽离了所有滚动层面的相关逻辑,你不再需要对滚动距离等相应 DOM 属性进行获取,也不再需要进行一系列滚动距离相关的复杂计算,并且同步的滚动事件触发变成异步的,你也不再需要另外去做防抖之类的逻辑,这在性能方面还是有所提升的。

存在的缺陷:
  • padding 的计算依赖列表项固定的高度。

  • 这是一个同步渲染的方案,也就是目前容器 padding 的计算调整,无法计算异步获取的数据,只跟用户的滚动行为有关。这看起来与实际业务场景有些不符。解决思路:

    • 思路 1、利用 Skeleton Screen Loading 来同步渲染数据元素,不受数据异步获取的影响。即在数据请求还未完成时,先使用一些图片进行占位,待内容加载完成之后再进行替换。

    • 思路 2、滚动到目标位置,阻塞容器 padding 的设置(即无限下拉的发生)直至数据请求完毕,用 loading gif 提示用户加载状态,但这个方案相对复杂,你需要全面考虑用户难以预测的滚动行为来设置容器的 padding。

Python简洁且有趣的无限下拉的实现方法是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: Python简洁且有趣的无限下拉的实现方法是什么

本文链接: https://lsjlt.com/news/228038.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python简洁且有趣的无限下拉的实现方法是什么
    本篇内容介绍了“Python简洁且有趣的无限下拉的实现方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!不知你是否从上面这张图中注意到...
    99+
    2023-06-01
  • git merge最简洁的使用方法是什么
    git merge最简洁的使用方法是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。在Git中使用最频繁的命令之一就是git merge,git-merge命令是用于将两个或...
    99+
    2023-06-28
  • php实现限时的方法是什么
    这篇文章主要讲解了“php实现限时的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“php实现限时的方法是什么”吧!通过“set_time_limit(0)”让程序无限制执行下去。通...
    99+
    2023-06-25
  • python无限循环语句的实现方法
    这篇文章主要为大家展示了python无限循环语句的实现方法,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“python无限循环语句的实现方法”这篇文章吧。python无限循环语句的实现方法:在whi...
    99+
    2023-06-06
  • html5实现下拉列表的标签是什么
    这篇文章主要介绍html5实现下拉列表的标签是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! html5实现下拉列表的标签是“<select&g...
    99+
    2024-04-02
  • VB.NET实现闰年的简单方法是什么
    VB.NET实现闰年的简单方法是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。想必大家都知道闰年是怎么回事吧,就是四年一闰,百年不闰,四百年再闰。在VB.N...
    99+
    2023-06-17
  • python自制简易mysql连接池的实现方法是什么
    这篇文章主要讲解了“python自制简易mysql连接池的实现方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python自制简易mysql连接池的实现方法是什么”吧!连接池是什么连...
    99+
    2023-06-25
  • html下拉菜单文字变小的方法是什么
    这篇文章主要介绍“html下拉菜单文字变小的方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“html下拉菜单文字变小的方法是什么”文章能帮助大家解决问题。 ...
    99+
    2024-04-02
  • 使用python实现下拉选择框和页签的方法
    目录前言ttk模块下拉选择框combobox下拉选择框2页签Notebook 前言 python学习之路任重而道远,要想学完说容易也容易,说难也难。很多人说python最好学了,但扪...
    99+
    2023-03-11
    python下拉选择框和页签 python下拉选择框 python页签 python选择框
  • Python使用for实现无限循环的方式有哪些
    这篇文章主要介绍“Python使用for实现无限循环的方式有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python使用for实现无限循环的方式有哪些”文章能帮助大家解决问题。Python使用...
    99+
    2023-07-05
  • Python技法之简单递归下降Parser的实现方法
    目录1. 算术运算表达式求值2. 生成表达式树左递归和运算符优先级陷阱3. 相关包参考总结1. 算术运算表达式求值 在上一篇博文《Python技法:用re模块实现简易tokenize...
    99+
    2024-04-02
  • Python多进程实现的方法是什么
    Python多进程实现的方法有两种:使用multiprocessing模块和使用concurrent.futures模块。 使用m...
    99+
    2024-04-02
  • koa-compose简单实现及使用的方法是什么
    这篇“koa-compose简单实现及使用的方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“koa-compose简...
    99+
    2023-07-06
  • vue权限控制与管理的实现方法是什么
    本篇内容介绍了“vue权限控制与管理的实现方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、 菜单权限菜单权限:控制用户在系统中能...
    99+
    2023-07-05
  • python简单程序的编写方法是什么
    这篇文章主要介绍“python简单程序的编写方法是什么”,在日常操作中,相信很多人在python简单程序的编写方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python简单程序的编写方法是什么”的疑...
    99+
    2023-06-17
  • python简单数值运算的方法是什么
    Python中进行简单数值运算的方法包括使用算术运算符、使用内置数学函数和使用第三方数学库。1. 使用算术运算符:- 加法:`+`-...
    99+
    2023-10-10
    python
  • 微信小程序实现文字从右往左无限滚动的方法是什么
    微信小程序实现文字从右往左无限滚动的方法:1.创建微信小程序项目;2.在index.wxml文件中添加页面设计代码;3.在index.wxss文件中添加样式代码;4.在index.js文件中添加实现文件滚动效果的代码;5.保存编辑的代码并进...
    99+
    2024-04-02
  • Python定时任务的实现方法是什么
    今天就跟大家聊聊有关Python定时任务的实现方法是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1、定时任务定时任务,顾名思义: 定时执行的任务,可以是一段bash命令,也可以...
    99+
    2023-06-25
  • python实现层次聚类的方法是什么
    本篇内容介绍了“python实现层次聚类的方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!层次聚类算法顾名思义,层次聚类就是一层一层...
    99+
    2023-06-25
  • Python实现链表反转的方法是什么
    本篇内容主要讲解“Python实现链表反转的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python实现链表反转的方法是什么”吧!Python实现链表反转链表反转(while迭代实现...
    99+
    2023-06-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作