body很长,可以滑动,body头部有一个模拟下拉的选择框,下拉选择有滚动轴

我给body一个overflow:hidden和高度是没有用的。手机网站上背景还是可以滑动,然后我给body一个touchmove的preventdefault()阻止事件,body滑动阻止了,PC上面是可以了,但是手机上面滑动div还是会导致底部body的滑动,我给div 一个阻止冒泡的事件stopPropagation(),手机网站上面还是不可以。

解决方案

我经过反复测试,发现滚动轴滚到底部的时候,会触发body的滑动,那么我就在事件滚到底部的时候对表层的div做一个touchmove的阻止。到达滚动轴底部,向下滑动,阻止事件,向上滑动,开启事件。为此就要判断touchmove的方向了。

var startX ,startY;
$("body").on("touchstart", function(e) {
e.preventDefault();
startX = e.originalEvent.changedTouches[0].pageX,
startY = e.originalEvent.changedTouches[0].pageY;
});
$("body").on("touchmove", function(e) {
e.preventDefault();
var moveEndX = e.originalEvent.changedTouches[0].pageX,
moveEndY = e.originalEvent.changedTouches[0].pageY,
X = moveEndX - startX,
Y = moveEndY - startY; if ( Math.abs(X) > Math.abs(Y) && X > 0 ) {
alert("left 2 right");
}
else if ( Math.abs(X) > Math.abs(Y) && X < 0 ) {
alert("right 2 left");
}
else if ( Math.abs(Y) > Math.abs(X) && Y > 0) {
alert("top 2 bottom");
}
else if ( Math.abs(Y) > Math.abs(X) && Y < 0 ) {
alert("bottom 2 top");
}
else{
alert("just touch");
}
});

上面的方法是判断touchmove的滑动方向。

除了上面方法判断手机端手机滑动方向,我这里再介绍一个方案,就是封装一个角度函数,通过角度函数来判断也还不错!我这里仅仅把这种方式实现上滑下滑左滑右滑列举一下!

var startx, starty;
//获得角度
function getAngle(angx, angy) {
return Math.atan2(angy, angx) * 180 / Math.PI;
}; //根据起点终点返回方向 1向上 2向下 3向左 4向右 0未滑动
function getDirection(startx, starty, endx, endy) {
var angx = endx - startx;
var angy = endy - starty;
var result = 0; //如果滑动距离太短
if (Math.abs(angx) < 2 && Math.abs(angy) < 2) {
return result;
} var angle = getAngle(angx, angy);
if (angle >= -135 && angle <= -45) {
result = 1;
} else if (angle > 45 && angle < 135) {
result = 2;
} else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) {
result = 3;
} else if (angle >= -45 && angle <= 45) {
result = 4;
} return result;
}
//手指接触屏幕
document.addEventListener("touchstart", function(e) {
startx = e.touches[0].pageX;
starty = e.touches[0].pageY;
}, false);
//手指离开屏幕
document.addEventListener("touchend", function(e) {
var endx, endy;
endx = e.changedTouches[0].pageX;
endy = e.changedTouches[0].pageY;
var direction = getDirection(startx, starty, endx, endy);
switch (direction) {
case 0:
alert("未滑动!");
break;
case 1:
alert("向上!")
break;
case 2:
alert("向下!")
break;
case 3:
alert("向左!")
break;
case 4:
alert("向右!")
break;
default:
}
}, false);

知道滑动方向如何判断,那么解决这个问题我们可以判断是否滑动到底部或者顶部,假如滑动到底部,再往下滑动,就阻止滑动,往上滑动,就开启滑动!滑动到顶部一个道理!总结代码如下:

  $('#haorooms底层背景').bind("touchmove", function (e) {
e.preventDefault();
});
$(".滚动的父亲").bind("touchstart", function (events) {
startY = events.originalEvent.changedTouches[0].pageY;
});
$(".滚动的父亲 ul").bind("touchmove", function (e) {
var ulheight = $(this).height();
var scrollTop = $(this).scrollTop();
var scrollheight = $(this)[0].scrollHeight;
if (ulheight + scrollTop + 20 >= scrollheight) { //滚到底部20px左右
$(".滚动的父亲").bind("touchmove", function (event) {
moveEndY = event.originalEvent.changedTouches[0].pageY,
theY = moveEndY - startY;
if (Math.abs(theY) > Math.abs(theX) && theY > 0) { //用上面的abs()更加准确!这里是判断上滑还是下滑!可以用角度函数也可以用上面绝对值方式!
$(".滚动的父亲").unbind("touchmove");//滑动到底部再往上滑动,解除阻止!
}
if (Math.abs(theY) > Math.abs(theX) && theY < 0) {
event.preventDefault();//滑动到底部,再往下滑动,阻止滑动!
}
})
}
if (scrollTop < 20) {//滚到顶部20px左右
$(".滚动的父亲").bind("touchmove", function (event) {
moveEndY = event.originalEvent.changedTouches[0].pageY,
theY = moveEndY - startY;
if (Math.abs(theY) > Math.abs(theX) && theY > 0) {
event.preventDefault();
}
if (Math.abs(theY) > Math.abs(theX) && theY < 0) {
$(".滚动的父亲").unbind("touchmove");
}
})
}
});

