效果


css

html,body{
height:100%; // 其他界面未设置html 无法监听scroll
}
/* 下拉刷新 */
.refresh-loading {
transition: all 300ms ease 0s;
height: 0;
padding-top: 10px;
overflow: hidden;
} .type-1 .con,
.refresh-loading .g-m--c {
width: 16px;
height: 16px;
border-radius: 50%;
-webkit-animation-name: locate-loading;
-moz-animation-name: locate-loading;
animation-name: locate-loading;
-webkit-animation-duration: 1.58s;
-moz-animation-duration: 1.58s;
animation-duration: 1.58s;
-webkit-animation-timing-function: linear;
-moz-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
animation-iteration-count: infinite;
border-top: 2px solid #f43939;
border-left: 2px solid #df5555;
margin: auto;
} @keyframes locate-loading {
0% {
opacity: 1;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
opacity: 1;
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
transform: rotate(360deg);
}
} @-webkit-keyframes locate-loading {
0% {
opacity: 1;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
opacity: 1;
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
transform: rotate(360deg);
}
} @-moz-keyframes locate-loading {
0% {
opacity: 1;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
opacity: 1;
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
transform: rotate(360deg);
}
} .refresh-txt {
color: #999;
text-align: center;
font-size: 12px;
}
/* 上拉加载 */
.more-c {
font-size: 12px;
} .more-c .con {
margin: 0 5px 0 0;
} .more-c .type {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
} .type-1:after {
content: '加载中...';
display: inline-block
}

html

<!-- 不设置高度,在执行滚动时,监听不到div上有scroll事件 -->
<!-- height: 100%;设置高度,不然会监听不到scroll -->
<body style="background-color: #FFFFFF;height: 100%;">
<div class="app_header"></div>
<!-- height: 100%;overflow: auto;设置高度,不然会监听不到scroll -->
<div class="warper" style="padding-top: 120px;overflow: auto;width: 100%;height: 100%;">
<!-- 下拉刷新 -->
<div class="refresh-loading" >
<div class="g-m--c"></div>
<p class="refresh-txt">下拉可刷新</p>
</div>
<!-- 下拉刷新 -->
<!-- 数据渲染容器 -->
<div id="result" class="scroll"></div> <!-- 数据渲染模板 --> <!-- 上拉加载 -->
<div class="more-c">
<div id="loadMore" class="type">
<div class="con"></div>
</div>
</div>
<!-- 上拉加载 -->
</div>

JavaScript

    var page = 1;//页面显示页码
