随手笔记:
html:
<p class="loading" id="upLoading" style='display:none;'>加载中</p>
js:
随手笔记:
html:
<p class="loading" id="upLoading" style='display:none;'>加载中</p>
js:
转载于:https://www.cnblogs.com/helenMoon/p/7307584.html
序
严格的来说,这是我第一个完全投入的开源项目,它的出现是为了统一移动H5中的下拉刷新,想通过一套框架,多主题拓展方式,适应于任意需求下的任意下拉刷新场景。
另外,这个项目作为独立项目存在,希望能有更多的人参与进来!
【minirefresh】优雅的H5下拉刷新。零依赖,高性能,多主题,易拓展。
特点
- 零依赖(原生JS实现,不依赖于任何库)
- 多平台支持。一套代码,多端运行,支持Android,iOS,主流浏览器
- 丰富的主题,官方提供多种主题(包括默认,applet-仿小程序,drawer3d-3d抽屉效果,taobao-仿淘宝等)
- 高性能。动画采用css3+硬件加速,在主流手机上流畅运行
- 良好的兼容性。支持和各种Scroll的嵌套(包括mui-scroll,IScroll,Swipe等),支持Vue环境下的使用
- 易拓展,三层架构,专门抽取UI层面,方便实现各种的主题,实现一套主题非常方便,而且几乎可以实现任何的效果
- 优雅的API和源码,API设计科学,简单,源码严谨,所有源码通过
ESlint
检测- 完善的文档与示例,提供完善的showcase,以及文档
源码
https://github.com/minirefresh/minirefresh
https://www.npmjs.com/package/minirefresh
官网与文档
https://minirefresh.github.io/
效果
基础示例
1. 【基础新闻列表】最基本的下拉刷新使用
2. 【多列表单容器】每次切换菜单时刷新容器
3. 【多列表多容器】多个列表都有一个Minirefresh对象
4. 【Vue支持】支持Vue下的使用
嵌套示例
1. 【Mui-Slider】内部嵌套图片轮播
2. 【Mui-Scroll】嵌套在Mui-Scroll中
3. 【Swipe】嵌套在Swipe中
主题示例
1. 【applet】仿微信小程序主题
2. 【taobao】仿淘宝刷新主题
3. 【drawer3d】3D抽屉效果主题
4. 【drawer-slider】滑动抽屉效果主题
showcase
可以直接在线体验效果
https://minirefresh.github.io/minirefresh/examples/
快速开始
引入
<link rel="stylesheet" href="xxx/minirefresh.css" /> <script type="text/javascript" src="xxx/minirefresh.js"></script>
或require
var MiniRefreshTools = require('xxx/minirefresh.js');
或import
import { MiniRefreshTools } from 'xxx/minirefresh.js';
页面布局
<!-- minirefresh开头的class请勿修改 --> <div id="minirefresh" class="minirefresh-wrap"> <div class="minirefresh-scroll"> </div> </div>
初始化
// 引入任何一个主题后,都会有一个 MiniRefresh 全局变量 var miniRefresh = new MiniRefresh({ container: '#minirefresh', down: { callback: function() { // 下拉事件 } }, up: { callback: function() { // 上拉事件 } } });
结束刷新
// 结束下拉刷新 miniRefresh.endDownLoading();
// 结束上拉加载 // 参数为true代表没有更多数据,否则接下来可以继续加载 miniRefresh.endUpLoading(true);
更多
更多的使用请参考官方文档
贡献
minirefresh
需要你!来为项目添砖加瓦,新的
Idea
,新的主题,重大Bug发现,新的设计资源(如图标,官网设计等)都可以通过
Issue
或PR
的方式提交!更多参考:https://minirefresh.github.io/minirefresh-doc/site/contribute/howtocontributor.html
讨论
- gitter
- QQ群(
601988892
)注意,申请加入群时请添加验证信息,例如:minirefresh使用遇到问题等等
最后关于灵感与参考
核心架构是参考的我自己以前的项目 https://github.com/dailc/pulltorefresh-h5-iscroll,只不过把依赖IScroll换成了原生JS与CSS3实现,并且完全的重构与优化
做这个项目的灵感与原动力是受 https://github.com/mescroll/mescroll 启发,但是由于那个项目里的代码不符合我的个人风格,一些主题拓展也没有达到我的要求,因此我自己重新写了一个项目而不是基于mescroll拓展
还有就是写这个项目也是对自己的一种锻炼,里面包含了
- JS与CSS3的熟练运用,并进行合理架构
- ESlint严格的代码检测
- Gulp 自动构建
- Karma+Mocha单元测试(待完善)
- Circleci,Codecov,Sauce等自动集成与测试网址,
- Gitbook构建API与教程文档
- Hexo构建官方网站(待完善)
- 域名备案,CDN加速等(待完善)
- Npm发布与Github项目团队
当然了,迫于一些原因,没有用全新的ES6或TS写,而是用的ES5严格模式。
另外,这个项目是托管在
Github
的minirefresh
组织上的,希望有更多的人能参与,成为组织的一员,共同维护,毕竟在不断的分享交流中才能进步更快...附录
博客
初次发布
2016.09.02
于我个人博客上面
H5下拉刷新和上拉加载实现原理浅析
前言
在移动端H5网页中,下拉刷新和上拉加载更多数据的交互方式出现频率很高,开源社区也有很多类似的解决方案,如iscroll,pulltorefresh.js库等。下面是对这两种常见交互基本实现原理的阐述。
实现原理
下拉刷新
实现下拉刷新主要分为三步:
touchstart
事件,记录其初始位置的值,e.touches[0].pageY
;touchmove
事件,记录并计算当前滑动的位置值与初始位置值的差值,大于0
表示向下拉动,并借助CSS3的translateY
属性使元素跟随手势向下滑动对应的差值,同时也应设置一个允许滑动的最大值;touchend
事件,若此时元素滑动达到最大值,则触发callback
,同时将translateY
重设为0
,元素回到初始位置。示例。查看链接:下拉刷新demo(PC浏览器需调成手机模拟器模式查看)
<main> <p class="refreshText"></p> <ul id="refreshContainer"> <li>111</li> <li>222</li> <li>333</li> <li>444</li> <li>555</li> ... </ul> </main>
(function(window) { var _element = document.getElementById('refreshContainer'), _refreshText = document.querySelector('.refreshText'), _startPos = 0, _transitionHeight = 0; _element.addEventListener('touchstart', function(e) { console.log('初始位置:', e.touches[0].pageY); _startPos = e.touches[0].pageY; _element.style.position = 'relative'; _element.style.transition = 'transform 0s'; }, false); _element.addEventListener('touchmove', function(e) { console.log('当前位置:', e.touches[0].pageY); _transitionHeight = e.touches[0].pageY - _startPos; if (_transitionHeight > 0 && _transitionHeight < 60) { _refreshText.innerText = '下拉刷新'; _element.style.transform = 'translateY('+_transitionHeight+'px)'; if (_transitionHeight > 55) { _refreshText.innerText = '释放更新'; } } }, false); _element.addEventListener('touchend', function(e) { _element.style.transition = 'transform 0.5s ease 1s'; _element.style.transform = 'translateY(0px)'; _refreshText.innerText = '更新中...'; // todo... }, false); })(window);
在下拉到松手的过程中,经历了三个状态:
上拉加载
上拉加载更多数据是在页面滚动时触发的动作,一般是页面滚动到底部时触发,也可以选择在滚动到一定位置的时候触发。
以滚动到页面底部为例。实现原理是分别获得当前滚动条的scrollTop
值、当前可视范围的高度值clientHeight
以及文档的总高度scrollHeight
。当scrollTop
和clientHeight
的值之和大于等于scrollHeight
时,触发callback
。
示例。查看链接:上拉加载demo
<main> <ul id="refreshContainer"> <li>111</li> <li>222</li> <li>333</li> <li>444</li> <li>555</li> ... </ul> <p class="refreshText"></p> </main>
(function(window) { // 获取当前滚动条的位置 function getScrollTop() { var scrollTop = 0; if (document.documentElement && document.documentElement.scrollTop) { scrollTop = document.documentElement.scrollTop; } else if (document.body) { scrollTop = document.body.scrollTop; } return scrollTop; } // 获取当前可视范围的高度 function getClientHeight() { var clientHeight = 0; if (document.body.clientHeight && document.documentElement.clientHeight) { clientHeight = Math.min(document.body.clientHeight, document.documentElement.clientHeight); } else { clientHeight = Math.max(document.body.clientHeight, document.documentElement.clientHeight); } return clientHeight; } // 获取文档完整的高度 function getScrollHeight() { return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); } var _text = document.querySelector('.refreshText'), _container = document.getElementById('refreshContainer'); // 节流函数 var throttle = function(method, context){ clearTimeout(method.tId); method.tId = setTimeout(function(){ method.call(context); }, 300); } function fetchData() { setTimeout(function() { _container.insertAdjacentHTML('beforeend', '<li>new add...</li>'); }, 1000); } window.onscroll = function() { if (getScrollTop() + getClientHeight() == getScrollHeight()) { _text.innerText = '加载中...'; throttle(fetchData); } }; })(window);
页面绑定onscroll
事件时加入了节流函数,其作用就是忽略滚动条300毫秒内的连续多次触发。
上拉刷新的实现主要依靠的是touch
事件的三个阶段,以及借助CSS3动画效果;下拉加载主要依靠页面的onscroll
事件,需要注意的是页面滚动时可能要考虑函数节流。
前言
在移动端H5网页中,下拉刷新和上拉加载更多数据的交互方式出现频率很高,开源社区也有很多类似的解决方案,如iscroll,pulltorefresh.js库等。下面是对这两种常见交互基本实现原理的阐述。实现原理
下拉刷新
实现下拉刷新主要分为三步:
<main>
<p class="refreshText"></p>
<ul id="refreshContainer">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
<li>555</li>
...
</ul>
</main>
(function(window) {
var _element = document.getElementById('refreshContainer'),
_refreshText = document.querySelector('.refreshText'),
_startPos = 0,
_transitionHeight = 0;
_element.addEventListener('touchstart', function(e) {
console.log('初始位置:', e.touches[0].pageY);
_startPos = e.touches[0].pageY;
_element.style.position = 'relative';
_element.style.transition = 'transform 0s';
}, false);
_element.addEventListener('touchmove', function(e) {
console.log('当前位置:', e.touches[0].pageY);
_transitionHeight = e.touches[0].pageY - _startPos;
if (_transitionHeight > 0 && _transitionHeight < 60) {
_refreshText.innerText = '下拉刷新';
_element.style.transform = 'translateY('+_transitionHeight+'px)';
if (_transitionHeight > 55) {
_refreshText.innerText = '释放更新';
}
}
}, false);
_element.addEventListener('touchend', function(e) {
_element.style.transition = 'transform 0.5s ease 1s';
_element.style.transform = 'translateY(0px)';
_refreshText.innerText = '更新中...';
// todo...
}, false);
})(window);
在下拉到松手的过程中,经历了三个状态:
以滚动到页面底部为例。实现原理是分别获得当前滚动条的scrollTop值、当前可视范围的高度值clientHeight以及文档的总高度scrollHeight。当scrollTop和clientHeight的值之和大于等于scrollHeight时,触发callback。
<main>
<ul id="refreshContainer">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
<li>555</li>
...
</ul>
<p class="refreshText"></p>
</main>
(function(window) {
// 获取当前滚动条的位置
function getScrollTop() {
var scrollTop = 0;
if (document.documentElement && document.documentElement.scrollTop) {
scrollTop = document.documentElement.scrollTop;
} else if (document.body) {
scrollTop = document.body.scrollTop;
}
return scrollTop;
}
// 获取当前可视范围的高度
function getClientHeight() {
var clientHeight = 0;
if (document.body.clientHeight && document.documentElement.clientHeight) {
clientHeight = Math.min(document.body.clientHeight, document.documentElement.clientHeight);
}
else {
clientHeight = Math.max(document.body.clientHeight, document.documentElement.clientHeight);
}
return clientHeight;
}
// 获取文档完整的高度
function getScrollHeight() {
return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
}
var _text = document.querySelector('.refreshText'),
_container = document.getElementById('refreshContainer');
// 节流函数
var throttle = function(method, context){
clearTimeout(method.tId);
method.tId = setTimeout(function(){
method.call(context);
}, 300);
}
function fetchData() {
setTimeout(function() {
_container.insertAdjacentHTML('beforeend', '<li>new add...</li>');
}, 1000);
}
window.onscroll = function() {
if (getScrollTop() + getClientHeight() == getScrollHeight()) {
_text.innerText = '加载中...';
throttle(fetchData);
}
};
})(window);
页面绑定onscroll事件时加入了节流函数,其作用就是忽略滚动条300毫秒内的连续多次触发。
小结
上拉刷新的实现主要依靠的是touch事件的三个阶段,以及借助CSS3动画效果;下拉加载主要依靠页面的onscroll事件,需要注意的是页面滚动时可能要考虑函数节流。