写在前面:本人水平有限,有什么分析不到位的还请各路大神指出,谢谢。

这次要写的东西是类似于<今日头条>的效果,下拉加载上啦加载,这次做的效果是简单的模拟,没有多少内容,下面是今日头条的移动端截图:

1. 先说一个题外话,拿到这个效果后,先分析了下,由于新闻分类很多,每个类目下都得有很多新闻,并且加载的时候得用ajax,所以得分清在哪个栏目下触发的加载,然后挑出相应的接口数据,插入到那个页面。

先分析一下:这个效果类似选项卡,但是简单的选项卡是把选项卡子内容全部写在文档内部(页面加载的时候会把所有的资源都加在进来),通过display:none/block;来控制显示,通过js处理可以达到下拉上拉加载的效果。但是这个新闻类页面图片资源比较多,在移动端加载大量资源会费时,费流量(不止自己的流量,服务器也需要流量),所以我们把这个项目下面的内容拆分为每个单页面。今日头条项目中每个类型在切换的时候都会先清空之前的内容,在重新插入,这个拆分单页面在类型切换,页面刷新时无疑会造成数据丢失,他们(每日头条开发者)的做法是吧数据写在了缓存里面(最下面有图,朋友们也可以自己去打开看看)。

开始写插件,插件结构如下:

;
(function($,window,document,undefined){//传值,多传的忽略
'use strict'//使用严格模式
//定义插件名称
var plugingName='slideDownRefresh',
defaults={
//默认 配置项 如果使用者不写自己加上
'width':'300px'
} // 属性:
function Plugin(element,options){
//element 为节点,options是执行的快慢,宽高呀配置项
//console.log(element);//测试是否正确
this.element = element;
// this.options = options;//得检测下看看 使用者是否佳丽参数
this.options = $.extend({},defaults,options);//如果options没有就用defaults,如果options有就把defaults的给替换
// console.log(this.options);
}
//方法:
Plugin.prototype={
init:function(){ },
eventHandle:function(){ }
}
// 把插件绑定到Zepto上:
$.fn[plugingName]=function(options){
return this.each(function(){//遍历匹配的元素,此处的this表示为jquery对象,而不是dom对象
// 因为 应该有多个地方用到这个插件
//zepto 的data与jquery的data有区别日后再说
if( !$(this).data('plugin_' + plugingName)) {
return $(this).data('plugin_'+plugingName,new Plugin(this,options))
}
})
}
})(Zepto,window,document);

接下来补充插件的事件等:

