JS异步观察目标元素方式完成分页加载

目录
  • 介绍
  • 代码
  • 演示
  • 正文
    • 监听元素
    • 反复交叉
  • 结语

介绍

平时我们处理分页加载时,往往是通过滚动条判断是否到了容器底部再执行的加载任务的,这样有一个问题就是,不管滚动条是否划到底部位置,它都会运行计算这个函数。

那么,如果能判断底部的加载区域出现后再去执行加载,不用再做滚动条计算了,这样岂不美哉。本期将以异步观察目标元素的新方式去完成分页加载业务。

代码

<div id="app" @vue:mounted="mounted" :class="{'active':active}">
  <ul>
    <li v-for="item in num"><span>{{item}}</span>
      <p></p>
    </li>'
    <div class="loading">
      <div ref="loading" v-show="!isLoading"></div>
      loading..
    </div>
  </ul>
</div>
#app{
  display: none;
  &.active{
    display: block;
  }
}
ul{
  width: 100%;
  li{
    width: 100%;
    height: 10vh;
    display: flex;
    align-items: center;
    justify-content: start;
    box-sizing: border-box;
    padding: 0 3%;
    position: relative;
    border-bottom: 1px solid #efefef;
    font-size: 14px;
    font-family: fantasy, Courier, monospace;
    span{
      display: inline-block;
      min-width: 30px;
      text-align: center;
    }
    p{
      flex: 1;
      height: 4vh;
      background-color: #e2e2e2;
      margin-left: 3%;
    }
  }
}
.loading{
  font-family: fantasy, Courier, monospace;
  display: flex;
  height: 15vh;
  align-items: center;
  justify-content: center;
  animation: loading 1s linear infinite;
}
@keyframes loading{
  0%,100%{
    opacity: 1;
  }
  50%{
    opacity:0;
  }
}
import { createApp } from 'https://unpkg.com/petite-vue?module'
createApp({
  num: 0,
  page:1,
  active:false,
  observer:null,
  isLoading:false,
  mounted() {
      this.active = true;
      this.loading = this.$refs.loading;
      this.observer= new IntersectionObserver(()=>{
         this.addNum();
      },{
        root:window.document,
        rootMargin:"0px 0px 0px 0px",
        threshold:0
      })
      this.observer.observe(this.loading)
      // this.observer.unobserve(this.loading)
  },
  addNum(){
    if(this.isLoading) return;
    this.isLoading = true;
    console.log(`loading,page:${this.page}`)
    setTimeout(()=>{
      this.num += 20;
      this.page ++;
      this.$nextTick(()=>{
          this.isLoading = false;
      })
    },1000)
  }
}).mount()

演示

正文

监听元素

IntersectionObserver() 对不少小伙伴来说可能是一个比较生疏的构造器,你可以传入监听区域,以及监听后的回调函数,然后它会创建并返回一个 IntersectionObserver 对象,而这个对象可以来完成监听某个目标元素是否与该监听区域发生交叉,每次达到检查阈值后都会触发刚才传入的回调函数。

// 获取监听目标
this.loading = this.$refs.loading;
// 用构造器创建监听区域对象
this.observer= new IntersectionObserver(()=>{
    this.addNum();
},{
    root:window.document, // 监听区域,默认为整个可视窗体
    rootMargin:"0px 0px 0px 0px", // 类似margin,为边界的偏移量用于判定范围是否满足计算需要,默认0px 0px 0px 0px
    threshold:0  // 阈值(0-1),表示交叉区域的比例值,默认为0
})
//
this.observer.observe(this.loading)

根据以上代码就可以在业务中,判断元素是否出现在,只要达到阈值就会触发回调,在这个回调函数中你可以去完成加载列表等操作,从而代替频繁用计算滚动条的位置距离的困扰。

反复交叉

或许你在尝试使用异步观察目标元素的这个写法时,会发现一个严重的问题,就是可能本想加载一次的任务突然出现两次请求。这又是为什么呢?

其实就是因为 threshold 这个阈值,表示着交叉区域的比例值的,当你进入这个观察区域的时候会触发,当页面内容往下填充,会把监听目标元素往下推,又到达了这个阈值从而又触发了一次。

解决方案很简单,就是加一个 isLoading 开关,在请求中的时候,把根据这个开关把监听目标隐藏掉,等加载渲染结束之后,再显示出来,就可以解决这个问题了。具体可以看演示的案例哦~

<div class="loading">
    <div ref="loading" v-show="!isLoading"></div>
    loading..
