问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

类似微信消息列表和腾讯新闻列表的下拉刷新效果怎么实现

发布网友 发布时间:2022-05-01 09:28

我来回答

2个回答

懂视网 时间:2022-04-20 03:48

这篇文章给大家介绍的内容是关于html5实现移动端下拉刷新(原理和代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

移动端的下拉刷新是一个很常见的功能,也有许多开源库实现了这个功能,不过为了学习,还是先自己写一个例子学习一下。其中用到了一些touch事件和一些DOM属性CSS3属性。直接上代码,代码里面有注释。

<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <title>Document</title>
 <style type="text/css">
 html,
 body,
 header,
 p,
 main,
 p,
 span,
 ul,
 li {
  margin: 0;
  padding: 0;
 }

 #refreshContainer li {
  background-color: #eee;
  margin-bottom: 1px;
  padding: 20px 10px;
 }

 .refreshText {
  position: absolute;
  width: 100%;
  line-height: 50px;
  text-align: center;
  left: 0;
  top: 0;
  transform: translateY(-50px);
 }
 </style>
</head>

<body>
 <main class="parent">
 <p class="refreshText"></p>
 <ul id="refreshContainer">
  <li>111</li>
  <li>222</li>
  <li>333</li>
  <li>444</li>
  <li>555</li>
  <li>111</li>
  <li>222</li>
  <li>333</li>
  <li>444</li>
  <li>555</li>
  <li>111</li>
  <li>222</li>
  <li>333</li>
  <li>444</li>
  <li>555</li>
 </ul>
 </main>
 <script type="text/javascript">
 window.onload = function(){
  //1.获取到列表的dom,刷新显示部分的dom,列表父容器的dom
  let container = document.querySelector('#refreshContainer');
  let refreshText = document.querySelector('.refreshText');
  let parent = document.querySelector('.parent');

  //2.定义一些需要常用的变量
  let startY = 0;//手指触摸最开始的Y坐标
  let endY = 0;//手指结束触摸时的Y坐标
  
  //3.给列表dom监听touchstart事件,得到起始位置的Y坐标
  parent.addEventListener('touchstart',function(e){
  startY = e.touches[0].pageY;
  });
  //4.给列表dom监听touchmove事件,当移动到一定程度需要显示上面的文字
  parent.addEventListener('touchmove',function (e) { 
  if(isTop() && (e.touches[0].pageY-startY) > 0){
   console.log('下拉了');
   refreshText.style.height = "50px";
   parent.style.transform = "translateY(50px)";
   parent.style.transition = "all ease 0.5s";
   refreshText.innerHTML = "释放立即刷新...";
  }
  });
  //5.给列表dom监听touchend事件,此时说明用户已经松开了手指,应该进行异步操作了
  parent.addEventListener('touchend',function (e) { 
  if(isTop()){
   refreshText.innerHTML = "正在刷新...";
   setTimeout(function(){
   parent.style.transform = "translateY(0)";
   console.log('成功刷新');
   },2000)
  }
  return;
  })
  function isTop(){
  var t = document.documentElement.scrollTop||document.body.scrollTop;
  return t === 0 ? true : false;
  }

 }
 </script>
</body>