以上方法基本上能够阻止body的滚动,但是,有时候还是会有问题,期待更好的解决方案!

张鑫旭的一种解决办法

下面是张鑫旭的一个解决办法,这里我简单的借用一下!

CSS代码:

.noscroll,
.noscroll body {
overflow: hidden;
}
.noscroll body {
position: relative;
}

js代码:

$.smartScroll = function(container, selectorScrollable) {
// 如果没有滚动容器选择器,或者已经绑定了滚动时间,忽略
if (!selectorScrollable || container.data('isBindScroll')) {
return;
} // 是否是搓浏览器
// 自己在这里添加判断和筛选
var isSBBrowser; var data = {
posY: 0,
maxscroll: 0
}; // 事件处理
container.on({
touchstart: function (event) {
var events = event.touches[0] || event; // 先求得是不是滚动元素或者滚动元素的子元素
var elTarget = $(event.target); if (!elTarget.length) {
return;
} var elScroll; // 获取标记的滚动元素,自身或子元素皆可
if (elTarget.is(selectorScrollable)) {
elScroll = elTarget;
} else if ((elScroll = elTarget.parents(selectorScrollable)).length == 0) {
elScroll = null;
} if (!elScroll) {
return;
} // 当前滚动元素标记
data.elScroll = elScroll; // 垂直位置标记
data.posY = events.pageY;
data.scrollY = elScroll.scrollTop();
// 是否可以滚动
data.maxscroll = elScroll[0].scrollHeight - elScroll[0].clientHeight;
},
touchmove: function () {
// 如果不足于滚动,则禁止触发整个窗体元素的滚动
if (data.maxscroll <= 0 || isSBBrowser) {
// 禁止滚动
event.preventDefault();
}
// 滚动元素
var elScroll = data.elScroll;
// 当前的滚动高度
var scrollTop = elScroll.scrollTop(); // 现在移动的垂直位置,用来判断是往上移动还是往下
var events = event.touches[0] || event;
// 移动距离
var distanceY = events.pageY - data.posY; if (isSBBrowser) {
elScroll.scrollTop(data.scrollY - distanceY);
elScroll.trigger('scroll');
return;
} // 上下边缘检测
if (distanceY > 0 && scrollTop == 0) {
// 往上滑,并且到头
// 禁止滚动的默认行为
event.preventDefault();
return;
} // 下边缘检测
if (distanceY < 0 && (scrollTop + 1 >= data.maxscroll)) {
// 往下滑,并且到头
// 禁止滚动的默认行为
event.preventDefault();
return;
}
},
touchend: function () {
data.maxscroll = 0;
}
}); // 防止多次重复绑定
container.data('isBindScroll', true);
};

html如下:

<aside id="aside" class="aside">
<i class="aside-overlay hideAside"></i>
<div class="aside-content">
<div class="module module-filter-list">
<div class="module-main scrollable">
<ul id="filters" class="sort-ul">
.......
</ul>
</div>
</div>
</div>
</aside>

使用:

$('#aside').addClass('active');
$.smartScroll($('#aside'), '.scrollable');
$('html').addClass('noscroll');

大家可以测试一下!

