记一次解决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定位的学习. 通过我们前面的学习,我们网页布局方法: ...
随机推荐
- C++指针一
指针也是变量,占有内存空间,用来保存内存地址. 指针也是一种数据类型,指针是一种数据类型,是指它所致内存空间的数据类型. 指针变量和它指向的内存块是两个不同的概念 *p操作内存 在指针声明时,*号表示 ...
- 有趣的HTML5 CSS3效果
iphone6 外观:http://www.html5tricks.com/demo/css3-iphone6/index.html 天气图标:http://www.html5tricks.com/d ...
- Reorder the Books -- hdu -- 5500
http://acm.hdu.edu.cn/showproblem.php?pid=5500 Reorder the Books Time Limit: 4000/2000 MS (Java/Othe ...
- (数学)Knight's Trip -- hdu -- 3766
http://acm.hdu.edu.cn/showproblem.php?pid=3766 Knight's Trip Time Limit: 2000/1000 MS (Java/Others) ...
- java注解学习(1)注解的作用和三个常用java内置注解
今天,记录一下自己学习的关于注解方面的知识. Annotation是从JDK5.0开始引入的新技术 Annotation的作用: -不是程序本身,可以对程序做出解释(这一点和注释没什么区别) -可以被 ...
- Java Map释放内存置null以及调用clear()的区别
今天自己在总结map的时候,想到了在释放Map对象空间的时候就有使用过将Map对象置null,也有时候会调用clear()将Map中的数据清除,那么它们都有什么区别呢? Map<Integer, ...
- jQuery插件初级练习2答案
html: $.font($("p"),"30px").html("变化了") jQuery: $.extend({ font:functi ...
- ASP.NET MVC5 高级编程-学习日记-第一章 入门
1.1 ASP.NET MVC 简介 ASP.NET是一种构建Web应用程序的框架,它将一般的MVC(Model-View-Controller)模式应用于ASP.NET框架. 1.1.1 MVC模式 ...
- 纸壳CMS主题增强,支持主题中加入模板
背景 在之前,纸壳CMS的主题仅仅只是CSS样式,并不支持在主题下使用模板来构建不同的HTML结构.现在我们对主题功能做了增强,可以在主题下添加各自的模板,这样在制作主题时,就会更加自由.不仅如此,新 ...
- 堆排序(大顶堆、小顶堆)----C语言
堆排序 之前的随笔写了栈(顺序栈.链式栈).队列(循环队列.链式队列).链表.二叉树,这次随笔来写堆 1.什么是堆? 堆是一种非线性结构,(本篇随笔主要分析堆的数组实现)可以把堆看作一个数组,也可以被 ...