</html>
  • 其中用到了CSS3中的transform和animate。因为既然都是移动端了,这些东西基本上都支持了。

  • 具体看代码吧,注释也有。本文只是讲解原理,后续将会对其进行封装成一个对象。方便直接调用。

  • 相关文章推荐:

    vue.js移动端实现上拉加载下拉刷新

    移动端下拉刷新,iScroll.js用法(转载)_html/css_WEB-ITnose

    热心网友 时间:2022-04-20 00:56

    大致跟童鞋们说下思路,实现原理是给listview加上一个headview,然后headview有四种状态

    [java] view
    plaincopy

    public interface IListViewState

    {

    int LVS_NORMAL = 0; // 普通状态

    int LVS_PULL_REFRESH = 1; // 下拉刷新状态

    int LVS_RELEASE_REFRESH = 2; // 松开刷新状态

    int LVS_LOADING = 3; // 加载状态

    }

    所以关键在于MotionEvent.ACTION_MOVE时根据手势情况切换各种headview状态

    MotionEvent.ACTION_UP时根据当前状态确定是该进入加载状态还是普通状态

    OK,先贴上touchevent代码:

    [java] view
    plaincopy

    @Override

    public boolean onTouchEvent(MotionEvent ev) {

    // TODO Auto-generated method stub

    if (mOnRefreshListener != null)

    {

    switch (ev.getAction()) {

    case MotionEvent.ACTION_DOWN:

    doActionDown(ev);

    break;

    case MotionEvent.ACTION_MOVE:

    doActionMove(ev);

    break;

    case MotionEvent.ACTION_UP:

    doActionUp(ev);

    break;

    default:

    break;

    }

    }

    return super.onTouchEvent(ev);

    }

    private void doActionDown(MotionEvent ev)

    {

    if(mIsRecord == false && mFirstItemIndex == 0)

    {

    mStartY = (int) ev.getY();

    mIsRecord = true;

    }

    }

    private void doActionMove(MotionEvent ev)

    {

    mMoveY = (int) ev.getY();

    if(mIsRecord == false && mFirstItemIndex == 0)

    {

    mStartY = (int) ev.getY();

    mIsRecord = true;

    }

    if (mIsRecord == false || mViewState == IListViewState.LVS_LOADING)

    {

    return ;

    }

    int offset = (mMoveY - mStartY) / RATIO;

    switch(mViewState)

    {

    case IListViewState.LVS_NORMAL:

    {

    if (offset > 0)

    {

    mHeadView.setPadding(0, offset - mHeadContentHeight, 0, 0);

    switchViewState(IListViewState.LVS_PULL_REFRESH);

    }

    }

    break;

    case IListViewState.LVS_PULL_REFRESH:

    {

    setSelection(0);

    mHeadView.setPadding(0, offset - mHeadContentHeight, 0, 0);

    if (offset < 0)

    {

    switchViewState(IListViewState.LVS_NORMAL);

    }else if (offset > mHeadContentHeight)

    {

    switchViewState(IListViewState.LVS_RELEASE_REFRESH);

    }

    }

    break;

    case IListViewState.LVS_RELEASE_REFRESH:

    {

    setSelection(0);

    mHeadView.setPadding(0, offset - mHeadContentHeight, 0, 0);

    if (offset >= 0 && offset <= mHeadContentHeight)

    {

    mBack = true;

    switchViewState(IListViewState.LVS_PULL_REFRESH);

    }else if (offset < 0)

    {

    switchViewState(IListViewState.LVS_NORMAL);

    }else{

    }

    }

    break;

    default:

    return;

    };

    }

    private void doActionUp(MotionEvent ev)

    {

    mIsRecord = false;

    mBack = false;

    if (mViewState == IListViewState.LVS_LOADING)

    {

    return ;

    }

    switch(mViewState)

    {

    case IListViewState.LVS_NORMAL:

    break;

    case IListViewState.LVS_PULL_REFRESH:

    mHeadView.setPadding(0, -1 * mHeadContentHeight, 0, 0);

    switchViewState(IListViewState.LVS_NORMAL);

    break;

    case IListViewState.LVS_RELEASE_REFRESH:

    mHeadView.setPadding(0, 0, 0, 0);

    switchViewState(IListViewState.LVS_LOADING);

    onRefresh();

    break;

    }

    }

    看下面这个代码段

    [java] view
    plaincopy

    if(mIsRecord == false && mFirstItemIndex == 0)

    {

    mStartY = (int) ev.getY();

    mIsRecord = true;

    }

    其实就是在一次完整的手势过程中,当headview第一次出现时,记录当前触摸点Y坐标值,而在之后的MotionEvent.ACTION_MOVE过程中,我们当前的触摸点与原始记录值会有一个偏移量offset

    int offset = (mMoveY - mStartY) / RATIO;

    这个RATIO值姑且不管它,把它当成一先,假设headview原始高度为size,那么offset与size就有以下三种关系:

    Offset < 0 headview不可见 NORMAL状态

    Offset > 0 && offset < size
    headview可见且不超过原始高度 PULL_REFRESH状态

    Offset > size
    headview可见且超过原始高度 RELEASE_REFRESH

    我们要做的就是根据当前状态再结合offset值来改变headview的尺寸以及确定是否需要切换headview状态

    Switch的这段代码已经描述的很明朗了

    [java] view
    plaincopy

    switch(mViewState)

    {

    case IListViewState.LVS_NORMAL:

    {

    if (offset > 0)

    {

    mHeadView.setPadding(0, offset - mHeadContentHeight, 0, 0);

    switchViewState(IListViewState.LVS_PULL_REFRESH);

    }

    }

    break;

    case IListViewState.LVS_PULL_REFRESH:

    {

    setSelection(0);

    mHeadView.setPadding(0, offset - mHeadContentHeight, 0, 0);

    if (offset < 0)

    {

    switchViewState(IListViewState.LVS_NORMAL);

    }else if (offset > mHeadContentHeight)

    {

    switchViewState(IListViewState.LVS_RELEASE_REFRESH);

    }

    }

    break;

    case IListViewState.LVS_RELEASE_REFRESH:

    {

    setSelection(0);

    mHeadView.setPadding(0, offset - mHeadContentHeight, 0, 0);

    if (offset >= 0 && offset <= mHeadContentHeight)

    {

    mBack = true;

    switchViewState(IListViewState.LVS_PULL_REFRESH);

    }else if (offset < 0)

    {

    switchViewState(IListViewState.LVS_NORMAL);

    }else{

    }

    }

    break;

    default:

    return;

    };
    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
    陌陌发语音出现转码失败怎么办 女孩2010年5月10号阴历3月27早晨9点55分出生的五行缺什么 钟姓男孩名字2023年5月10日出生的 凤眼果有什么营养?凤眼果的这些营养你都知道吗? 专升本成绩多少合格 山东专升本成绩多少合格 山东2022年专升本成绩什么时候出 2024专升本成绩公布时间及入口 2023年山东专升本各专业录取分数线 什么时候出专升本成绩 山东专升本综合素质测评成绩怎么算 Android 编程下如何调整 SwipeRefreshLayout 的下拉刷新距离 铁友火车放票时间一般是几点? 光有ICP没有红盾的网站可以相信吗? 红盾信息网上的年审资料怎么打印啊? 昆明红盾信息网查不到“云南竹龙投资集团有限公司&quot;的相关信息,所以我觉得红盾网的数据是不是不全面?求助 红盾信息网上提交资料时提示&quot;请求出错,请与管理员联系&quot;是什么意思 关于在广州红盾信息网申请个人工商户名称核准的流程 红盾查询网恶意批漏个人信息是犯法吗 企业年检要在红盾信息网填写什么信息 什么是红盾?以及,某某红盾信息网是什么网站? 为什么红盾信息网打开以后是工商局的网站? 红盾信息网和工商行政管理局的网站有什么区别?哪个信息更准确? 红盾信息网有什么作用 我用MFC写了个多线程的小程序,要共享同一个数据库,但是会报错。数据库连接方面的,请问怎么解决? 财务分析题:造句 关于公司节约成本的励志名言有哪些? 用......好像.......一样,......造句 质量,成本,效率3个词怎么造句 广州星河壹号公馆优劣势? 平价口红牌子 铁友火车票如何改签 请问为何我的AE在用鼠标按住时间线拖动时,画面不能实时更新,而只有松开时才更新。多谢了 求一个可以实现手机下滑松开并刷新的脚本代码 手机按键精灵 F5不能连续刷新 我桌面鼠标右键的项目只剩下刷新和属性两个,怎么让恢复到默认的那? 连续开*(一直按住鼠标)一会后松开还在打,太浪费子弹了,咋办??????? 不松开地按F5刷新桌面会CPU性能损坏??? 魔兽世界人物按下鼠标转身松开后延迟现象 空气开关一合就跳闸是怎么回事 空气开关1安能管多少瓦 太原市一德酒业有限公司怎么样? 青岛上升天地物流有限公司怎么样? 美术加课程质量怎么样? 美术家有哪些人物? 美术加对比其他线上美术怎么样? 有什么技术能把两台液晶电视变成一台电视播放? 2022浙江中考美术加多少分 河南中考美术加多少分 目前十大美术加盟品牌有哪些? 今年湖南邵东中考美术加多少分