web移动端:touchmove实现局部滚动

总结一下最近项目用到的一个功能点,具体要求如下:body中会呈现一个可滚动的长页面,在点击某个按钮的时候,会出现一个弹出框,由于弹出框的内容较长,会出现滚动条,但是要保证位于弹框下部的body在弹框滚动的时候不触发滚动事件实现效果图如下:一.css部分html,body{margin:0;padding:0;}.btn{position:fixed;

大家好,又见面了,我是你们的朋友全栈君。

总结一下最近项目用到的一个功能点,具体要求如下:
body中会呈现一个可滚动的长页面,在点击某个按钮的时候,会出现一个弹出框,由于弹出框的内容较长,会出现滚动条,但是要保证位于弹框下部的body在弹框滚动的时候不触发滚动事件

实现效果图如下:
这里写图片描述这里写图片描述

一.css部分

html,body{ margin:0; padding: 0; }
.btn{ position: fixed; bottom: 0; width: 100%; padding: .5rem 0; background-color: pink; text-align: center; color: #fff; font-weight: 700; }
.replyCeng{ display: none; position: fixed; top:0; width:100%; height: 100vh; background-color: rgba(0,0,0,0.6); z-index: 100; }
.replyContainer{ background-color: #fff; position: absolute; bottom: 0; width: 100%; height: 24rem; text-align: center; overflow: hidden; }
.replyList{ position: absolute; top:3.2rem; width: 100%; }
.replyTitle{ position: absolute; top: 0; width:100%; padding:1.0625rem 0; border-bottom:1px solid #e0e0e2; z-index: 202; color: #575b61; font-size: .9375rem; font-weight: 700; background-color: #fff; }
.closeReply{ position: absolute; width: 1rem; height: 1rem; top: .25rem; right: .25rem; z-index: 202; margin: 1rem; }
.reply-item{ padding:.9375rem 1.625rem; font-size: .9375rem; line-height: 1.5; color: #666666; border-bottom:1px solid #e0e0e2; }
.replyBtn{ /* padding: 1.0625rem 1.625rem;*/ font-size: .9375rem; color: #1daffa; font-weight: 700; width:100%; position: absolute; bottom: 0; background-color: #fff; z-index: 202; border-top: 1px solid #e0e0e2; }
.replyBtn div{ margin: 1.0625rem 1.625rem; padding: .6rem; /* width: 100%;*/ border: 1px solid #1daffa; border-radius: .3rem; }

二.html部分

<div>
    <img src="image/langImg.jpg" style="width:100%;height:auto;"/>
</div>
<div class="btn" onclick="replyCengShow()">button</div>
<div class="replyCeng">
    <div class="replyContainer">
        <div class="replyTitle">睡前小贴士</div>
        <img class="closeReply" src="image/close.png" />
        <div class="replyList" id="wrapper">
            <div class="reply-item" onclick="selectReply()">要注意哦,睡觉前不要吃水果,可以适当喝牛奶</div>
            <div class="reply-item">要注意哦,睡觉前不要吃水果,可以适当喝牛奶</div>
            <div class="reply-item">要注意哦,睡觉前不要吃水果,可以适当喝牛奶</div>
            <div class="reply-item">要注意哦,睡觉前不要吃水果,可以适当喝牛奶</div>
            <div class="reply-item">把黑暗的光线试想成大自然的安眠药,从而提示你的身体去大量地制造褪黑激素,这是一种能帮助人平静下来的激素。来自旧金山的专门从事焦虑和失眠的心理学家、心理学博士Steve Orma表示,在入睡前将灯关掉能提高褪黑激素的产量,这样人就会感到倦意。支持这一说法的研究有:2011年发表在《临床内分泌与代谢》期刊上的一篇研究报告表明,在黄昏时刻到睡觉之前暴露在明亮的灯光下会极大地压缩褪黑激素的产量,使人变得极其兴奋。</div>
            <div class="reply-item">把黑暗的光线试想成大自然的安眠药,从而提示你的身体去大量地制造褪黑激素,这是一种能帮助人平静下来的激素。来自旧金山的专门从事焦虑和失眠的心理学家、心理学博士Steve Orma表示,在入睡前将灯关掉能提高褪黑激素的产量,这样人就会感到倦意。支持这一说法的研究有:2011年发表在《临床内分泌与代谢》期刊上的一篇研究报告表明,在黄昏时刻到睡觉之前暴露在明亮的灯光下会极大地压缩褪黑激素的产量,使人变得极其兴奋。</div>
        </div>
        <div class="replyBtn">
            <div>管理</div>
        </div>
    </div>
</div>

三.js部分

1.获得触屏的初始坐标

$(".replyList").on("touchstart",function(e){
    startX = e.originalEvent.changedTouches[0].pageX,
    startY = e.originalEvent.changedTouches[0].pageY;
});

2.移动屏幕添加相应事件
touchmove事件的要点主要是移动方向的判断和滑动边界的判断
<1>移动方向的判断

var replyListTop=parseInt($(".replyList").css("top"));
$(".replyList").bind("touchmove",function(e){ 
     
    moveEndX = e.originalEvent.changedTouches[0].pageX;
    moveEndY = e.originalEvent.changedTouches[0].pageY;
    var moveX;
    var moveY;
    moveX=moveEndX-startX;
    moveY=moveEndY-startY;
    //向上滑动
    if(moveY < 0){  
    }
    //向下滑动
    else if(moveY > 0){
    }
});

<2>移动边界的判断
A.向上滑动到上边界
注:replyScrollTop为文中replyListTop
注:replyScrollTop为文中replyListTop

此时replyListTop为负数

canSeeHeight == replyHeight + replyListTop //(此时正好处于边界状态)

如果再往上滑动,我们将会看到越来越少的内容,也就是:

canSeeHeight > replyHeight + replyListTop

于是得到上边界值:

hasTop= canSeeHeight <= $(this).height()+replyListTop ? true:false

B.向下滑动到下边界
这里写图片描述
由于滚动区域是包裹在replyContainer里面的,所以滚动区域的初始top值为标题区域的高度,只要标题区域的高度 == 滚动区域的top值 ,就代表向下滑动到下边界

hasBottom = 3.2*fontHeight >= replyListTop ? true:false ;//title区域用rem布局,fontHeight为html字体大小
//向上滑动
if(moveY < 0 && hasTop){
    $(".replyList").css("top",replyListTop+"px");
    replyListTop= replyListTop+moveY;
}
//向下滑动
else if(moveY > 0 && hasBottom){
    $(".replyList").css("top",replyListTop);
    replyListTop= replyListTop+moveY;
}

<3>限制滑动过大越界

//向上滑动
if(moveY < 0 && hasTop){
    $(".replyList").css("top",replyListTop+"px");
    replyListTop= replyListTop+moveY;
    //判断加上移动后的位置是否越界,如果越界,以边界值为top值
    replyListTop= canSeeHeight <= ($(this).height()+replyListTop) ? replyListTop : (-Math.abs($(this).height()-canSeeHeight));
}
//向下滑动
else if(moveY > 0 && hasBottom){
    $(".replyList").css("top",replyListTop);
    replyListTop= replyListTop+moveY;
    //判断加上移动后的位置是否越界,如果越界,以边界值为top值
    replyListTop= 3.2*fontHeight >= replyListTop ? replyListTop : 3.2*fontHeight;
}

<4>js完整代码

function replyCengShow(){ 
   
    var startX;
    var startY;
    var moveEndX;
    var moveEndY;
    var testLeft;
    var fontHeight=parseInt($("html").css("fontSize"));
    $(".replyCeng").css("display","block");
    $('body').bind("touchmove",function(e){ 
     
            e.preventDefault();  
        });
    $(".replyList").on("touchstart",function(e){ 
   
        startX = e.originalEvent.changedTouches[0].pageX,
        startY = e.originalEvent.changedTouches[0].pageY;
    });

    var replyListTop=parseInt($(".replyList").css("top"));
    $(".replyList").bind("touchmove",function(e){ 
     
        moveEndX = e.originalEvent.changedTouches[0].pageX;
        moveEndY = e.originalEvent.changedTouches[0].pageY;
        var moveX;
        var moveY;
        moveX=moveEndX-startX;
        moveY=moveEndY-startY;

        canSeeHeight=$(".replyContainer").height()-($(".replyBtn").height()+2.125*fontHeight);
        hasTop= canSeeHeight <= $(this).height()+replyListTop ? true:false
        hasBottom = 3.2*fontHeight >= replyListTop ? true:false ;
        //向上滑动
        if(moveY < 0 && hasTop){
            $(".replyList").css("top",replyListTop+"px");
            replyListTop= replyListTop+moveY;
            replyListTop= canSeeHeight <= ($(this).height()+replyListTop) ? replyListTop : (-Math.abs($(this).height()-canSeeHeight));
        }
        //向下滑动
        else if(moveY > 0 && hasBottom){
            $(".replyList").css("top",replyListTop);
            replyListTop= replyListTop+moveY;
            replyListTop= 3.2*fontHeight >= replyListTop ? replyListTop : 3.2*fontHeight;
        }
    });

    $(".closeReply").unbind("click").bind("click",function(){ 
   
        $(".replyCeng").css("display","none");
        $('body').unbind("touchmove");
    });
}

四.不足

在滚动的过程中能够感到明显的卡顿

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/127092.html原文链接:https://javaforall.net

(0)
上一篇 2022年4月9日 上午9:00
下一篇 2022年4月9日 上午9:00


相关推荐

  • Pytest(13)命令行参数–tb的使用

    Pytest(13)命令行参数–tb的使用前言pytest使用命令行执行用例的时候,有些用例执行失败的时候,屏幕上会出现一大堆的报错内容,不方便快速查看是哪些用例失败。–tb=style参数可以设置报错的时候回溯打印内容,可以设置参

    2022年7月31日
    7
  • msfconsole模块_msfconsole下载

    msfconsole模块_msfconsole下载Msfconsole提供了一个一体化的集中控制台。通过msfconsole,你可以访问和使用所有的metasploit的插件,payload,利用模块,post模块等等。Msfconsole还有第三方程序的接口,比如nmap,sqlmap等,可以直接在msfconsole里面使用。在启动MSF终端之后,可以首先输入help命令列出MSF终端所支持的命令列表,包括核心命令集和后端数据库命令集。对于其中的大部分命令,你可以输入help[COMMAND],进一步查看该命令的使用帮助信息。一、Msfconso

    2025年9月25日
    7
  • angular框架如何实现父子组件传值、非父子组件传值

    angular框架如何实现父子组件传值、非父子组件传值文章目录1.理解父子组件、非父子组件2.父组件给子组件传值–@input3.父组件通过@ViewChild主动获取子组件的数据和方法4.非父子组件如何传递数据1.理解父子组件、非父子组件什么是父子组件?组件的父子关系是相对来说的,即在一个A组件中嵌入了B组件,那么在这一层关系中,A组件是B组件的父组件,B组件是A组件的子组件。看下面两幅图即可理解:app.component.html与普通组件的关系:普通组件与普通组件:现在应该知道父子组件是什么关系了,关键看谁嵌入了谁那里。父子组件

    2022年5月13日
    46
  • vi 命令 使用方法

    vi 命令 使用方法

    2021年11月14日
    52
  • phpstrom 2021.5 激活码[在线序列号][通俗易懂]

    phpstrom 2021.5 激活码[在线序列号],https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月19日
    46
  • 国际邮箱有哪些比较出名_国际上比较认可的邮箱

    国际邮箱有哪些比较出名_国际上比较认可的邮箱经济全球化,越来越多的企业选择跨国贸易,包括外贸、物流、软件科技等行业。在和客户谈生意时,虽然邮箱这个工具不起眼,但是却有着举足轻重的作用,如TOM国际企业邮箱。什么国际邮箱靠谱?企业注册国际邮箱,一般选择企业邮箱。要说什么国际邮箱靠谱,首先考虑海外邮件收发稳定性,其次是安全性。和普通邮箱相比,TOM企业邮箱的国内外邮件收发更安全,拥有专属的收发信通道,邮件加密传输,让用户丝毫不会担心邮件安全。公司用邮箱来往的信息,大多为重要信息,最好能长期存储,无限容量的企业邮箱可长期存储,单次发送邮件附件最大2

    2026年2月25日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号