(function ($)
{
$.fn.extend({
loadmore: function (option)
{
var onMove = option.onMove || function () { }
var onRefresh = option.onRefresh || function () { }
var onLoadMore = option.onLoadMore || function () { }
var parent = $(this)
var child = parent.children()
var pointDownY = 0
var pointDownScrollTop = 0
var maxScrollTop = 0
var isTouchOrMouseDownStartFromChild = false
child.bind('mousedown touchstart', function (e)
{
if (e.type == 'touchstart')
{
pointDownY = e.originalEvent.changedTouches[0].clientY
}
else
{
pointDownY = e.clientY
}
maxScrollTop = GetHeightWithMargin(child) - parent.height()
maxScrollTop = maxScrollTop < 0 ? 0 : maxScrollTop
pointDownScrollTop = parent.scrollTop()
isTouchOrMouseDownStartFromChild = true
})
$(window).bind('mousemove touchmove', function (e)
{
e.preventDefault()
if (!isTouchOrMouseDownStartFromChild)
{
return
}
var y
if (e.type == 'touchmove')
{
y = e.originalEvent.changedTouches[0].clientY
}
else
{
if (e.buttons != 1)
{
return
}
else
{
y = e.clientY
}
}
var dy = pointDownY - y
var toScrollTop = 0
var toTransformY = 0
if (dy > 0)
{
var tempScrollTop = maxScrollTop - pointDownScrollTop
if (dy <= tempScrollTop)
{
toScrollTop = pointDownScrollTop + dy
}
else
{
toScrollTop = maxScrollTop
toTransformY = -1 * (dy - tempScrollTop)
}
}
else
{
if (-dy > pointDownScrollTop)
{
toScrollTop = 0
toTransformY = -dy - pointDownScrollTop
}
else
{
toScrollTop = pointDownScrollTop + dy
}
}
parent.scrollTop(toScrollTop)
var toTransform = 'translateY(' + toTransformY + 'px)'
child.css({
transform: toTransform
})
onMove(toTransformY)
})
$(window).bind('mouseup touchend', function (e)
{
var y
isTouchOrMouseDownStartFromChild = false
if (e.type == 'touchend')
{
y = e.originalEvent.changedTouches[0].clientY
}
else
{
y = e.clientY
}
var currentTransformTranslateY = GetTransformTranslateY(child)
if (currentTransformTranslateY > 50)
{
onRefresh(function ()
{
GoBack(0, pointDownY > y)
})
}
else if (currentTransformTranslateY < -50)
{
onLoadMore(function ()
{
GoBack(0, pointDownY > y)
})
}
else
{
GoBack(0, pointDownY > y)
}
})
function GetTransformTranslateY(el)
{
var transform = el.css('transform')
if (transform == 'none')
{
transform = '(0, 0, 0)'
}
return transform.split(',').reverse()[0].split(')')[0].trim() * 1
}
function GoBack(toTransformTranslateY, isLoadMore)
{
var fromTransformTranslateY = GetTransformTranslateY(child)
maxScrollTop = GetHeightWithMargin(child) - parent.height()
maxScrollTop = maxScrollTop < 0 ? 0 : maxScrollTop
if (fromTransformTranslateY != 0)
{
parent.scrollTop(isLoadMore ? maxScrollTop : 0)
}
var duration = 100
var interval = 5
var steps = duration / interval
var dsPerInterval = (toTransformTranslateY - fromTransformTranslateY) / steps
var si = setInterval(function ()
{
var currentTransformTranslateY = GetTransformTranslateY(child)
if (currentTransformTranslateY == toTransformTranslateY)
{
clearInterval(si)
}
else
{
var toTransform = ''
if (Math.abs(Math.abs(currentTransformTranslateY) - Math.abs(toTransformTranslateY)) <= Math.abs(dsPerInterval))
{
toTransform = 'translateY(' + toTransformTranslateY + 'px)'
}
else
{
toTransform = 'translateY(' + (currentTransformTranslateY + 1 * dsPerInterval) + 'px)'
}
child.css({
transform: toTransform
})
}
}, interval)
}
function GetHeightWithMargin(el)
{
return el.outerHeight() + el.css('margin-top').replace('px', '') * 1 + el.css('margin-bottom').replace('px', '') * 1
}
}
})
})(jQuery)
然后是demo
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1" />
<title>实验室</title>
</head>
<body>
纯文本
<div class="container container1">
<ul class="list1"></ul>
</div>
带图片
<div class="container container2">
<ul class="list2"></ul>
</div>
<style type="text/css">
.container { border: 1px solid black; height: 300px; overflow: hidden; }
img { max-width: 100%; }
</style>
<script type="text/javascript" src="./js/jquery-2.1.4.js"></script>
<script type="text/javascript" src="./js/jquery.loadmore.js"></script>
<script type="text/javascript">
for (var i = 1; i <= 10; i++)
{
$('ul.list1').append('<li>我是初始化的第' + i + '条数据</li>')
}
for (var i = 1; i <= 3; i++)
{
$('ul.list2').append('<li>我是初始化的第' + i + '条数据<a href="http://blog.csdn.net/u010655942/article/details/47093981">链接戳我</a><img src="http://avatar.csdn.net/3/6/7/1_u010655942.jpg" /></li>')
}
$('.container1').loadmore({
onMove: function (distance)
{
if (distance > 50)
{
console.log('Show refresh style')
}
else if (distance < -50)
{
console.log('Show load more style')
}
},
onLoadMore: function (callback)
{
setTimeout(function ()
{
for (var i = 0; i < 5; i++)
{
$('ul.list1').append('<li>我是新添加的第' + ($('ul.list1').children().length + 1) + '条数据</li>')
}
callback()
}, 500)
},
onRefresh: function (callback)
{
setTimeout(function ()
{
$('ul.list1').empty()
for (var i = 0; i < 10; i++)
{
$('ul.list1').append('<li>我是刷新后的第' + ($('ul.list1').children().length + 1) + '条数据</li>')
}
callback()
}, 500)
}
})
$('.container2').loadmore({
onMove: function (distance)
{
if (distance > 50)
{
console.log('Show refresh style')
}
else if (distance < -50)
{
console.log('Show load more style')
}
},
onLoadMore: function (callback)
{
setTimeout(function ()
{
for (var i = 0; i < 3; i++)
{
$('ul.list2').append('<li>我是新添加的第' + ($('ul.list2').children().length + 1) + '条数据<a href="http://blog.csdn.net/u010655942/article/details/47093981">链接戳我</a><img src="http://www2.res.meizu.com/zh_cn/images/mx5/features/banner2.png"/></li>')
}
callback()
}, 500)
},
onRefresh: function (callback)
{
setTimeout(function ()
{
$('ul.list2').empty()
for (var i = 0; i < 3; i++)
{
$('ul.list2').append('<li>我是刷新后的第' + ($('ul.list2').children().length + 1) + '条数据<a href="http://blog.csdn.net/u010655942/article/details/47093981">链接戳我</a><img src="http://www2.res.meizu.com/zh_cn/images/mx5/features/banner2.png"/></li>')
}
callback()
}, 500)
}
})
</script>
</body>
</html>