;
(function($,window,document,undefined){//传值,多传的忽略
'use strict'//使用严格模式
//定义插件名称
var plugingName = 'slideDownRefresh',
defaults = {
//默认 配置项 如果使用者不写自己加上
'width':'300px'
}
// 属性:
function Plugin(element,options){
//element 为节点,options是执行的快慢,宽高呀配置项
//console.log(element);//测试是否正确
this.element = element;
// this.options = options;//得检测下看看 使用者是否佳丽参数
this.options = $.extend({},defaults,options);//如果options没有就用defaults,如果options有就把defaults的给替换
// console.log(this.options); // 执行以下,初始化调用一下
this.init();
this.eventHandle();
}
//方法:
Plugin.prototype = {
init: function(){
this.$refresh = $(this.element).find('.refresh');//找到标签
this.$rotate = $(this.element).find('img');//找到旋转标签
this._start = ;//旋转的初始值
this._end = ;//旋转的结束值
}, // 事件主要为移动端touch事件,下面会写到,不懂得可以取查阅资料
eventHandle: function(){
this.touchStart(this.element);
},
touchStart: function(ele){
var _self=this;//把this存起来,不用来回反复取(节约性能);
$(ele).on('touchstart', function(e){
var touch = e.targetTouches[];//只允许一个手指触碰
_self._start = touch.pageY;//获取点上去时的纵坐标
_self.touchMove(_self.element);//调用移动方法
})
},
touchMove: function(ele){
var _self=this;//把this存起来,不用来回反复取(节约性能);
$(ele).on('touchmove', function(e){
var touch = e.targetTouches[];//只允许一个手指触碰
_self._end = _self._start - touch.pageY;//获取移动的纵坐标距离
_sliding.call(_self,_self._end);
//这里之所以不用_sliding.()调用是因为,这样传的this为touchmove的this,而我们要的this为:_self
_self.touchEnd(_self.element);
});
// 写个私有方法
function _sliding(dist){
// dist为距离
_self.$refresh.css('transform', 'translate3d(0,'+ -dist + 'px, 0)');//拿到结点 写动画
_self.$rotate.css('transform','rotate('+ (-dist * ) + 'deg)');//让load转起来这里的4只是随便写的,可以任意写,怎么好看怎么写
}
},
touchEnd: function(ele){
var _self=this;//把this存起来,不用来回反复取(节约性能);
$(ele).on('touchend', function(e){
if(_self._end < -){
// 这个数字可以随便设置 成功时
_slided.call(_self);
setTimeout(function(){
_reset.call(_self);
},);
}else{
//距离不够
_noslide.call(_self);
}
// 事件全部执行完以后,把事件全部移除
$(this).unbind('touchmove');
$(this).unbind('touchend');
});
function _slided(){// 下拉,然后松开,然后执行
_self.$refresh.addClass('refreshing');
_self.$rotate.addClass('index');
};
// 下滑距离不够时,复原 但是不算新
function _noslide(){
_self.$refresh.addClass('refreshing');
_self.$rotate.addClass('index');
_self.$refresh.css('transform', 'translate3d(0,0,0)');
_self.$rotate.css('transform', 'rotate(0deg)');
// 移除加的class
setTimeout(function(){
_self.$refresh.removeClass('refreshing');
_self.$rotate.removeClass('index');
},);
};
// 刷新完成,回到原来状态
function _reset(){
_self.$refresh.css('transform', 'translate3d(0,0,0)');
_self.$rotate.css('transform', 'rotate(0deg)'); setTimeout(function(){
_self.$refresh.removeClass('refreshing');
_self.$rotate.removeClass('index');
// window.location.reload(); //刷新页面,或者执行ajax 调取数据 // 调用数据
$.ajax({
url:,
data:url,
success:function(data){
var list=defaults.redenr(data);
$("...").append(list);
}
})
},);
}
}
}
// 把插件绑定到Zepto上:
$.fn[plugingName] = function(options){
return this.each(function(){//遍历匹配的元素,此处的this表示为jquery对象,而不是dom对象
// 因为 应该有多个地方用到这个插件
//zepto 的data与jquery的data有区别日后再说
if( !$(this).data('plugin_' + plugingName)){
return $(this).data('plugin_' + plugingName, new Plugin(this,options))
}
})
}
})(Zepto,window,document);

调用代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>基于Zepto移动端下拉刷新(加载),上拉加载插件开发</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0,minimum-scale=1.0, maximum-scale=1.0,user-scalable=no">
<style>
*{
padding:;
margin:;
}
a{
text-decoration: none;
}
li{
list-style: none;
}
header{
width:%;
height: 40px;
line-height: 40px;
position: fixed;
top:;
left: ;
background: #fff;
z-index: ;
}
header li{
display: inline-block;
width:%;
}
header li a{
text-align: center;
width: %;
display: block;
color:#;
height: 40px;
}
.refresh{
width: %;
position: absolute;
text-align: center;
}
.refresh img{
width: 40px;
}
.warp{
width: %;
clear: both;
}
.refreshing{
transition: all .5s ease-in-out;
-webkit-transition: all .5s ease-in-out;
}
.refresh img.index{
-webkit-animation:today 3s infinite;
animation:today 3s infinite;
}
@keyframes today{
%{
transform:rotate(0deg);
}
%{
transform:rotate(-2000deg);
}
}
@-webkit-keyframes today{
%{
-webkit-transform:rotate(0deg);
}
%{
-webkit-transform:rotate(-2000deg);
}
}
</style>
</head>
<body>
<div class="warp">
<header>
<ul>
<li><a href="#tuijian" class="tuijian">推荐</a></li>
<li><a href="#junshi" class="junshi">军事</a></li>
<li><a href="#jingji" class="jingji">经济</a></li>
<li><a href="#shehui" class="shehui">社会</a></li>
</ul>
</header>
<div class="refresh">
<img src="img/re.png" alt="">
</div>
<section id="content">
<li>测试内容</li>
<li>测试内容</li>
</section>
</div> </body>
<script src="http://apps.bdimg.com/libs/zepto/1.1.4/zepto.js"> </script>
<script src="js/myDemo.js"></script>
<script>
$('.warp').slideDownRefresh({
'width':'800px',
'url':,//这个url 为要添加新数据的url
redenr:function(data){
//在这里拼接页面
var list=null;
return list;
}
}); </script>
</html>