移动端表层div滑动,导致底层body滑动(touchmove的阻止)的更多相关文章

  1. 滑动表层div时 禁止底层滑动

    $(".container").bind("touchstart", function (events) { startX = events.originalE ...

  2. 移动端300ms延迟原理,穿透、遮罩层滑动导致下面滑动总结

    遮罩层滑动导致下面滑动 1,阻止弹层滑动,使用默认事件,使用这种方式弹层不能滑动 document.getElementById("model").addEventListener ...

  3. 移动端touch事件影响click事件以及在touchmove添加preventDefault导致页面无法滚动的解决方法

    这两天自己在写一个手机网页,用到了触屏滑动的特效,就是往右滑动的时候左侧隐藏的菜单从左边划出来. 做完之后在手机原生浏览器中运行正常,但在QQ和微信中打开,发现touchmove只会触发一次,而且to ...

  4. js实现一个可以兼容PC端和移动端的div拖动效果

    前段时间写了一个简单的div拖动效果,不料昨天项目上正好需要一个相差不多的需求,就正好用上了,但是在移动端的时候却碰到了问题,拖动时候用到的三个事件:mousedown.mousemove.mouse ...

  5. 基于zepto的插件之移动端无缝向上滚动并上下触摸滑动

    该插件乃本博客作者所写,目的在于提升作者的js能力,也给一些js菜鸟在使用插件时提供一些便利,老鸟就悠然地飞过吧. 公司的移动端项目是基于zepto的,有一个页面要求文字能够无缝地不停向上滚动,但查了 ...

  6. 关于dom节点绑定滑动事件导致浏览器上下滑动失效解决方案--黄丕巧

    1.移动端开发往往需要添加一下自定义的左右滑动事件,但是添加了左右滑动事件之后就要阻止浏览器大默认事件,否则dom节点的滑动事件和浏览器本身的滑动会出现冲突,导致滑动的时候会出现消失瞬间再出现的效果 ...

  7. 移动端:div在手机页面上随意拖动

    <!doctype html> <html> <head> <title>弹窗</title> <meta charset=" ...

  8. 解决scrollView中嵌套编辑框导致不能上下滑动的问题

    EditText设置maxLines之后,文本行数超过maxLines,会网上折叠,上下滑动能够浏览全部文本. 若EditText外层有scrollView.在EditText上下滑动,不会像正常情况 ...

  9. SwipeMenuListView在ScrollView里上下滑动导致菜单不能显示完全的bug解决方法

    这是因为上下滑动的时候,事件被ScrollView截获了,这时候应该禁止ScrollView截获上下滑动事件,解决方法如下 public class NoRollSwipeMenuListView e ...

随机推荐

  1. Linux 内核综述

    一.什么是Linux内核: 内核->操作系统中最重要的部分,内核将在系统引导时被装载进RAM,其中包含了很多关键的例程,以操作系统.内核是OS最为关键的部分,人们常将OS(操作系统)与内核等同. ...

  2. 解决CentOS7中文乱码(包括Tomcat日志乱码)问题

    Linux系统中文语言乱码,是很多小伙伴在开始接触Linux时经常遇到的问题,而且当我们将已在Wndows部署好的项目搬到Linux上运行,Tomcat的输出日志中文全为乱码(在Windows上正常) ...

  3. 构建自己的Tomcat镜像

    在很多情况下,我们会不满足于官方提供的Tomcat镜像.比如官方镜像的时区为UTC时间,并不是北京时间:再比如在特定硬件环境下,jdk的随机数生成器初始化过慢问题.此时,我们就会考虑构建自己的Tomc ...

  4. BottomupSort算法 c++代码实现

    #include <iostream> using namespace std; #define N 100 int A[N]; static int n; void Initial() ...

  5. 关于WIN7 内存占用很大的 问题svchost.exe

    svchost.exe 是用来启动系统服务的,所以某个 svchost.exe 占用内存过大,可能就是它启动的那个服务占用内存过大,所以只要停止并禁用那个服务就行了. 一般来说占用内存最大的服务是 S ...

  6. 历年NOIP中的搜索题

    什么题目都不会做于是开始做搜索题. 然而我搜索题也不会做了. 铁定没戏的蒟蒻. 1.NOIP2004 虫食算 “对于给定的N进制加法算式,求出N个不同的字母分别代表的数字,使得该加法算式成立.输入数据 ...

  7. Django学习(九)---Templates过滤器及Django shell和Admin增强

    一.Templates过滤器 过滤器属于django模板语言 修改模板中的变量,从而显示不同内容 {{ value | filter }} 举例:{{ list_nums | length}}    ...

  8. 基于.NET CORE微服务框架 -谈谈surging的服务容错降级

    一.前言 对于不久开源的surging受到不少.net同学的青睐,也受到.net core学习小组的关注,邀请加入.NET China Foundation以方便国内.net core开源项目的推广, ...

  9. linux基础(五)

    一.linux网络原理及基础设置 ifconfig 命令:显示所有正在启动的网卡的详细信息或设定系统中网卡的IP地址. [root@bogon ~]# ifconfig ens33: flags=41 ...

  10. java线程数过高原因分析

    作者:鹿丸不会多项式  出处:http://www.cnblogs.com/hechao123   转载请先与我联系. 一.问题描述 前阵子我们因为B机房故障,将所有的流量切到了A机房,在经历了推送+ ...