背景:

弹层里边有可滚动区域时,在移动端的坑我就不多说了。

找了很多解决滚动穿透的方案,最终都不能完美解决。

一气之下自己js撸了一个。

效果图:

原理:

1、解决滚动穿透:通过给弹层绑定touchmove和mousewheel事件,取消默认行为实现。

2、取消默认行为后不能滚动:给需要滚动展示的区域绑定touchstart、touchmove和mousewheel事件,监听触发区域的Y值,对应修改可滚动区域的translateY值,实现滚动效果。

缺点/不足:
滑动起来略显卡顿,用户体验不好,有大佬给提示下怎么优化吗?

代码:

 <div class="layer">
<div class="layer-box">
<h3>title
<span class="close">X</span>
</h3>
<div class="lose-list">
<ul class="layer-scroll">
<li class="lose-item">
<h3>有效降价车款1</h3>
<ul class="lose-date">
<li>10月7日5分</li>
<li>10月7日6分</li>
<li>10月7日7分</li>
<li>10月7日8分</li>
<li>10月7日9分</li>
<li>10月7日10分</li>
<li>10月7日11分</li>
<li>10月7日12分</li>
<li>10月7日13分</li>
<li>10月7日14分</li>
<li>10月7日15444分</li>
</ul>
</li>
<li class="lose-item">
<h3>有效降价车款2</h3>
<ul class="lose-date">
<li>10月7日5分</li>
<li>10月7日6分</li>
<li>10月7日7分</li>
<li>10月7日8分</li>
<li>10月7日9分</li>
<li>10月7日10分</li>
<li>10月7日11分</li>
<li>10月7日12分</li>
<li>10月7日13分</li>
<li>10月7日14分</li>
<li>10月7日15333分</li>
</ul>
</li>
<li class="lose-item">
<h3>有效降价车款3 </h3>
<ul class="lose-date">
<li>10月7日5分</li>
<li>10月7日6分</li>
<li>10月7日7分</li>
<li>10月7日8分</li>
<li>10月7日9分</li>
<li>10月7日10分</li>
<li>10月7日11分</li>
<li>10月7日12分</li>
<li>10月7日13分</li>
<li>10月7日14分</li>
<li>10月7日152222分</li>
</ul>
</li>
</ul>
<div class="right-bar">
<div class="bar-pro"></div>
</div>
</div>
</div>
</div>
 myScroll({
openBtn: 'button',
layer: '.layer',
client: '.lose-list',
scroll: '.layer-scroll',
barBG: '.right-bar',
bar: '.bar-pro'
});
function myScroll(params) {
var utils = {
clientH: $(params.client).height(), //h1
scrollH: $(params.scroll).height(), //h2
barBgH: $(params.barBG).height() //h4
}
var lastY = 0,
transY = 0,
barTransY = 0,
barH = 0; //h3
function noScroll(dom) {
$(dom).on('mousewheel', function (e) {
e.preventDefault();
});
$(dom).on('touchmove', function (e) {
e.preventDefault();
});
}
function touchToBottom(target, bar) {
$(target).on('touchstart', function (e) {
e.preventDefault();
let y = e.originalEvent.touches[0].pageY;
lastY = y;
});
$(target).on('touchmove', function (e) {
e.preventDefault();
let y = e.originalEvent.touches[0].pageY,
moveY = y - lastY;
transY += moveY;
if (moveY > 0 && transY > 0) {
/* 鼠标向下移动,对应元素向上回看 */
transY = 0; //到顶
} else {
/* 鼠标向上移动,对应元素向下翻看 */
if (Math.abs(transY) >= e.currentTarget.clientHeight - utils.clientH) { //触底
transY = -(e.currentTarget.clientHeight - utils.clientH) + 1;
}
}
$(this).css('transform', `translate(0px, ${transY}px)`);
/* 移动时,滚轮的变化监听 */
var barMove = Math.abs(moveY) * utils.barBgH / utils.scrollH;
if (moveY > 0) {
barMove = -barMove;
}
barTransY += barMove;
if (moveY > 0) {
if (barTransY <= 0) {
barTransY = 0; //到顶
}
} else {
if (barTransY >= utils.barBgH - barH) {
barTransY = utils.barBgH - barH; //到底
}
}
$(bar).css('transform', `translate(0px, ${barTransY}px)`);
lastY = y;
});
/* 滚轮事件 */
$(target).on("mousewheel", function (e, delta) {
e.preventDefault();
let y = e.originalEvent.deltaY;
if (y > 0) {
/* 向下翻滚轮 wheelDeltaY的值与之相反*/
transY -= 100;
barTransY += 100 * utils.barBgH / utils.scrollH;
if (Math.abs(transY - 100) >= e.currentTarget.clientHeight - utils.clientH) { //触底
transY = -(e.currentTarget.clientHeight - utils.clientH) + 1;
}
if (barTransY > utils.barBgH - barH) {
barTransY = utils.barBgH - barH
}
} else {
/* 向上翻滚轮*/
transY += 100;
barTransY -= 100 * utils.barBgH / utils.scrollH;
if (Math.abs(transY) - 100 <= 0) {
transY = 0; //到顶
}
if (barTransY <= 0) {
barTransY = 0; //到顶
}
}
$(this).css('transform', `translate(0px, ${transY}px)`);
$(bar).css('transform', `translate(0px, ${barTransY}px)`);
});
}
noScroll(params.layer);
$(params.layer + ' .close').on('click', function () {
$(params.layer).fadeOut();
// $(params.scroll).css('transform', 'translate(0px, 0px)');
// $(params.bar).css('transform', 'translate(0px, 0px)');
});
$(params.openBtn).on('click', function () {
$(params.scroll).css('transform', 'translate(0px, 0px)');
$(params.bar).css('transform', 'translate(0px, 0px)');
lastY = 0;
transY = 0;
barTransY = 0;
$(params.layer).fadeIn();
utils = {
clientH: $(params.client).height(), //h1
scrollH: $(params.scroll).height(), //h2
barBgH: $(params.barBG).height() //h4
}
barH = parseInt(utils.clientH * utils.barBgH / utils.scrollH); //h3
$(params.bar).height(barH + 'px');
if (utils.clientH < utils.scrollH) {
touchToBottom(params.scroll, params.bar);
}
});
}

