记一次解决CSS定位bug思路
事因
网站中的遮罩层大都有一个问题,就是在这个遮罩层中滑动,里面的内容也会跟着滑动,我是这样想的,既然都有这个问题,干脆写一个通用的插件出来,省的每个还得单独处理。如果是单独处理这个问题是比较好解决的,关键问题是,我想写的这个插件是,你直接在有问题的页面中引入这个插件就行,而不需要做其他的任何事情,而难就难在这,因为我们不知道什么时候需要阻止滑动,什么时候是正常滑动。
灵感
下班后的路上在想,虽然我们不知道是哪段代码引起的,但如果我们能够分析出什么时候会发生这件事,那就解决了一半的问题,而什么时候会发生我们是可以知道的,在问出这个问题的时候就可以知道,既然是因为在弹出层中滑动引起的,那么也就是说在滚动的时候会发生这件事。而我的想法就是在滚动事件中加一个判断,如果是正常滚动那么就不做任何处理,而如果是由其他DOM冒泡导致里面的内容发生滚动的,那么就不让它滚动。
也就是类似下面这段代码
window.addEventListener("scroll",function(event){
if(非正常滚动){
.....
}
});
实践
那么我们怎么知道它是不是正常滚动,一开始我想的是获取event对象中的target属性,之所以我想获取这个属性是因为它能够确定当前正在活动的DOM,而如果我们能够知道当前活动的DOM是什么,也就可以用它来判断是不是非正常滚动,因为如果body是活动状态,那么就属于正常滚动了,而如果是其他的那么就属于非正常滚动。但遗憾的是,不管是在遮罩层中引发的滚动还是直接在body中滚动,event.target获取到的都是body,也就是说此路不通。
虽然说直接用event.target失败了,但我想一定有能够获取到当前活动的DOM,虽然以前没用过,也没听说过,于是我就将event打印出来,看看它里面都有哪些属性,注意是打印两次,一次是正常滚动的数据,一次是非正常滚动的数据,把它们对比一下。不看不知道,一对比还真发现了点什么,event.target中有一个activeElement属性,而这个正是我苦苦寻找的,从名字上看也能够看出点什么,“活动元素”,怪我无知,还以为自己javascript学的有多好,竟然这个属性都没用过。
有了这个发现以后,我们的代码就变成下面这样啦
window.addEventListener("scroll",function(event){
if(event.target.activeElement.tagName.toLowerCase()!=="body"){
解决bug代码
}
});
解决bug倒也简单,直接给html或者body添加一个overflow:hidden;就ok了,代码如下
window.addEventListener("scroll",function(event){
if(event.target.activeElement.tagName.toLowerCase()!=="body"){
document.all[0].style.overflow= "hidden";
}
});
我这里是给html添加的,防止代码被其他同事窜改,因为body比较多人操作。
虽然上面已经解决了很大一部分问题,但还有一个问题得解决,那就是当遮罩层被关闭我们应该去掉html的overflow:hidden;不然文档超出的部分就看不见了。而我们现在需要解决的问题就是,怎么知道遮罩层被关闭?
分析了一下,所有的遮罩层基本上都是通过点击事件来关闭的,也就是说我们可以通过监听点击事件来去掉html的overflow:hidden;不过直接用click事件会有些问题,有时不会被触发,我这里用的是touchend事件,至于为什么不用touchstart也是有原因的,等等再说,现在我们的代码变成了下面这样
document.addEventListener("touchend",function(){
document.all[0].style.overflow= "auto";
});
window.addEventListener("scroll",function(event){
if(event.target.activeElement.tagName.toLowerCase()!=="body"){
document.all[0].style.overflow= "hidden";
}
});
运行以上代码,我们很快发现了一个新问题,它会出现一卡一卡的,仔细分析,发现直接在touchend事件中改变html的overflow是有问题的,因为不是所有情况都是属于关闭遮罩层的,有可能是在里面正常的滚动,而滚动就需要我们点击一下遮罩层,前面也就是因为忽略了这件事导致卡顿现象的,你想象一下,一下取消一下又不取消,这不是纠结吗。
所以我们还得想另外一个办法,我想到的是,判断一下是属于点击事件,还是滑动事件,至于怎么区分的话,我用了一个计数器,但这个计数器大于2的话就属于滑动事件,代码如下
var count = 0;
document.addEventListener("touchmove",function(){
count++;
});
document.addEventListener("touchend",function(){
if(count<2){
document.all[0].style.overflow= "auto";
}
count = 0;
});
window.addEventListener("scroll",function(event){
if(event.target.activeElement.tagName.toLowerCase()!=="body"){
document.all[0].style.overflow= "hidden";
}
});
到此就结束啦,还有一件事没说,那就是之所以使用touchend事件而没有使用touchstart事件,是因为touchstart在touchmove后不会执行,因此会造成count有时没有被清零。
虽然这个插件确实可以用,但还是有一点点的问题没办法解决,自己测试一下就明白了。
总结
这一次还是蛮有挑战的,倒不是说有多难,关键是要学会把问题看清,把问题分析清楚。要解决的问题是什么?已知什么?通过已知的可以解决什么问题?这也是本次实践的收获吧。
记一次解决CSS定位bug思路的更多相关文章
- 记一次解决layui 的bug - layer.open 与 layui渲染问题
场景是这样的,通过layer打开一个弹窗,里面放置一个表单,表单是用layui来渲染的. 当弹窗完成之后,我需要渲染表单中的一些内容.譬如laydate. layer.open({ type: 1, ...
- (高德地图)marker定位 bug 解决总结
项目背景: 一个项目bug,项目中用到高德地图,默认打开页面会生成一个marker(下图红色icon),然后用户拖动marker到想要的位置,并且保存. 用户反映定位不准确,在当前页面编辑的位置,到后 ...
- 【Unity游戏开发】记一次解决 LuaFunction has been disposed 的bug的过程
一.引子 RT,本篇博客记录的是马三的一次解决 LuaFunction has been disposed 的bug的全过程,事情还要从马三的自研框架 ColaFrameWork 说起.最近,马三在业 ...
- vue—你必须知道的 js数据类型 前端学习 CSS 居中 事件委托和this 让js调试更简单—console AMD && CMD 模式识别课程笔记(一) web攻击 web安全之XSS JSONP && CORS css 定位 react小结
vue—你必须知道的 目录 更多总结 猛戳这里 属性与方法 语法 计算属性 特殊属性 vue 样式绑定 vue事件处理器 表单控件绑定 父子组件通信 过渡效果 vue经验总结 javascript ...
- IE6的那些css常见bug(汇总)
IE6的那些css常见bug(汇总) 我的微博终于在前几天建立了 虽说很早之前就知道博客园这个地方 但怕自己不能坚持去写一些东西一直没有建.这几天 我做了这个决定 把我的博客建起来 每周发一些看到的, ...
- CSS定位与布局:浮动
浮动的特点 浮动(float)属性提出的作用是实现文字的环绕效果,一个元素浮动后,会脱离普通流.主要的特点如下: 浮动的元素会向左或者向右移动直到它的外边缘接触容器框(containing blo ...
- nginx实现动态分离,解决css和js等图片加载问题
改帖专门为使用nginx,通过nginx把请求转发到web服务器再返回客户端的时候,解决css和js和图片加载不出来的问题. 如果没安装nginx,请访问一下地址进行安装 http://www.cnb ...
- CSS定位(CSS定位概述、相对定位、绝对定位、浮动)
CSS 定位属性 CSS 定位属性允许你对元素进行定位. 属性 描述 position 把元素放置到一个静态的.相对的.绝对的.或固定的位置中. top 定义了一个定位元素的上外边距边界与其包含块上边 ...
- CSS定位深入理解 完全掌握CSS定位 相对定位和绝对定位
其实前面的标准流和浮动流都很理解,就是定位不太好理解,特别是相对定位和绝对定位,很多刚开始学的同学不好区分.因此这里,小强老师和大家一起分享CSS定位的学习. 通过我们前面的学习,我们网页布局方法: ...
随机推荐
- webService之helloword(web)
spring 整合webservice pom.xml文件 <dependencies> <!-- CXF WS开发 --> <dependency> <gr ...
- day21(Listener监听器)
监听器只要分为监听web对象创建与销毁,监听属性变化,感知监听器. 1.监听web对象的创建与销毁 servletContextListener 监听ServletContext对象的创建和销毁 ...
- 用mysql workbench导出mysql数据库关系图
用mysql workbench导出mysql数据库关系图 1. 打开mysql workbench,选择首页中间"Data Modeling"下方的第二栏"Create ...
- eclipse中html编辑环境的搭建
转自http://blog.csdn.net/xuanyuansen/article/details/9318661 最近开始对JAVA网络编程感兴趣,所以索性用起了鼎鼎有名的eclipse,正如广大 ...
- RxSwift学习笔记2:Observable/生命周期/Event/oneNext/onError/onCompleted/
Observable 是 Rx 的根基 官网:http://reactivex.io/ github地址:https://github.com/ReactiveX/RxSwift Observabl ...
- 学习JavaScript计划
1.首先根据视频做小例子 2.每天记录到博客 3.这次坚持把这个学完,并完成接口测试界面的编写
- Grid++Report报表工具C/S实战篇(五)
一.课程介绍 本次分享课程属于<C#高级编程实战技能开发宝典课程系列>中的第五部分,阿笨后续会计划将实际项目中的一些比较实用的关于C#高级编程的技巧分享出来给大家进行学习,不断的收集.整理 ...
- 【BZOJ3097】 Hash Killer I
BZOJ3097 Hash Killer I Solution 考虑它是自然溢出,相当于就是对\(2^{63}\)取膜 那么就有\(aaaaa...aaa\)(多于64个)和\(baaaa...aaa ...
- AJPFX技术分析入门
AJPFX:技术分析入门 技术分析就是指通过考察历史数据来预测未来价格走向.外汇市场是非常讲技术分析的,而且分析师的基本功就是技术分析,但是,没有对基本面的准确把握,技术分析就会含糊.但是技术分析究其 ...
- dapper视频
dapper是dotnet下的一种小巧快捷的ORM框架,本视频主要讲解了dapper的多库使用,以及常见的操作,如:对象查询.多集合查询,关联查询等,添加.修改.删除等. 视频地址:https://w ...