var quantity = 10;//每页显示总数
var isPullUpLoad = false;//是否为上拉加载
var isPullDownRefresh = true;//下拉刷新
/** 下拉刷新/上拉加载 开始 **/
var moveEle = document.getElementsByClassName('warper')[0]; //内容容器,可视区域
var scrollView = document.getElementsByClassName('scroll')[0]; //真正的内容
var refreshEle = document.getElementsByClassName('refresh-loading')[0]; //刷新的loading
var refreshTxtEle = document.getElementsByClassName('refresh-txt')[0]; //刷新显示的提示文字
var touch, moved, startY, diff, moveDiff = 60; // 设置一个移动距离
// 可视区域监听触摸开始
moveEle.addEventListener('touchstart', function (e) {
// fyappapi.toastInfo(moveEle.scrollTop);
if (moveEle.scrollTop > 0) {
//当页面已经有滚动或者不是置顶的时候,不需要进行下拉刷新,是页面正常的滑动
touch = false;
return;
}
touch = true; //触摸开始
moved = false; //还没有进行下拉刷新的滑动
startY = e.touches[0].clientY; //记录当前手指在屏幕上的纵向坐标,用于判断页面是上滑还是下滑
}, false);
// 可视区域监听移动
moveEle.addEventListener('touchmove', function (e) {
if (!touch || !isPullDownRefresh) {
return;
}
var touchesDiff = e.touches[0].clientY - startY; //计算的移动位移
if (touchesDiff < 0) {
//说明页面是向上滑的,不做任何操作
moved = false;
return;
}
moved = true;
diff = touchesDiff;
var distance = 0;
if (diff <= moveDiff) {
//moveDiff至少要等于loading的高度
//当滑动小于规定的临界值时
distance = diff;
refreshTxtEle.innerHTML = '下拉可刷新';
} else {
refreshTxtEle.innerHTML = '释放可刷新';
//弹性
if (touchesDiff <= (2 * moveDiff)) {
distance = moveDiff + 0.5 * (touchesDiff - moveDiff);
} else {
distance = moveDiff + 0.1 * (touchesDiff - moveDiff) + 0.05 * (touchesDiff - 2 * moveDiff);
}
}
if (distance > 0) {
//滑动的距离
css(refreshEle, 0);
refreshEle.style.height = distance + 'px';
}
generatedCount = 0; //下拉刷新的时候清空上拉加载更多的次数统计
}, false);
// 可视区域监听触摸完成
moveEle.addEventListener('touchend', function (e) {
if (!touch || !moved) {
refreshEle.style.height = '0px';
return;
}
css(refreshEle, 300);
isPullDownRefresh = false;
if (diff > moveDiff) {
refreshTxtEle.innerHTML = '刷新中';
refreshEle.style.height = moveDiff + 'px'; setTimeout(() => {
// fyappapi.toastInfo('下拉刷新');
//延迟模拟接口调用
css(refreshEle, 300);
page = 1;
quantity = 100;
if(type == 0){ // 店铺
getdata();
}else{
getcangku(); // 仓库
}
refreshEle.style.height = '0px';
setTimeout(() => {
isPullDownRefresh = true; //控制在刷新期间,重复向下拉动,不做任何操作
}, 300);
}, 500);
} else {
isPullDownRefresh = true;
refreshEle.style.height = '0px';
}
}, false); function css(ele, t) {
ele.style.transition = "all " + t + "ms";
ele.style.webkitTransition = "all " + t + "ms";
} //上拉加载 开始
var loadMore = document.getElementById('loadMore');
var className = loadMore.getAttribute('class');
// fyappapi.toastInfo(scrollView.offsetHeight);
//上拉加载 监听scroll 若未设置
moveEle.addEventListener('scroll', function (e) {
requestAnimationFrame(function () {
//当数据正在加载时,直接返回
if (isPullUpLoad) {
return;
}
var contentHeight = scrollView.offsetHeight; //1500
//滚动的距离,加上可视窗口的高度,因为设置了content的max-height为300px
var scrollTop = moveEle.scrollTop + 300; //开始325.5 最后 1124
// alert(scrollTop);
// 原这里减掉30,可能因为布局不同,我需要减到400才能触发
if (contentHeight && scrollTop > contentHeight - 400) {
//当滚动距离内容底部30px的时候,拉取下一页数据
//html5提供的classList
loadMore.classList.add('type-1');
isPullUpLoad = true;
setTimeout(() => {
//接口调用
loadMore.classList.remove('type-1');
// fyappapi.toastInfo('接口调用');
page ++ ;
if(type == 0){ // 店铺
getdata();
}else{
getcangku(); // 仓库
}
}, 300);
} });
}, false);
/** 下拉刷新/上拉加载 完 **/ // 接口获取数据渲染界面 根据 isPullUpLoad 判断
if (data.status == 1) {
var template = $.templates("#theTmpl");
var htmlOutput = template.render(data.result);
if (isPullUpLoad != true) {
$("#result").html(htmlOutput);
} else {
isPullUpLoad = false;
$("#result").append(htmlOutput);
} } else {
if (isPullUpLoad == true) {
isPullUpLoad = false;
page--;
fyappapi.toastInfo("没有更多数据了!");
} else {
$("#result").html(`<div style="display: flex;flex-direction: column;justify-content: center;align-items: center;margin-top: 40%;">
<img style="width: 50%;height: 50%;" src="__PUBLIC__/img/nono_data.png" />
<span style="margin-top: 30px;font-size: 20px;color: #666666;">暂无数据</span>
</div>`);
}
}

道路还是很遥远 很感恩发布共享的大佬们,我花了三天时间才解决各种问题