</div>

结语

以异步观察目标元素的方式来完成诸如此类的业务比如说分页加载,触发动画,阻止操作等等都是不错的选择,而且从兼容性来看也可以放心在大多数现代浏览器中使用到它。

以上就是异步观察目标元素方式完成分页加载的详细内容,更多关于异步观察目标元素分页加载的资料请关注我们其它相关文章!

(0)

相关推荐

  • js异步之async和await实现同步写法

    首先我们假设有一方法 readFile 可以读取文件内容,  但是它是异步的. var gen = function* (){     var a = yield readFile('./a.txt');     console.log(a.toString());     var b = yield readFile('./b.txt');     console.log(b.toString()); }; 首先我们看下上面的代码,如果我们将function 后面的 * 改成 async,将y

  • Vue.js实现无限加载与分页功能开发

    本篇文章是一篇Vue.js的教程,目标在于用一种常见的业务场景--分页/无限加载,帮助读者更好的理解Vue.js中的一些设计思想.与许多Todo List类的入门教程相比,更全面的展示使用Vue.js完成一个需求的思考过程:与一些构建大型应用的高阶教程相比,又更专注于一些零碎细节的实现,方便读者快速掌握.致用. 需求分析 当一个页面中信息量过大时(例如一个新闻列表中有200条新闻需要展示),就会产生问题,例如: >数据量过大,影响加载速度 >用户体验差,很难定位到之前自己看过的某篇文章 >

  • Javascript vue.js表格分页,ajax异步加载数据

    分页一般和表格一起用,分页链接作为表格的一部分,将分页链接封装成一个独立的组件,然后作为子组件嵌入到表格组件中,这样比较合理. 效果: 代码: 1.注册一个组件 js Vue.component('pagination',{ template:'#paginationTpl', replace:true, props:['cur','all','pageNum'], methods:{ //页码点击事件 btnClick: function(index){ if(index != this.cu

  • JavaScript前端超时异步操作完美解决过程

    目录 如果一段代码久久不能执行完成,会怎么样? Axios 自带超时处理 处理 fetch() 超时 万物皆可超时 自从 ECMAScript 的 Promise ES2015 和 async/await ES2017 特性发布以后,异步在前端界已经成为特别常见的操作.异步代码和同步代码在处理问题顺序上会存在一些差别,编写异步代码需要拥有跟编写同步代码不同的"意识". 如果一段代码久久不能执行完成,会怎么样? 如果这是同步代码,我们会看到一种叫做"无响应"的现象,或

  • 基于JavaScript实现移动端无限加载分页

    本文实例为大家分享了js实现移动端无限加载分页的具体代码,供大家参考,具体内容如下 原理:当滚动条到达底部时,执行下一页内容. 判断条件需要理解三个概念:     1.scrollHeight 真实内容的高度     2.clientHeight 视窗的高度,即在浏览器中所能看到的内容的高度     3.scrollTop 视窗上面隐藏掉的部分,即滚动条滚动的距离 思路: 1.使用fixed定位加载框     2.使用$(window).scroll();方法来触发是否加载     3.通过 真

  • JS异步观察目标元素方式完成分页加载

    目录 介绍 代码 演示 正文 监听元素 反复交叉 结语 介绍 平时我们处理分页加载时,往往是通过滚动条判断是否到了容器底部再执行的加载任务的,这样有一个问题就是,不管滚动条是否划到底部位置,它都会运行计算这个函数. 那么,如果能判断底部的加载区域出现后再去执行加载,不用再做滚动条计算了,这样岂不美哉.本期将以异步观察目标元素的新方式去完成分页加载业务. 代码 <div id="app" @vue:mounted="mounted" :class="{

  • Android应用中ListView利用OnScrollListener分页加载数据

    当用户从网络上读取微薄的时候,如果一下子全部加载用户未读的微薄这将耗费比较长的时间,造成不好的用户体验,同时一屏的内容也不足以显示如此多的内容.这时候,我们就需要用到另一个功能,那就是listview的分页了.通过分页分次加载数据,用户看多少就去加载多少. 通常这也分为两种方式,一种是设置一个按钮,用户点击即加载.另一种是当用户滑动到底部时自动加载.今天我就和大家分享一下这个功能的实现. 首先,写一个xml文件,moredata.xml,该文件即定义了放在listview底部的视图: <?xml

  • Android性能优化之RecyclerView分页加载组件功能详解

    目录 引言 1 分页加载组件 1.1 功能定制 1.2 手写分页列表 1.3 生命周期管理 2 github 引言 在Android应用中,列表有着举足轻重的地位,几乎所有的应用都有列表的身影,但是对于列表的交互体验一直是一个大问题.在性能比较好的设备上,列表滑动几乎看不出任何卡顿,但是放在低端机上,卡顿会比较明显,而且列表中经常会伴随图片的加载,卡顿会更加严重,因此本章从手写分页加载组件入手,并对列表卡顿做出对应的优化 1 分页加载组件 为什么要分页加载,通常列表数据存储在服务端会超过100条

  • in.js 一个轻量级的JavaScript颗粒化模块加载和依赖关系管理解决方案

    国外的像基于jQuery的RequireJs,YUI Loader,LabJs,RunJs,国内也有淘宝的SeaJs,豆瓣的DoJs等,这些都是一些十分优秀的模块加载器.但是本文将会向大家介绍一个新的开源的轻量级"多线程"异步模块加载器In.js,In的开发借鉴了Do的一些思路和使用习惯,在此期间感谢@kejun同我的耐心交流,In.js压缩后只有4.77k,不仅小巧而且十分好用. 优点: 按需加载 无阻塞加载 依赖关系管理 颗粒化模块管理 如何使用? A.引入In.js 复制代码 代

  • ListView 分页加载更新实例分享

    ListView是android中最常用的控件之一. 在实际运用中往往会遇到一次性加载全部数据过多,需要分页加载增加程序运行效率! 本demo是将更新的监听放在listview的foot中,通过底部按钮点击触发或者通过滑动事件监听,当滑动到列表最底部的时候触发. 有图有真像: 列表初始状态  触发加载  加载后  部分代码: MainActivity 复制代码 代码如下: private void initActivity() { // TODO Auto-generated method st

  • Android基于ListView实现类似Market分页加载效果示例

    本文实例讲述了Android基于ListView实现类似Market分页加载效果.分享给大家供大家参考,具体如下: 最近几天研究ListView实现分页加载和滚动加载,发现可以用listView的OnScroll方法来实现,直接上代码 ListViewScroll.java package zy.lucifer.ListViewScroll; import android.app.Activity; import android.os.Bundle; import android.util.Lo

  • 微信小程序实战之上拉(分页加载)效果(2)

    上拉加载(分页加载) 当用户打开一个页面时,假设后台数据量庞大时,一次性地返回所有数据给客户端,页面的打开速度就会有所下降,而且用户只看上面的内容而不需要看后面的内容时,也浪费用户流量,基于优化的角度来考虑,后台不要一次性返回所有数据,当用户有需要再往下翻的时候,再加载更加数据出来. 业务需求: 列表滚动到底部时,继续往上拉,加载更多内容 必备参数: (1)pageindex: 1 //第几次加载 (2)callbackcount: 15 //需要返回数据的个数 其他参数: 根据接口的所需参数

  • JS+CSS实现下拉刷新/上拉加载插件

    闲来无事,写了一个当下比较常见的下拉刷新/上拉加载的jquery插件,代码记录在这里,有兴趣将代码写成插件与npm包可以留言. 体验地址:http://owenliang.github.io/pullToRefresh/ 项目地址:https://github.com/owenliang/pullToRefresh 实现注意: 利用transition做动画时,优先使用transform:translate取代top,后者动画流畅度存在问题. 各移动浏览器对手势触摸的处理不同(简单罗列如下),但

  • Android程序开发之Listview下拉刷新上拉(滑动分页)加载更多

    最近做的类似于微博的项目中,有个Android功能要使用到listview的向下拉刷新来刷新最新消息,向上拉刷新(滑动分页)来加载更多. 新浪微博就是使用这种方式的典型. 当用户从网络上读取微博的时候,如果一下子全部加载用户未读的微博这将耗费比较长的时间,造成不好的用户体验,同时一屏的内容也不足以显示如此多的内容.这时候,我们就需要用到另一个功能,那就是listview的分页了,其实这个分页可以做成客户端的分页,也可以做成服务器端的分页(点击加载时,从服务器对应的加载第N页就好了!!!).通过分

  • vue实现分页加载效果

    本文实例为大家分享了vue分页加载的具体代码,供大家参考,具体内容如下 HTML <!-- 商品 页数--> <div class="pagenavi"> <div class="all-number"> <span>共{{data.length}}个商品</span> </div> <p class="pageArea" data-countpage="1&

随机推荐