总结:这个插件只是写了下拉,上啦加载的可以在 touchEnd 函数中判断是上滑还是下滑来判断加载。 本插件在单页中没什么问题,要是放在 今日头条这样的项目中就得补充插件内容了。

分析今日头条:今日头条的每个新闻项目的切换 相应的url也会变化,项目来回切换的时候 各种新闻数据还是不变的,即便F5刷新 各个新闻数据还是不变的。于是我找了下缓存还有发现了新闻的缓存。

所以本插件还得添加一个功能:把拿来的数据添加到缓存中。 类似的还有《微信热文》也是这个原理实现的。

欢迎大家指出问题,项目下载地址https://github.com/WangMaoling/refresh

基于Zepto移动端下拉加载(刷新),上拉加载插件开发的更多相关文章

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

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

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

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

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

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

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

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

  5. listview下拉刷新上拉加载扩展(三)-仿最新版美团外卖

    本篇是基于上篇listview下拉刷新上拉加载扩展(二)-仿美团外卖改造而来,主要调整了headview的布局,并加了两个背景动画,看似高大上,其实很简单: as源码地址:http://downloa ...

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

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

  7. MaterialRefreshLayout+ListView 下拉刷新 上拉加载

    效果图是这样的,有入侵式的,非入侵式的,带波浪效果的......就那几个属性,都给出来了,自己去试就行. 下拉刷新 上拉加载 关于下拉刷新-上拉加载的效果,有许许多多的实现方式,百度了一下竟然有几十种 ...

  8. react-native-page-listview使用方法(自定义FlatList/ListView下拉刷新,上拉加载更多,方便的实现分页)

    react-native-page-listview 对ListView/FlatList的封装,可以很方便的分页加载网络数据,还支持自定义下拉刷新View和上拉加载更多的View.兼容高版本Flat ...

  9. mui下拉刷新上拉加载

    新外卖商家端主页订单大厅页面 使用mui双webview,实现下拉刷新上拉加载 主页面: order_index.html <!doctype html> <html> < ...

随机推荐

  1. 4.QList

    #include "mainwindow.h" #include <QApplication> #include <QLabel> #include < ...

  2. 在centos上面开机自启动某个程序

    Systemd 是 Linux 系统工具,用来启动守护进程,已成为大多数发行版的标准配置.可以通过 systemctl --version 命令来查看使用的版本 常用命令 # 立即启动一个服务 $ s ...

  3. C#对 Json的序列化和反序列化时出现“k_BackingField”

    在C#2.0的项目中,以前经常使用Json.NET实现序列化和反序列化.后来从c#3.0中开始使用新增的DataContractJsonSerializer进行json相关的操作.微软提供的原生类库使 ...

  4. Linux 系列- 基本命令

    Linux 基本命令 转自:http://www.taobaotest.com/blogs/qa?bid=353 Linux是一个基于命令的系统,它有很多很强的命令. 但它也有桌面系统,比如KDE, ...

  5. Oracle学习系类篇(四)

    .分析函数 分析函数oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组,然后计算基于组的邹忠统计值,并且每一组的每一行都可以返回一个统计值. 分析函数和聚合函数的不同之处 ...

  6. ifame子页实现父页面刷新(或跳转到指定页面)

    <script>parent.location.replace('../D_DailyManager/Add.aspx?id=" + x + "');</scri ...

  7. vue项目踩坑-引入bootstrap

    1.下载jquery; npm install jquery --save-dev 2.在webpack.base.conf.js中添加如下内容: var webpack = require('web ...

  8. 让html页面不缓存js的实现方法

    很多朋友都会碰到这样的情况:如果我们页面加载了js的话下次打开时也会是调用这个js缓存文件,但对于我们调试时是非常的不方便了,本文就来谈论如何解决这一问题,下面一起来看看. 不缓存JS的方法其实挺简单 ...

  9. maridb Error 'Operation DROP USER failed for

    数据库版本:mariadb   10.0.12 主库删除多余的用户名,因从库没有此信息造成主从故障! 报错信息如下:Error 'Operation DROP USER failed for 'use ...

  10. POJ 1328 Radar Installation 【贪心 区间选点】

    解题思路:给出n个岛屿,n个岛屿的坐标分别为(a1,b1),(a2,b2)-----(an,bn),雷达的覆盖半径为r 求所有的岛屿都被覆盖所需要的最少的雷达数目. 首先将岛屿坐标进行处理,因为雷达的 ...