最近要在手机端的HTML5里面实现一个类似新浪微博的“Pull & Refresh”的功能,时间紧迫,一时找不到比较好用的框架,发现Lungo还不错,于是试用了一下,发现还不错,轻量小巧。
Lungo很多函数与JQuery差不多,比如mix()、isOwnProperty()、toType(),另外因为我使用BootStrap,很多功能与Lungo重复,因此Lungo的很多组件我用不上,没有细致的研究。不过,最坑爹的是,我要用的Pull & Refresh它只支持从顶部下拉刷新,不支持从底部往上刷新!
好吧!暂时找不到其它框架,那就自己动手修改一下吧
由于Lungo的css与Bootstrap的css冲突了,没有全部引用Lungo的css,并且自己加了不少样式,所以单独出来,只包含Pull & Refresh的部分,代码如下:
/* Pull & Refresh */
body>section.show {
-webkit-box-ordinal-group: 2;
-moz-box-ordinal-group: 2;
-ms-box-ordinal-group: 2;
-o-box-ordinal-group: 2;
box-ordinal-group: 2;
display: -webkit-box;
display: -moz-box;
display: -ms-box;
display: -o-box;
display: box;
position: relative;
}
body>aside.show>article.active.pull,
body>section.show>article.active.pull,
body>aside.hide>article.active.pull,
body>section.hide>article.active.pull,
body>aside.hiding>article.active.pull,
body>section.hiding>article.active.pull
{
-webkit-transition-property: transform;
-moz-transition-property: transform;
-ms-transition-property: transform;
-o-transition-property: transform;
transition-property: transform;
-webkit-transition-duration: 500ms;
-moz-transition-duration: 500ms;
-ms-transition-duration: 500ms;
-o-transition-duration: 500ms;
transition-duration: 500ms
}
section.show>[data-control="pull"]>.loading {
position: relative;
width: 25px;
color: #ff8612;
font-size: 12px;
line-height: 1; /* 1倍行距,否则不能居边对齐 */
}
section.hide>[data-control="pull"] {
display: none
}
section.show>[data-control="pull"] {
position: absolute;
z-index: -1;
top: 0;
line-height: 60px;
width: 100%;
height: 80px;
padding: 10px 0;
text-align: center;
}
section.show>[data-control="pull"]>.icon {
display: inline-block;
width: 25px;
color: #ff8612;
font-size: 12px;
line-height: 1;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
-o-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-transition: all .2s ease-in-out;
-o-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
}
section.show>[data-control="pull"]>.loading {
display: none;
left: 0%
}
section.show>[data-control="pull"]>.msg {
position: relative;
color: #ff8612;
font-size: 12px;
font-weight: normal;
line-height: 1; /* 1倍行距,否则不能居边对齐 */
display: inline-block;
}
section.show>[data-control="pull"].rotate>.icon {
-webkit-transform: rotate(-180deg);
-moz-transform: rotate(-180deg);
-ms-transform: rotate(-180deg);
-o-transform: rotate(-180deg);
transform: rotate(-180deg);
-webkit-transition: all .2s ease-in-out;
-o-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
}
section.show>[data-control="pull"].refresh>.icon {
display: none
}
section.show>[data-control="pull"].refresh>.loading {
display: inline-block
}
section.show>[data-control="pull"].pulling-down {
top: 0;
bottom: auto;
}
section.show>[data-control="pull"].pulling-up {
top: auto;
bottom: 0;
}
section.show>[data-control="pull"].pulling-down .pullup.icon {
display: none;
}
section.show>[data-control="pull"].pulling-up .pulldown.icon {
display: none;
}
section.show>[data-control="pull"].pulling-down>.icon,
section.show>[data-control="pull"].pulling-down>.loading,
section.show>[data-control="pull"].pulling-down>.msg {
vertical-align: top;
}
section.show>[data-control="pull"].pulling-up>.icon,
section.show>[data-control="pull"].pulling-up>.loading,
section.show>[data-control="pull"].pulling-up>.msg {
vertical-align: bottom;
}
/* Pull & Refresh end */
然后,重新实现了Pull组件,要用的话可以将如下代码替换Lungo.js中与Pull相关的那部分,JavaScript代码如下:
/**
* Creates a instance of Pull & Refresh Element。<br>
* 增加功能:在原来的Pull Down & Refresh的基础上,支持Pull Up & Refresh。
*
* @namespace Lungo.Element
* @class Pull
* @version 1.0
*
* @author Ignacio Olalde <ina@tapquo.com> || @piniphone
* @author Javier Jimenez Villar <javi@tapquo.com> || @soyjavi
* @author fbchen <fbchen@fourbin.com>
*/
(function() {
// 修改loading的样式
Lungo.Attributes['loading'] = {
selector : "*",
html : '<span class="loading {{value}}"></span>'
};
Lungo.Attributes['pull'] = {
selector : "*",
html : '<div data-control="pull" data-icon="pulldown {{value}}" data-loading="fa fa-spinner fa-spin"><span class="msg"></span></div>'
};
Lungo.Element.Pull = function(element_selector, config_data) {
var ANIMATION_TIME, CONFIG_BASE, CONTAINER, CURRENT_DISTANCE, ELEMENT,
MAX_HEIGHT, REFRESHING, REFRESHING_HEIGHT, PULLING_DOWN,
hide, _blockGestures, _getTouchY, _handlePullEnd, _handlePulling, _moveElementTo,
_refreshStart, _setContainerLoading, _setContainerOnPulling, _setContainerTitle,
UP = void 0,
DOWN = void 0,
isOwnProp = Lungo.Core.isOwnProperty,
pullUpIcon;
REFRESHING_HEIGHT = 68;
MAX_HEIGHT = 80;
ANIMATION_TIME = 300;
CURRENT_DISTANCE = 0;
PULLING_DOWN = true;
REFRESHING = false;
ELEMENT = $$(element_selector);
CONTAINER = ELEMENT.siblings("div[data-control=\"pull\"]");
CONFIG_BASE = {
onPull : "Pull down to refresh",
onRelease : "Release to...",
onRefresh : "Loading...",
callback : void 0
};
// 分出pull down、pull up的配置,为了向后兼容,默认都是pull down
UP = Lungo.Core.mix(CONFIG_BASE, config_data['up']);
DOWN = Lungo.Core.mix(CONFIG_BASE, config_data['down']);
if (!isOwnProp(config_data, 'up') && !isOwnProp(config_data, 'down')) {
DOWN = Lungo.Core.mix(CONFIG_BASE, config_data);
}
// 注入data-pullup图标
pullUpIcon = UP.icon || ELEMENT.parent().data('pullup');
if (pullUpIcon) {
CONTAINER.prepend('<span class="pullup icon ' + pullUpIcon + '"></span>');
}
hide = function() {
_moveElementTo(0, true);
setTimeout((function() {
REFRESHING = false;
CONTAINER.attr("class", "");
return ELEMENT[0].removeEventListener("touchmove",
_blockGestures, true);
}), ANIMATION_TIME);
return CURRENT_DISTANCE = 0;
};
_moveElementTo = function(posY, animate) {
var newPos;
newPos = Math.abs(posY) > MAX_HEIGHT ? (posY < 0 ? -1 * MAX_HEIGHT : MAX_HEIGHT) : posY;
if (animate) {
ELEMENT.addClass("pull");
} else {
ELEMENT.removeClass("pull");
}
ELEMENT.style("-webkit-transform", "translate(0, " + newPos + "px)");
if (animate) {
return setTimeout((function() {
return ELEMENT.removeClass("pull");
}), ANIMATION_TIME);
}
};
_refreshStart = function(event) {
REFRESHING = true;
ELEMENT[0].addEventListener("touchmove", _blockGestures, true);
_setContainerTitle(_getConf().onRefresh);
_setContainerLoading(true);
_moveElementTo(PULLING_DOWN ? REFRESHING_HEIGHT : -1 * REFRESHING_HEIGHT, true);
if (_getConf().callback) {
return _getConf().callback.apply(this);
}
};
_setContainerTitle = function(title) {
return CONTAINER.find(".msg").html(title);
};
_setContainerLoading = function(op) {
_setContainerPosition();
if (op) {
return CONTAINER.addClass("refresh");
} else {
return CONTAINER.removeClass("refresh");
}
};
_setContainerOnPulling = function(op) {
_setContainerPosition();
if (op) {
return CONTAINER.addClass("rotate");
} else {
return CONTAINER.removeClass("rotate");
}
};
_setContainerPosition = function() {
if (PULLING_DOWN) {
CONTAINER.removeClass("pulling-up").addClass("pulling-down");
} else {
CONTAINER.removeClass("pulling-down").addClass("pulling-up");
}
}
_getConf = function() {
return PULLING_DOWN ? DOWN : UP;
};
_blockGestures = function(touchEvent) {
return touchEvent.preventDefault();
};
_handlePulling = function(event) {
_moveElementTo(PULLING_DOWN ? CURRENT_DISTANCE : -1 * CURRENT_DISTANCE, false);
_setContainerLoading(false);
if (CURRENT_DISTANCE > REFRESHING_HEIGHT) {
_setContainerTitle(_getConf().onRelease);
return _setContainerOnPulling(true);
} else {
_setContainerTitle(_getConf().onPull);
return _setContainerOnPulling(false);
}
};
_handlePullEnd = function(event) {
if (CURRENT_DISTANCE > REFRESHING_HEIGHT) {
_refreshStart();
} else {
hide();
}
return this;
};
_getTouchY = function(event) {
if ($$.isMobile()) {
return event.touches[0].pageY;
} else {
return event.pageY;
}
};
(function() {
var INI_Y, STARTED, dt;
STARTED = false;
INI_Y = 0;
return ELEMENT.bind("touchstart", function(event) {
if (ELEMENT[0].scrollTop <= 1) {
STARTED = true;
INI_Y = _getTouchY(event);
}
return true;
}).bind("touchmove", function(event) {
var current_y;
if (!REFRESHING && STARTED) {
current_y = _getTouchY(event);
dt = current_y - INI_Y;
PULLING_DOWN = dt > 0;
CURRENT_DISTANCE = Math.abs(dt);
_handlePulling(event);
if (event.cancelable !== false) {
event.preventDefault();
}
}
return true;
}).bind("touchend", function() {
if (STARTED) {
_handlePullEnd();
}
STARTED = false;
return true;
});
})();
return {
hide : hide
};
};
}).call(this);
最后是HTML测试页面,模拟手机端的“拖拽”功能,可以用Chrome打开,用浏览器自带的“开发者工具”,切换到Device模式调试。HTML页面如下:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pull & Refresh</title>
<!-- Bootstrap -->
<link type="text/css" rel="stylesheet" href="./js/bootstrap3.2/css/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="./css/font-awesome-4.2.0/css/font-awesome.min.css">
<link type="text/css" rel="stylesheet" href="./css/zyb/app.css">
<style type="text/css">
.article {
background-color: beige;
}
h1 {
background-color: azure;
margin-bottom: 0;
margin-top: 100px;
}
</style>
</head>
<body>
<h1>测试下拉刷新功能</h1>
<!-- 内容列表 -->
<section id="articleList" data-transition="slide" data-pull="fa fa-long-arrow-down" data-pullup="fa fa-long-arrow-up">
<article class="article">
<div title="下拉文章内容刷新">
文章内容<br>
文章内容<br>
文章内容<br>
文章内容<br>
</div>
</article>
</section>
<script type="text/javascript" src="./js/jquery/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="./js/bootstrap3.2/js/bootstrap.min.js"></script>
<!-- 支持 Pull & Refresh -->
<script type="text/javascript" src="./js/quojs-2.3.6/quo.js"></script>
<script type="text/javascript" src="./js/lungo-2.2.1/lungo-1.js"></script>
<script>
$(function(){
Lungo.init({});
var pull_example = new Lungo.Element.Pull('#articleList article', {
down: {
onPull: '下拉刷新', // Text on pulling
onRelease: '释放更新', // Text on releasing
onRefresh: '加载中...', // Text on refreshing
callback: function() { // Action on refresh
//alert('Pull & Refresh completed!');
setTimeout(function() {
pull_example.hide();
}, 3000);
}
},
up: {
onPull: '上推刷新', // Text on pulling
onRelease: '释放更新', // Text on releasing
onRefresh: '加载中...', // Text on refreshing
callback: function() { // Action on refresh
//alert('Pull & Refresh completed!');
setTimeout(function() {
pull_example.hide();
}, 3000);
}
}
});
});
</script>
</body>
</html>
效果如下:



本文介绍了一种在HTML5应用中实现自定义上下拉刷新的方法,通过对Lungo.js框架的扩展,支持了从底部向上刷新的功能。
1143

被折叠的 条评论
为什么被折叠?



