记一次解决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定位的学习. 通过我们前面的学习,我们网页布局方法: ...
随机推荐
- 重建控制文件ORA-12720
重建过程出错:ORA-01503: CREATE CONTROLFILE failedORA-12720: operation requires database is in EXCLUSIVE mo ...
- spring之jdbcTemplate
spring的另一个功能模块data access对于数据库的支持 spring data access第一个helloword案例: 使用java程序实现访问配置 1.导包 2.测试案例 @Test ...
- 关于python logging的 NOTSET 级别
说重点: NOTSET 意指不设置 所以按照父logger级别来过滤日志 注意 不是最低级别的意思 由于logging中root日志对象的默认级别是WARNING, 所以当你使用logging.get ...
- springJDBC和SpringJDBCTemplate解决方案探究
先来看一个纯JDBC的例子,体会一下springJDBC和SpringJDBCTemplate两者的区别 一个Customer类 package com.mkyong.customer.model; ...
- 最大m段子段和
hdu1024 最大m子序列和 给定你一个序列,让你求取m个子段(不想交的子段)并求取这m个子段和的最大值 从二维开始来看dp[i][j]表示取第j个数作为第i个子段的元素所得到的前i个子段和的最大值 ...
- mysql变更数据的捕获和入库
问题:涉及状态的信息,mysql中是update的,缺少中间状态的记录.数据分析中需要这部分数据. 思路:后端服务通过监控某张表的某个字段,根据mysql的binlog文件,还原数据,发送到kafka ...
- 4.update更新和delete删除用法
一.update更新 UserMapper.java package tk.mybatis.simple.mapper; import org.apache.ibatis.annotations.Pa ...
- Android-HttpClient-Get请求获取网络图片设置壁纸
第一种方式使用httpclient-*.jar (需要在网上去下载httpclient-*.jar包) 把httpclient-4.5.jar/httpclient-4.4.1.jar包放入到libs ...
- Winform文件上传
近期在做了一个winform的项目的附件上传的需求 最初项目选型的时候有三种 1.使用webservice.webapi上传文件 2,直接保存在数据库中 3.使用共享目录+dos命令 第一种有文件大小 ...
- Linux系统磁盘与分区管理(7)
Linux最传统的磁盘文件系统(filesystem)使用的是EXT4格式,所以要了解文件系统就得要由认识EXT4开始,而文件系统是创建在硬盘上面的,因此我们得了解硬盘的物理组成才行,下面我们回来详细 ...