all-of-javascript
all-of-javascript copied to clipboard
h5上拉加载下拉刷新
参考:
offsetHeight、clientHeight、scrollTop等
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>pull</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html, body, header, div, main, p, span, ul, li {
margin: 0;
padding: 0;
}
.wrapper li {
list-style: none;
padding: 20px 10px;
background-color: #eee;
margin-bottom: 1px;
}
.refresh {
position: absolute;
width: 100%;
line-height: 50px;
text-align: center;
left: 0;
top: 0;
}
.more {
line-height: 50px;
text-align: center;
}
</style>
</head>
<body>
<main>
<p class="refresh"></p>
<ul class="wrapper">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
<li>g</li>
<li>h</li>
<li>i</li>
<li>j</li>
<li>k</li>
<li>l</li>
<li>m</li>
</ul>
<p class="more"></p>
</main>
</body>
<script>
(function(window){
// 下拉刷新
var refreshTarget = document.querySelector('.wrapper');
var refreshTip = document.querySelector('.refresh');
var moreTip = document.querySelector('.more');
var addEventListener = refreshTarget.addEventListener;
var removeEventListener = refreshTarget.removeEventListener;
var style = refreshTarget.style;
var location = window.location;
var start = 0;
var transformHeight = 0;
var offset = 60;
var boby = document.body;
var dbody = document.documentElement;
// 节流函数
function throttle(fn, wait, options){
var timeout, context, args, previous = 0;
if(!options) options = {};
var later = function(){
previous = options.leading === false ? 0 : +new Date();
timeout = null;
fn.apply(context, args);
if(!timeout) context = args = null;
}
var throttled = function(){
var now = +new Date();
if(options.leading === false && !previous) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if(remaining <= 0 || remaining > wait){
if(timeout){
clearTimeout(timeout);
timeout = null;
}
previous = now;
fn.apply(context, args);
if(!timeout) context = args = null;
}else if(!timeout && options.trailing !== false){
timeout = setTimeout(later, remaining);
}
}
return throttled
}
var handleTouchStart = function(e){
var ele = e.touches[0] || e.changedTouches[0];
start = ele.pageY;
style.position = 'relative';
style.transition = 'transform 0s';
}
var handleTouchMove = function(e){
var ele = e.touches[0] || e.changedTouches[0];
transformHeight = ele.pageY - start;
if(transformHeight > 0 && transformHeight < offset){
refreshTip.innerText = '下拉刷新';
style.transform = 'translateY(' + transformHeight + 'px)';
if(transformHeight > 55){
refreshTip.innerText = '松开刷新';
}
}
}
var handleTouchEnd = function(e){
refreshTip.innerText = '更新中...';
var timeout = setTimeout(function(){
clearTimeout(timeout);
timeout = null;
style.transition = 'transform 0.5s ease';
style.transform = 'translateY(0px)';
location.reload();
}, 2000)
}
addEventListener('touchstart', handleTouchStart, false);
addEventListener('touchmove', handleTouchMove, false);
addEventListener('touchend', handleTouchEnd, false);
var removeListeners = function(){
removeEventListener('touchstart', handleTouchStart);
removeEventListener('touchmove', handleTouchMove);
removeEventListener('touchend', handleTouchEnd);
}
// 上拉加载更多
var fetch = function(){
setTimeout(function(){
refreshTarget.insertAdjacentHTML('beforeend', '<li>新增加的...</li>');
}, 1000)
}
var getClientHeight = function(){
var clientHeight = 0, bodyClientHeight = boby.clientHeight, dbodyClientHeight = dbody.clientHeight;
if(bodyClientHeight && dbodyClientHeight){
clientHeight = Math.min(bodyClientHeight, dbodyClientHeight);
}else{
clientHeight = Math.max(bodyClientHeight, dbodyClientHeight);
}
return clientHeight;
}
var getScrollTop = function(){
var scrollTop = 0;
if(dbody && dbody.scrollTop){ // if DTD
scrollTop = dbody.scrollTop;
}else if(boby){
scrollTop = boby.scrollTop;
}
return scrollTop;
}
var getScrollHeight = function(){
return Math.max(document.body.scrollHeight, dbody.scrollHeight);
}
window.onscroll = throttle(function(){
// 到底部了
if(getClientHeight() + getScrollTop() >= getScrollHeight()){
moreTip.innerText = '加载中...'
fetch();
}
}, 1000, {leading: false, trailing: true});
})(window)
</script>
</html>