vuxmint loadmoree怎么监控滑动到底部

jq滚动到底部自动加载数据实例
我的图书馆
jq滚动到底部自动加载数据实例
一、功能描述:下拉到页面底部加载数据是很多瀑布流网站的做法,本实例是固定数据,小菜总结记录之用,高手勿喷。首先要先判断页面怎么样才是滚动到底部,也就是scrollTop+window的height是否大于document的 height,如下代 码:Js代码&$(window).scrollTop()+$(window).height()&=$(document).height();&&再给window绑定scroll事件来实现加载数据显示。本实例的主要是提供版使用所以使用了的旋转模拟图片加载效果。在实例中实现了自动判断是否已经具备事件的条件,如果高度不足自动补充下一页,直接满足滚动事件能有效执行,如果已经加载完所有内容,就提示:【Duang~到底了】二、效果图如下:三、源代码如下:Html代码&&!DOCTYPE&HTML&&&&&&&http-equiv="Content-Type"&content="text/&charset=utf-8"&&&content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,minimal-ui"&name="viewport"&&jq滚动到底部自动加载|幸凡学习网&&&&&&&&&&&&&&html,body,ul,li{margin:0;padding:0;border:0;vertical-align:}&&&&&&&&&&body,html{line-height:1;font-family:"Microsoft&YaHei",Arial,Helvetica,sans-font-size:16color:#333;}&&&&&&&&&&ol,ul{list-style:}&&&&&&&&&&a{text-decoration:}&&&&&&&&&&body{background:#f2f2f2;}&&&&&&&&&&.prolist&li{height:50line-height:50border-bottom:1px&solid&#f8f8f8;background:#padding:0&15text-overflow:overflow:white-space:}&&&&&&&&&&.prolist&li&a{color:#333;font-size:16}&&&&&&&&&&&&&&&&&&&&/**加载效果旋转**/&&&&&&&&&&@-webkit-keyframes&rotate&{0%&{-webkit-transform:&rotate(0deg);transform:&rotate(0deg);}100%&{-webkit-transform:&rotate(360deg);transform:&rotate(360deg);}}&&&&&&&&&&@keyframes&rotate&{0%&{-webkit-transform:&rotate(0deg);transform:&rotate(0deg);}100%&{-webkit-transform:&rotate(360deg);transform:&rotate(360deg);}}&&&&&&&&&&&&&&&&&&&&.loadmore&{display:line-height:&50text-align:color:#font-size:14}&&&&&&&&&&.loadmore&span{height:20width:20border-radius:100%;display:inline-margin:10border:2px&solid&#f60;border-bottom-color:&vertical-align:&-webkit-animation:&rotate&1.1s&infinite&animation:&rotate&1.1s&infinite&}&&&&&&&&&&.loadover{position:margin:0&12padding:24px&0;height:20line-height:20color:#909090;text-align:&}&&&&&&&&&&.loadover&span{position:display:inline-padding:0&6height:20background:#F2F2F2;z-index:2}&&&&&&&&&&.loadover:after&{content:''position:&left:&0;top:50%;width:&100%;height:1background:#DCDCDC;z-index:1;display:}&&&&&&&&&&&&&&&class="prolist"&&&&&&&href="http://www.86y.org/art_detail.aspx?id=744"好经典人生语句,经典得让人心痛!&&&&&&&href="http://www.86y.org/art_detail.aspx?id=744"好经典人生语句,经典得让人心痛!&&&&&&&href="http://www.86y.org/art_detail.aspx?id=744"好经典人生语句,经典得让人心痛!&&&&&&&href="http://www.86y.org/art_detail.aspx?id=744"好经典人生语句,经典得让人心痛!&&&&&&&href="http://www.86y.org/art_detail.aspx?id=744"好经典人生语句,经典得让人心痛!&&&&&&&href="http://www.86y.org/art_detail.aspx?id=744"好经典人生语句,经典得让人心痛!&&&&&&&href="http://www.86y.org/art_detail.aspx?id=744"好经典人生语句,经典得让人心痛!&&&&&&&href="http://www.86y.org/art_detail.aspx?id=744"好经典人生语句,经典得让人心痛!&&&&&&&href="http://www.86y.org/art_detail.aspx?id=744"好经典人生语句,经典得让人心痛!&&&&&&&href="http://www.86y.org/art_detail.aspx?id=744"好经典人生语句,经典得让人心痛!&&&&&&&&&type="text/javascript"&src="http://www.86y.org/js/jquery.min.js"&&&&var&page=1;&&var&finished=0;&&var&sover=0;&&&&//如果屏幕未到整屏自动加载下一页补满&&var&setdefult=setInterval(function&(){&&&&&&if(sover==1)&&&&&&&&&&clearInterval(setdefult);&&&&&&&&&else&if($(".prolist").height()$(window).height())&&&&&&&&&&loadmore($(window));&&&&&&else&&&&&&&&&&clearInterval(setdefult);&&},500);&&&&//加载完&&function&loadover(){&&&&&&if(sover==1)&&&&&&{&&&&&&&&&&&&&var&overtext="Duang~到底了";&&&&&&&&&&$(".loadmore").remove();&&&&&&&&&&if($(".loadover").length0)&&&&&&&&&&{&&&&&&&&&&&&&&$(".loadover&span").eq(0).html(overtext);&&&&&&&&&&}&&&&&&&&&&else&&&&&&&&&&{&&&&&&&&&&&&&&var&txt='&div&class="loadover"&&span&'+overtext+''&&&&&&&&&&&&&&$("body").append(txt);&&&&&&&&&&}&&&&&&}&&}&&&&//加载更多&&var&vid=0;&&function&loadmore(obj){&&&&&&if(finished==0&&&&sover==0)&&&&&&{&&&&&&&&&&var&scrollTop&=&$(obj).scrollTop();&&&&&&&&&&var&scrollHeight&=&$(document).height();&&&&&&&&&&var&windowHeight&=&$(obj).height();&&&&&&&&&&&&&&&&&&&&if($(".loadmore").length==0)&&&&&&&&&&{&&&&&&&&&&&&&&var&txt='&div&class="loadmore"&&span&class="loading"&&/span&加载中..&/div&'&&&&&&&&&&&&&&$("body").append(txt);&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&if&(scrollTop&+&windowHeight&-scrollHeight=50&)&{&&&&&&&&&&&&&&//此处是滚动条到底部时候触发的事件,在这里写要加载的数据,或者是拉动滚动条的操作&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//防止未加载完再次执行&&&&&&&&&&&&&&finished=1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&var&result&=&"";&&&&&&&&&&&&&&for(var&i&=&0;&i&&;&i++){&&&&&&&&&&&&&&&&&&vid++;&&&&&&&&&&&&&&&&&&result+=''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&+'&href="http://www.86y.org/art_detail.aspx?id=744"好经典人生语句,经典得让人心痛!'+parseInt(vid)+''&&&&&&&&&&&&&&&&&&&&&&&&&&+''&&&&&&&&&&&&&&}&&&&&&&&&&&&&&setTimeout(function(){&&&&&&&&&&&&&&&&&&//$(".loadmore").remove();&&&&&&&&&&&&&&&&&&$('.prolist').append(result);&&&&&&&&&&&&&&&&&&page+=1;&&&&&&&&&&&&&&&&&&finished=0;&&&&&&&&&&&&&&&&&&//最后一页&&&&&&&&&&&&&&&&&&if(page==10)&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&sover=1;&&&&&&&&&&&&&&&&&&&&&&loadover();&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&},1000);&&&&&&&&&&&&&&/*$.ajax({&&&&&&&&&&&&&&&&&&type:&'GET',&&&&&&&&&&&&&&&&&&url:&'json/more.json?t=25&page='+page,&&&&&&&&&&&&&&&&&&dataType:&'json',&&&&&&&&&&&&&&&&&&success:&function(data){&&&&&&&&&&&&&&&&&&&&&&if(data=="")&&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&sover&=&1;&&&&&&&&&&&&&&&&&&&&&&&&&&loadover();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if&(page&==&1)&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$("#no_msg").removeClass("hidden");&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$(".loadover").remove();&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&var&result&=&''&&&&&&&&&&&&&&&&&&&&&&&&&&for(var&i&=&0;&i&&;&i++){&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&result+=''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&+'&href="'+data.lists[i].link+'"'+data.lists[i].title+parseInt(page+1)+"-"+i+''&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&+''&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//&为了测试,延迟1秒加载&&&&&&&&&&&&&&&&&&&&&&&&&&setTimeout(function(){&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$(".loadmore").remove();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&$('.prolist').append(result);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&page+=1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&finished=0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//最后一页&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&if(page==10)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sover=1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&loadover();&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&&},1000);&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&},&&&&&&&&&&&&&&&&&&error:&function(xhr,&type){&&&&&&&&&&&&&&&&&&&&&&alert('Ajax&error!');&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&});*/&&&&&&&&&&}&&&&&&}&&}&&//页面滚动执行事件&&$(window).scroll(function&(){&&&&&&loadmore($(this));&&});&&&&&&&&DEMO地址:(建议使用手机打开效果更佳)
TA的最新馆藏
喜欢该文的人也喜欢在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
标签:至少1个,最多5个
如今移动端站点越来越多,滚动到底部加载数据和下拉刷新的需求非常的常见,即使现在很多pc站点也会有这样的需求,比如百度首页就有。虽然简单的完成这么一个功能非常方便,但是滚动往往会成为性能的瓶颈,处理不好滚动很有可能会不流畅。既然很多页面和项目都需要,当然最需要有一个复用性高的插件。但是我却一直没找到特别好用的插件,有些需要依赖jquery,但貌似编写这样的插件时jquery并没有带来任何的便利。
Scrollload.js介绍
Scrollload是一个无依赖,体积极小(压缩+gzip后不到3k),可配置性高(可以自定义加载时候动画,加载完后的dom,提前加载的距离),可扩展性强大(很方便做到指定容器内的滚动,多tab的滚动,异常处理,刷新重新加载等),性能好(在滚动的时候做了一些性能优化,如缓存window的高度,函数节流)的js插件。源码地址:
解决的痛点
无依赖,配置简单,有多套滚动加载效果可选(需要单独引入对应的css,当然也有默认效果)
支持下拉刷新
在ios中,全局滚动会有很多不好的体验,我认为是可以用局部滚动来替代全局的。局部滚动也会有几个坑,但都是可解决的,也就是说全局滚动的坑目前还很难解决。该插件内置局部滚动坑的解决方案,方便使用局部滚动替代全局滚动且无副作用。具体见。
不支持ie8及以下浏览器。
——复杂示例
npm install scrollload --save
如果你没有用模块管理,
直接从window对象下取Scrollload对象也是可以的,打包后的js放在lib目录下,可以直接用script标签引入
同时支持模块引入
import Scrollload from 'Scrollload'
//commonjs
const Scrollload = require('Scrollload').default
当然也支持amd,不过我没用过。
真正用起来也非常简单。记住一点。插件会把底部DOM插入到container最后一个子节点之后。
你的dom结构是以下这样的
&div class="scrollload-container"&
&ul class="scrollload-content"&
插件会把底部DOM就会被插在ul标签的后面。你可以按照你以前的方式操作dom。demo中我都是用这种方式来做的。
下面是js中的使用。
let page = 1
new Scrollload({
// container 和 content 两个配置的默认取的scrollload-container和scrollload-content类的dom。只要你按照以上的dom结构写,这两个配置是可以省略的
container: document.querySelector('.scrollload-container'),
content: document.querySelector('.scrollload-content'),
loadMore: function(sl) {
if (page === 6) {
// 没有数据的时候需要调用noMoreData
sl.noMoreData()
// 我这里用jquery的不是因为需要jquery,只是jquery的语法看起来比较简单。大家都认识。
// 如果你不是用jquery,可以看看原生的insertAdjacentHTML方法来替代append
type: 'GET',
url: `http://rap.taobao.org/mockjsdata/14522/getgamelist?page=${page++}`,
dataType: 'json',
success: function(data){
// contentDom其实就是你的scrollload-content类的dom
$(sl.contentDom).append(data)
// 处理完业务逻辑后必须要调用unlock
sl.unLock()
error: function(xhr, type){
// 加载出错,需要执行该方法。这样底部DOM会出现出现异常的样式。
sl.throwException()
// 你也可以关闭下拉刷新
enablePullRefresh: true,
pullRefresh: function (sl) {
type: 'GET',
url: `http://rap.taobao.org/mockjsdata/14522/getgamelist?page=1`,
dataType: 'json',
success: function(data){
$(sl.contentDom).prepend(data)
// 处理完业务逻辑后必须要调用refreshComplete
sl.refreshComplete()
// 以下是配置参数及其默认内容
container: document.querySelector('.scrollload-container'),
// 列表内容
content: container.querySelector('.scrollload-content'),
// 视窗(默认是window,如果是局部滚动需要设置滚动的dom)
window: window,
// 是否开启加载更多(默认开启,如果关闭则滚动到底部则不再出现加载更多)
enableLoadMore: true,
// 初始化的时候是否锁定,锁定的话则不会去加载更多。由于这个插件实例化后默认是没有锁定的所以会去调用loadMore,但其实在多个tab的情况下是不应该一实例化完后就去调用的。所以有了这个参数。
isInitLock: false,
// 阀值 (滚动到底部提前加载的距离)
threshold: 10,
// 修复局部滚动的两个坑。参见ios局部滚动的坑及解决方案 /p/
useLocalScrollFix: false,
useScrollFix: false,
// 底部加载中的html
loadingHtml: generateHtml('加载中...'),
// 底部没有更多数据的html
noMoreDataHtml: generateHtml('没有更多数据了'),
// 底部出现异常的html
exceptionHtml: generateHtml('出现异常'),
// 加载更多的回调
loadMore: noop,
// 是否开启下拉刷新
enablePullRefresh: false,
// 顶部下拉刷新的html
notEnoughRefreshPortHtml: generateHtml('下拉刷新'),
// 顶部松开刷新的html
overRefreshPortHtml: generateHtml('松开刷新'),
// 顶部正在刷新的html
refreshingHtml: generateHtml('正在刷新'),
// 下拉刷新的回调
pullRefresh: noop,
// 到达刷新点的回调(包括向上和向下,可以通过isMovingDown判断方向)
arrivedRefreshPortHandler: noop,
// 开始滑动的回调
touchStart: noop,
// 滑动时的回调
touchMove: noop,
// 滑动中松开手指的回调
touchEnd: noop,
// 超过可刷新位置后的监听函数
overRefreshPortHandler: noop,
// 未超过可刷新位置前的监听函数
notEnoughRefreshPortHandler: noop,
// 计算下拉的阻力函数
calMovingDistance(start, end) {
return (end - start) / 3
// 实例化完后的回调
initedHandler: noop
lock(): 锁定后不会调用loadMore方法
unLock(): 每次滚动到底部都会锁定,所以你在loadMoreFn方法中需要解锁,下次滚动到底部才能继续调用loadMoreFn
noMoreData(): 当你的数据全部加载完后调用这个方法,将显示没有更多数据的div,你也可以配置这个div,用noMoreDataHtml配置参数
refreshData(): 当你调用完noData方法后,如果你想刷新当前的数据重新加载就要调用这个方法
throwException(): 出现异常需要调用这个方法,会在底部DOM中出现相应的样式
solveException(): 当你的异常问题解决后需要调用这个方法可以继续加载数据
refreshComplete(): 下拉刷新的时候你去请求完数据后需要调用这个函数通知我。我就可以把正在刷新的状态改成刷新完成。
getOptions(): 获取配置
setOptions(obj): 修改配置。obj和new Scrollload()的第二个参数一样的格式。
setGlobalOptions(obj): 全局配置,一次配置多次时候。调用这个方法和之前的方法不一样。之前的都需要对象实例化后才能调用。这个方法直接Scrollload构造函数上调用。Scrollload.setGlobalOptions()。接受的参数和setOptions方法一样
bottomDom: 底部DOM,包裹着加载中动画和没有更多数据的dom对象
isLock: 是否为锁定状态
hasMoreData: 是否还有更多数据,默认为true,调用noData方法后为false
container: 你传进来的container
content: 你传进来的content
win: 你传进来的window
isMovingDown: 下拉刷新的时候你滑动的方向
isRefreshing: 下拉刷新的时候你是否在刷新中
distance: 下拉刷新的时候你滑动的dom移动的距离,不是你手指移动的距离。这两者的关系可以通过calMovingDistance计算
如果你有好的加载更多动画的效果,可以在loading-demos文件夹下写一些自己的demo,loading的css必须是loading.css,并在头部加入loadingHtml的dom结构。,然后提一个pr给我。
当然用的时候有什么建议都可以和我提,有什么不懂得也可以和我提。任何形式和我提都可以。
0 收藏&&|&&14
你可能感兴趣的文章
21 收藏,234
4 收藏,503
11 收藏,1.3k
本作品 保留所有权利 。未获得许可人许可前,不允许他人复制、发行、展览和表演作品。不允许他人基于该作品创作演绎作品
分享到微博?
我要该,理由是://页面滚到底部异步加载下一页数据
$(window).scroll(function () {
//已经滚动到上面的页面高度
var scrollTop = parseFloat($(this).scrollTop()),
//页面高度
scrollHeight = $(document).height(),
//浏览器窗口高度
windowHeight = parseFloat($(this).height()),
totalHeight = scrollTop + windowH
//此处是滚动条到底部时候触发的事件,在这里写要加载的数据,或者是拉动滚动条的操作
if (scrollTop + windowHeight &= scrollHeight - <span style="color: #.7) {
//一级分类
var first = $("#h_first").val(),
//二级分类
second = $("#h_second").val(),
num = parseInt($("#pageNum").val()),
num = num + <span style="color: #;
$("#pageNum").attr('value', num);
type: 'post',
url: '/MicroPortal/ContentListForNotice?f=' + first + '&s=' + second + '&t=&PageIndex=' + num,
beforeSend: function (XMLHttpRequest) {
$("#loadMore").removeClass('hidden').text('正在加载数据...');
success: function (data) {
if (data.length == <span style="color: #) {
$("#loadMore").removeClass('hidden').text('已加载全部数据!');
var data = getTime(data);
for (var i = <span style="color: #, length = data. i & i++) {
$("#infoList").append("&li&&a href='public_content.html?id=" + data[i].Id + "&f=" + first + "&s=" + second + "'&&span&" + data[i].Title + "&/span&&span class='time'&" + data[i].PublishTime + "&/span&&/a&&/li&");
error: function (XMLHttpRequest, textStatus, errorThrown) {
$("#loadMore").removeClass('hidden').text('数据加载失败,请重试!');
阅读(...) 评论()vue mint-ui源码解析之loadmore组件 - CSDN博客
vue mint-ui源码解析之loadmore组件
官方接入文档
接入使用Example
:top-method="loadTop" :bottom-method="loadBottom" :bottom-all-loaded="allLoaded" :max-distance="150"
@top-status-change="handleTopChange" ref="loadmore"&
slot="top" class="mint-loadmore-top"&
v-show="topStatus === 'pull'" :class="{ 'rotate': topStatus === 'drop' }"&↓&
v-show="topStatus === 'loading'"&Loading...&
v-show="topStatus === 'drop'"&释放更新&
class="scroll-wrapper"&
v-for="item in list" @click="itemClick(item)"&{{ item }}&
& ="" ="://.com///.css"&
margin: 0;
padding: 0;
height: 100%;
height: 100%;
overflow: scroll;
.scroll-wrapper{
margin: 0;
padding: 0;
list-style: none;
.scroll-wrapper {
line-height: 120px;
font-size: 60px;
text-align: center;
&!-- 先引入 Vue --&
src="/vue/dist/vue.js"&&
src="/mint-ui/lib/index.js"&&
el: '#app',
allLoaded: false,
topStatus: ''
created: function () {
var i =0, len=20;
for (; i& i++){
this.list.push('demo' + i);
methods: {
loadTop: function () {
var self = this;
setTimeout(function () {
self.list.splice(0, self.list.length);
var i =0, len=20;
for (; i& i++){
self.list.push('demo' + i);
self.$refs.loadmore.onTopLoaded();
loadBottom: function () {
var self = this;
setTimeout(function () {
var i =0; len = 10;
for (; i& i++){
self.list.push('dddd' + i);
self.$refs.loadmore.onBottomLoaded();
handleTopChange: function (status) {
this.topStatus =
itemClick: function (data) {
console.log('item click, msg : ' + data);
实现原理解析
loadmore组件内部由三个slot组成,分别为name=top,name=bottom,default;
top用于展示下拉刷新不同状态展示的内容,初始设置margin-top为-top的高度来将自己隐藏
bottom同top,用于展示上拉加载更多不同状态展示的内容
default填充滚动详细内容
主要是通过js的touch事件的监听来实现
在touchmove事件,如果是向下滑动并且滚动的dom的scrollTop为0,那么整个组件向下偏移(滑动的距离/比值)展示出top solt的内容
在touchmove时间,如果是向上滑动并且滑动到了底部,再继续滑动整个组件向上偏移(滑动的距离/比值)展示出bottom solt的内容
组件的template html
class="mint-loadmore"&
class="mint-loadmore-content" :class="{ 'is-dropped': topDropped || bottomDropped}" :style="{ 'transform': 'translate3d(0, ' + translate + 'px, 0)' }"&
name="top"&
class="mint-loadmore-top" v-if="topMethod"&
v-if="topStatus === 'loading'" class="mint-loadmore-spinner" :size="20" type="fading-circle"&&
class="mint-loadmore-text"&{{ topText }}&
name="bottom"&
class="mint-loadmore-bottom" v-if="bottomMethod"&
v-if="bottomStatus === 'loading'" class="mint-loadmore-spinner" :size="20" type="fading-circle"&&
class="mint-loadmore-text"&{{ bottomText }}&
关于 上面的spinner标签,是一个组件,这里不做详细介绍。top solt和bottom slot中的内容是展示的内容,可以通过外部自定义的方式传入。
其实它的实现有一个很严重的弊端,就是写死了top solt和bottom slot的高度为50px,而且js中的处理也是使用50px进行的逻辑处理。所以并满足我们开发中自定义top slot 和bottom slot的需求。
js核心解析
关于props的解析,可以参考mint-ui的官方文档
translate: 0,
scrollEventTarget: null,
containerFilled: false,
topText: '',
topDropped: false,
bottomText: '',
bottomDropped: false,
bottomReached: false,
direction: '',
startY: 0,
startScrollTop: 0,
currentY: 0,
topStatus: '',
bottomStatus: ''
上面的关于每个data数据的具体作用通过注释做了详细说明。
topStatus(val) {
this.$emit('top-status-change', val);
switch (val) {
case 'pull':
this.topText = this.topPullT
case 'drop':
this.topText = this.topDropT
case 'loading':
this.topText = this.topLoadingT
bottomStatus(val) {
this.$emit('bottom-status-change', val);
switch (val) {
case 'pull':
this.bottomText = this.bottomPullT
case 'drop':
this.bottomText = this.bottomDropT
case 'loading':
this.bottomText = this.bottomLoadingT
上面是组件通过watch监听的两个变量,后面我们能看到他们的改变是在touchmove事件中进行处理改变的。它的作用是通过它的变化来改变top slot和bottom slot的文本内容;
同时发出status-change事件给外部使用,因为可能外部自定义top slot 和bottom slot的内容,通过此事件来通知外部当前状态以便外部进行处理。
核心函数的解析
这里就不将所有的method列出,下面就根据处理的所以来解析对应的method函数。
首先,入口是在组件mounted生命周期的钩子回调中执行init函数
mounted() {
this.init();
init函数:
this.topStatus = 'pull';
this.bottomStatus = 'pull';
this.topText = this.topPullT
this.scrollEventTarget = this.getScrollEventTarget(this.$el);
if (typeof this.bottomMethod === 'function') {
this.fillContainer();
this.bindTouchEvents();
if (typeof this.topMethod === 'function') {
this.bindTouchEvents();
fillContainer() {
if (this.autoFill) {
this.$nextTick(() =& {
if (this.scrollEventTarget === window) {
this.containerFilled = this.$el.getBoundingClientRect().bottom &=
document.documentElement.getBoundingClientRect().
this.containerFilled = this.$el.getBoundingClientRect().bottom &=
this.scrollEventTarget.getBoundingClientRect().
if (!this.containerFilled) {
this.bottomStatus = 'loading';
this.bottomMethod();
init函数主要是初始化状态和事件的一些操作,下面着重分析touch事件的回调函数的处理。
首先touchstart事件回调处理函数
handleTouchStart(event) {
this.startY = event.touches[0].clientY;
this.startScrollTop = this.getScrollTop(this.scrollEventTarget);
this.bottomReached = false;
if (this.topStatus !== 'loading') {
this.topStatus = 'pull';
this.topDropped = false;
if (this.bottomStatus !== 'loading') {
this.bottomStatus = 'pull';
this.bottomDropped = false;
主要是记录初始位置和重置状态变量。
下面继续touchmove的回调处理函数
handleTouchMove(event) {
if (this.startY & this.$el.getBoundingClientRect().top && this.startY & this.$el.getBoundingClientRect().bottom) {
this.currentY = event.touches[0].clientY;
let distance = (this.currentY - this.startY) / this.distanceI
this.direction = distance & 0 ? 'down' : 'up';
if (typeof this.topMethod === 'function' && this.direction === 'down' &&
this.getScrollTop(this.scrollEventTarget) === 0 && this.topStatus !== 'loading') {
event.preventDefault();
event.stopPropagation();
if (this.maxDistance & 0) {
this.translate = distance &= this.maxDistance ? distance - this.startScrollTop : this.
this.translate = distance - this.startScrollT
if (this.translate & 0) {
this.translate = 0;
this.topStatus = this.translate &= this.topDistance ? 'drop' : 'pull';
if (this.direction === 'up') {
this.bottomReached = this.bottomReached || this.checkBottomReached();
if (typeof this.bottomMethod === 'function' && this.direction === 'up' &&
this.bottomReached && this.bottomStatus !== 'loading' && !this.bottomAllLoaded) {
event.preventDefault();
event.stopPropagation();
if (this.maxDistance & 0) {
this.translate = Math.abs(distance) &= this.maxDistance
? this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance : this.
this.translate = this.getScrollTop(this.scrollEventTarget) - this.startScrollTop +
if (this.translate & 0) {
this.translate = 0;
this.bottomStatus = -this.translate &= this.bottomDistance ? 'drop' : 'pull';
this.$emit('translate-change', this.translate);
上面的代码逻辑挺简单,注释也就相对不多。
重点谈一下checkBottomReached()函数,用来判断当前scroll dom是否滚动到了底部。
checkBottomReached() {
if (this.scrollEventTarget === window) {
return document.body.scrollTop + document.documentElement.clientHeight &= document.body.scrollH
return this.$el.getBoundingClientRect().bottom &= this.scrollEventTarget.getBoundingClientRect().bottom + 1;
经过我的测试,上面的代码是有问题:
当scrollEventTarget是window的条件下,上面的判断是不对的。因为document.body.scrollTop总是比正常值小1,所以用于无法满足到达底部的条件;
当scrollEventTarget不是window的条件下,上面的判断条件也不需要在this.scrollEventTarget.getBoundingClientRect().bottom后面加1,但是加1也不会有太大视觉上的影响。
最后来看下moveend事件回调的处理函数
handleTouchEnd() {
if (this.direction === 'down' && this.getScrollTop(this.scrollEventTarget) === 0 && this.translate & 0) {
this.topDropped = true;
if (this.topStatus === 'drop') {
this.translate = '50';
this.topStatus = 'loading';
this.topMethod();
this.translate = '0';
this.topStatus = 'pull';
if (this.direction === 'up' && this.bottomReached && this.translate & 0) {
this.bottomDropped = true;
this.bottomReached = false;
if (this.bottomStatus === 'drop') {
this.translate = '-50';
this.bottomStatus = 'loading';
this.bottomMethod();
this.translate = '0';
this.bottomStatus = 'pull';
this.$emit('translate-change', this.translate);
this.direction = '';
下拉刷新和上拉加载更多的实现原理可以借鉴
getScrollEventTarget()获取滚动对象,getScrollTop()获取滚动距离,checkBottomReached()判断是否滚动到底部;这三种方式可以借鉴
缺点: 写死了top slot 和 bottom slot的高度,太不灵活;这个地方可以优化
本文已收录于以下专栏:
相关文章推荐
mintui是饿了么团队针对vue开发的移动端组件库,方便实现移动端的一些功能,这里只用了Loadmore功能实现移动端的上拉分页刷新,下拉加载数据,废话不说上代码。
在使用vue做一个h5项目的时候,需要上拉分页加载,所以在实践中总结了一下使用方法:1.npm i mint-ui -S
2.main.js中引入import &#39;mint-ui/lib/style.c...
前叙mint-ui组件库中swipe组件,实现的是常见的轮播图效果。但是它的实现方式,和常见的实现有所不同。
常见的实现方式: 通过移动轮播图的wrapper来实现item的切换效果(也就是修改wr...
我知道很多人同我一样,不太喜欢看这玩意。但是对于Vue来说我强烈推荐在做项目之前大家必须去过一遍文档,或者说最起码也要了解到Vue的基础用法,基础API,生命周期这些东西。我说了。。是了解,所以不用急...
好久没更新过Vue的小文章,上次做了一个基于Vue+Mint-ui的移动端AppDemo,集成了推送功能,然后通过cordova打包生成apk,移动端表现还不错,今天把这个小东西分享出来,希望有更多的...
建议先看上一篇再来食用本文,如果直接想看源码文末就是~上一篇讲到在项目中使用上拉加载更多组件,但是由于实际项目开发中由于需求变更或者说在webview中上拉加载有些机型在上拉时候会把webview也一...
因为我们项目中,还用了swiper。。。很多都是滑动切换的,但是又得上拉加载,所以导致,很多UI框架,我们用了,都有不同的bug出现,没办法,最后写了一个。代码如下(这个因为很多地方会用,所以建议放在...
他的最新文章
讲师:宋宝华
讲师:何宇健
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 mint ui loadmore 的文章

 

随机推荐