js 前端实现下拉刷新 上拉加载的更多相关文章

  1. Android 下拉刷新上啦加载SmartRefreshLayout + RecyclerView

    在弄android刷新的时候,可算是耗费了一番功夫,最后发觉有现成的控件,并且非常好用,这里记录一下. 原文是 https://blog.csdn.net/huangxin112/article/de ...

  2. SwipeRefreshLayout实现下拉刷新上滑加载

    1. 效果图 2.RefreshLayout.java package myapplication.com.myapplication; import android.content.Context; ...

  3. 移动端下拉刷新上拉加载-mescroll.js插件

    最近无意间看到有这么一个上拉刷新下拉加载的插件 -- mescroll.js,个人感觉挺好用的,官网地址是:http://www.mescroll.com 然后我就看了一下文档,简单的写了一个小dem ...

  4. JS+CSS实现的下拉刷新/上拉加载插件

    闲来无事,写了一个当下比较常见的下拉刷新/上拉加载的jquery插件,代码记录在这里,有兴趣将代码写成插件与npm包可以留言. 体验地址:http://owenliang.github.io/pull ...

  5. vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件

    vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源 ...

  6. [ionic开源项目教程] - 第7讲 实现下拉刷新上拉加载ion-refresher和ion-infinite-scroll

    第7讲 实现下拉刷新上拉加载ion-refresher和ion-infinite-scroll 1.将tab1.html的代码改为如下: <ion-content> <ion-ref ...

  7. 基于SwiperJs的H5/移动端下拉刷新上拉加载更多的效果

    最早时,公司的H5项目中曾用过点击一个"加载更多"的DOM元素来实现分页的功能,后来又用过网上有人写的一个上拉加载更多的插件,那个插件是页面将要滚动到底部时就自动请求数据并插入到页 ...

  8. 基于SwiperJs的H5/移动端下拉刷新上拉加载更多

    最早时,公司的H5项目中曾用过点击一个"加载更多"的DOM元素来实现分页的功能,后来又用过网上有人写的一个上拉加载更多的插件,那个插件是页面将要滚动到底部时就自动请求数据并插入到页 ...

  9. react-native 模仿原生 实现下拉刷新/上拉加载更多(RefreshListView)

    1.下拉刷新/上拉加载更多 组件(RefreshListView) src/components/RefreshListView/index.js /** * 下拉刷新/上拉加载更多 组件(Refre ...

随机推荐

  1. docker-compose + nginx部署前后端分离的项目

    安装docker 安装必要的系统工具 # 更新yum工具 yum update -y # 安装必要的工具 yum install -y yum-utils device-mapper-persiste ...

  2. 什么是sql注入?如何有效防止sql注入?

    一.什么是sql注入 利用程序员的代码bug,将输入的参数绕过校验并在系统中当做代码运行,从而攻击系统. 二.如何避免sql注入 1.对sql语句进行预编译 PreparedStatement类可以对 ...

  3. 你在项目中哪些地方用到了 XML?

    XML 的主要作用有两个方面:数据交换和信息配置.在做数据交换时,XML 将数 据用标签组装成起来,然后压缩打包加密后通过网络传送给接收者,接收解密与 解压缩后再从 XML 文件中还原相关信息进行处理 ...

  4. java中的正则表达式And Pattern And Macher

    在哪里?? java.util.regex包下有两个用于正则表达式的类, 一个是Matcher类, 另一个Pattern 简单例子 public class RegexLeaning { public ...

  5. SQL 注入漏洞产生的原因?如何防止?

    SQL 注入产生的原因:程序开发过程中不注意规范书写 sql 语句和对特殊字符进 行过滤,导致客户端可以通过全局变量 POST 和 GET 提交一些 sql 语句正常执行. 防止 SQL 注入的方式: ...

  6. js获取元素本身相关值

    Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置. getClientRects() 方法返回的一组矩形的集合, 即:是与该元素相关的CSS 边框集 ...

  7. List、Set、Map 和 Queue 之间的区别?

    List 是一个有序集合,允许元素重复.它的某些实现可以提供基于下标值的常量 访问时间,但是这不是 List 接口保证的.Set 是一个无序集合.

  8. TIME_WAIT 优化

    ·[场景描述] HTTP1.1之后,HTTP协议支持持久连接,也就是长连接,优点在于在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟. 如果我们使用了nginx去作为 ...

  9. Tensorflow安装教程(Anaconda)

    写在最前: 在安装过程中遇到很多坑,一开始自己从官网下载了Python3.6.3或者Python3.6.5或者Python3.7.1等多个版本,然后直接pip install tensorflow或者 ...

  10. 关于个人开源项目(vue app)的一些总结

    关于个人开源项目(vue app)的一些总结 项目地址 https://github.com/BYChoo/record 项目简介 此项目名叫:Record.是以Vue全家桶(vue,vue-rout ...