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

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

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. java1.8对集合中对象的特有属性进行排序

    每天学习一点点,知识财富涨点点 1.创建对象user12 2.编写测试类 3.输出结果 加油!!!!

  2. docker compose的使用--在线安装未完成

    Compose 是一个用户定义和运行多个容器的 Docker 应用程序.在 Compose 中你可以使用 YAML 文件来配置你的应用服务.然后,只需要一个简单的命令,就可以创建并启动你配置的所有服务 ...

  3. CommandType.Text

    CommandType.Text代表执行的是SQL语句CommandType.StoreProcedure代表执行的是存储过程CommandType代表要执行的类型 //返回DataTable的SQL ...

  4. Imperative programming

    In computer science, imperative programming is a programming paradigm that uses statements that chan ...

  5. ZBrush中标准几何体与Polymesh

    通过对ZBrush的学习,相信您已经对这款软件有了一定的了解,文本我们主要学习ZBrush®的3D物体标准几何体的特性和使用方法.在ZBrush中只有Polymesh(多边形网格)物体才能使用雕刻笔刷 ...

  6. mmap详解

    共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式, 因为进程可以直接读写内存,而不需要任何 数据的拷贝.对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存 ...

  7. elment表格分页

    项目的时候遇到了一个分页的bug,经过分析Element源码之后找到了问题所在,现在把这个问题及解决方法记录下来. 项目中要实现的功能是用户选择查看表格的时候在任意页面点击查询,得到结果之后要展示的页 ...

  8. tensorflow的tf.train.Saver()模型保存与恢复

    将训练好的模型参数保存起来,以便以后进行验证或测试.tf里面提供模型保存的是tf.train.Saver()模块. 模型保存,先要创建一个Saver对象:如 saver=tf.train.Saver( ...

  9. zabbix_get 获取agnet端mysql数据失败

    问题 在使用zabbix_get获取agent端的mysql数据时,总是报错,ERROR 2002 (HY000): Can't connect to local MySQL server throu ...

  10. python的装饰器,迭代器用法

    装饰器. 装饰器实际就是一个函数 定义:在不改变内部代码和调用方式的基础上增加新的功能 了解装饰器需要了解3个内容: 1.函数即变量 2.高阶函数 1).把一个函数名当作实参传给另一个函数 2).返回 ...