完整demo见github:

移动端超出滚动效果

声明:

  请尊重博客园原创精神,转载或使用图片请注明:

  博主:xing.org1^

  出处:http://www.cnblogs.com/padding1015/

js - 移动端的超出滚动功能,附带滚动条,可解决弹层中滚动穿透问题。的更多相关文章

  1. 解决: 移动端经mouseover显示出的弹层中链接点击问题

    通常我们会遇到这样的需求,导航菜单在鼠标划过的时候显示自定义弹层,在弹层中有一些链接需要点击后跳转或者其他一些事件.比如: $(".menu li").on("mouse ...

  2. css 之内容溢出滚动,隐藏滚动条(解决火狐浏览隐藏不了滚动条问题)

    解决火狐浏览隐藏不了滚动条问题 1.里层容器的width多17px,外层容器溢出隐藏,能兼容各个浏览器 .outContainer { width:350px; height:300px; overf ...

  3. 弹层蒙版(mask),ios滚动穿透,我们项目的解决方案

    问题描述 项目开发遇到一个ios独有的问题,在wkwebview中稳定复现 问题: 弹出一个蒙版,当在蒙版上面滑动的时候蒙版后面的内容滚动了 这当然是ios的bug,但是经过我们测试iphone7也会 ...

  4. C# 在RichTextBox中滚动鼠标时滚动的是父窗口的滚动条

    1. RichTextBox u2 = new RichTextBox(); 2. 先记住日RichTextBox没有显示滚动条时的总宽度和显示宽度 u2.Width - u2.ClientSize. ...

  5. 基于animate.css动画库的全屏滚动小插件,适用于vue.js(移动端、pc)项目

    功能简介 基于animate.css动画库的全屏滚动,适用于vue.js(移动端.pc)项目. 安装 npm install vue-animate-fullpage --save 使用 main.j ...

  6. 原生js移动端列表无缝间歇向上滚动

    在项目开发中尤其是在项目的活动页面的开发中,经常需要将用户的购买信息或中奖信息等以列表的形式展示在页面当中,并可以使其自动间歇向上滚动来达到在有限的区域内展示所有信息的目的.通常的做法是通过将列表父元 ...

  7. JS pc端和移动端共同实现复制到剪贴板功能实现

    JS pc端和移动端实现复制到剪贴板功能实现 在网页上复制文本到剪切板,一般是使用JS+Flash结合的方法,网上有很多相关文章介绍.随着 HTML5 技术的发展,Flash 已经在很多场合不适用了, ...

  8. vue.js移动端app实战4:上拉加载以及下拉刷新

    上拉加载以及下拉刷新都是移动端很常见的功能,在搜索或者一些分类列表页面常常会用到. 跟横向滚动一样,我们还是采用better-scroll这个库来实现.由于better已经更新了新的版本,之前是0.几 ...

  9. 基于Vue.js PC桌面端弹出框组件|vue自定义弹层组件|vue模态框

    vue.js构建的轻量级PC网页端交互式弹层组件VLayer. 前段时间有分享过一个vue移动端弹窗组件,今天给大家分享一个最近开发的vue pc端弹出层组件. VLayer 一款集Alert.Dia ...

随机推荐

  1. Struts与jsp+javabean+servlet区别

    采用Struts框架技术和直接使用jsp+javabean技术开发各有什么优势?各自的缺点又是什么? 在Javaweb开发领域存在2种开发模式, 模式一,jsp+javabean 模式二,jsp+ja ...

  2. ArcGIS Pro 中不可用的工具

    有些可用于 ArcMap 之类的其他 ArcGIS Desktop 应用程序的地理处理工具在 ArcGIS Pro 中不可用.用于处理 ArcGIS Pro 所不支持的数据格式的地理处理工具已被移除, ...

  3. 给你的 CentOS 7 安装中文支持

    今天给大家分享个给 CentOS 7 安装中文支持的方法,所谓“中文支持”目前明月观测到的是指命令行提示支持中文提示显示,还有就是 Vim 启动后看到的也是有中文提是的界面包括 Vim 内各种提示也会 ...

  4. 解决Gerrit的git unpack error问题

    今天上午同事和我说neutron项目要换成全新的内部代码,原先仓库里的代码要全部废弃掉.于是我就简单地创建了一个空项目使用git push --force将其置空. 下午的时候,麻烦事情就来了,同事发 ...

  5. Windows平台下tomcat 性能调优

    Tomcat 线程查看工具: https://blog.csdn.net/jrainbow/article/details/49026365 16G内存 Tomcat并发优化.内存配置.垃圾回收.宕机 ...

  6. Cache Line 伪共享发现与优化

    https://yq.aliyun.com/articles/465504 Cache Line 伪共享发现与优化 作者:吴一昊,杨勇 1. 关于本文 本文基于 Joe Mario 的一篇博客 改编而 ...

  7. 基于Centos搭建 Mono 开发环境

    系统要求: CentOS 7.2 64 位操作系统 安装 Mono 安装前的准备 yum install yum-utils 执行命令添加安装包仓库 rpm --import "http:/ ...

  8. Homebrew macOS 包管理

    1.Homebrew 简介 1.1 Homebrew Homebrew 是一款 macOS 平台下的软件包管理工具,拥有安装.卸载.更新.查看.搜索等很多实用的功能.简单的一条指令,就可以实现包管理, ...

  9. Asp.Net MVC4中的全局过滤器

    可以对整个项目进行全局监控. 新建一个MVC4项目,可以在global.asax文件中看到如下代码:  FilterConfig.RegisterGlobalFilters(GlobalFilters ...

  10. d3实现的力向导图

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...