IE filter & z-index bug

对最近遇到的2个问题的一点总结。

1.IE filter & z-index

重构后的首页即将上线,测试提出fix导航条扩展菜单在ie789滚动后一段无法显示的问题。

疑云重重:

这个问题一开始一度以为是fix本身的bug,因为之前顶部的滚动切换是写成了500固定值,并没留意到bug触发真正机理,加之fix在ie低版本确实存在一些问题,但是base库中tb函数本身并不存在问题。

之前的扩展菜单都是用js动态去算位置,个人觉得这样滥用js是极为不好的,使用css来制作,扩展菜单是作为主菜单的子元素一部分,给予扩展菜单相对主菜单绝对定位即可,css可以很好的实现它,并且代码也更加优美。

初步猜测:

昨个自己优化复测时发现在平板竖屏下,由于slider高度变得较小,如果再滚500再触发感觉就体验较差(本来想把关联设定成可自定义的元素,不过为了避免近期改动较多暂时搁置)。

由于改了这个数值后,当再次检测这个Bug时,可以清晰发现就是在触发scroll切换导航条class后发生了这个bug。

如果研究过ie filter的机制就马上能想到原因了,不了解的可以拿透明边框(ts)在ie6下测试,能更好的理解filter的镂空原理。

故而想到了,因为是后来触发了filter,而触发filter的时候,此时display:none的扩展菜单被直接镂空处理了,而箭头是用伪元素制成的,可以看出来伪元素不受影响?

感谢斌哥一起帮忙耐心测试。到这里,我以为:ie filter处理,针对自身元素,包含子元素,但不包括伪元素。当有hide/show切换的子元素时,会造成该元素镂空。

豁然开朗:

正好周末回家,准备再次梳理一下,打开test再次测试,却发现远不是那么简单。

例如我们写一个父元素,父元素为半透明,有应用filter,里面装个子元素,子元素通过位移离开父元素的元素占位区间。

测试结果1:子元素默认可见,通过margin位移,此时,尽管子元素并没有display:none,它依旧无法显示,包括伪元素。

测试结果2:子元素默认可见,通过绝对定位位移,表现正常,包括伪元素。

测试结果3:子元素默认隐藏,通过绝对定位位移,表现正常,包括伪元素。

到这里为止我们可以确定,其实ie的filter只是自身平面上元素,而绝对定位的子元素并不受影响,也就是说和display:none没有半毛钱关系。

对比线上案例,线上案例就是绝对定位呀,为什么却不显示呢,并且箭头,伪元素是显示的。

打开IE11审查工具测试可知,js操作正常,扩展菜单也确确实实存在,取消父级filter确实就能显示了,但这和本地的测试并不一致。

冥思苦想片刻,这并不是上面推理出来的结论错误。

注意到父级是有设置z-index的,惊奇的发现,这个现象和父级与子级的z-index并没有半毛钱关系,不论数学逻辑关系如何,关键是父级有设置z-index时,则回到测试结果1的现象。

最后查一下stackoverflow和google,终其原因还是filter与z-index的渲染绘制冲突原因。

虽然其他童鞋给出了其他可以参考的解决方案,但是我认为最佳的考虑方案还是直接上png半透明背景图。

http://tagsoup.github.io/blog/2011/12/29/ms-filters-make-me-hate-life-memoirs-of-a-fe-ender/

http://stackoverflow.com/questions/13780124/z-index-or-overflow-issue-on-a-css-menu-with-gradient-background-in-ie-9

http://www.telerik.com/forums/menu-z-index-issue-ie-8-and-9

2.display:none 与 visibility:hidden

还是上面的菜单,由于考虑兼容的问题,必须js动态给予扩展菜单宽度。

由于本身扩展菜单宽度实际上只能是等同于主菜单,并且由于每个li的宽度并不一致,我们通过css设置禁止折行后,需要逐一获取每个li单元的宽度累加。

但是如果菜单默认是display:none的话,则所有的css属性为空,转换为数值后则为0,则无法正常渲染,除非这个行为发生在show的回调函数中,但是如果写在show的回调中,菜单的内容会逐一蹦出来,这也不是我们要的效果。

故,部分类似情况下,应用hidden代替none。

时间: 2024-11-20 15:42:04

IE filter & z-index bug的相关文章

AngularJS最佳实践: 请小心使用 ng-repeat 中的 $index

"有客户投诉,说在删除指定的某条记录时,结果删掉的却是另外一条记录!" 看起来是个很严重的BUG. 有一次我们在工作中碰到了这个问题. 要定位这个BUG非常麻烦, 因为客户也不清楚如何重现这个问题. 后来发现这个Bug是由于在 ng-repeat 中使用了 $index 引发的.下面一起来看看这个错误是如何引发的, 以及如何避免这种bug产生,然后说说我们从中得到的经验和教训. 一个简单动作(action)的列表 先来看看一个完整有效的ng-repeat示例. <ul ng-co

请小心使用 ng-repeat 中的 $index

一个简单动作(action)的列表 先来看看一个完整有效的ng-repeat示例. <ul ng-controller="ListCtrl"> <li ng-repeat="item in items"> {{item.name}} <button ng-click="remove($index)">remove</button> </li> </ul> 对应的控制器(con

Java Web之Filter

Filter被称为过滤器或者拦截器,基本功能就是对调用servler过程的拦截,在servlet进行响应和处理前后实现一些特殊功能.其实,Filter过滤器就是一个实现了javax.servlet.Filter接口的类,在javax.servlet.Filter接口中定义了3个方法: init(FilterConfig filterConfig) : 用来初始化过滤器,可以在init()中完成与构造方法类似的初始化功能,如果初始化代码中要使用FilterConfig对象,那么,这些初始化代码就只

jQuery -&amp;gt; filter使用方法

利用filter函数能够从wrapper set中过滤符合条件的DOM元素. 假设我们有一个内容例如以下的html文件,要获取类为external的<a>元素,使用filter能够非常easy地搞定. <a href="#" class="external">link</a> <a href="#" class="external">link</a> <a hr

jquery中filter的用法

一.filter的参数类型可分为两种 1.传递选择器 $('a').filter('.external') 2.传递过滤函数 $('a').filter(function(index) {        return $(this).hasClass('external');    }) 二.Jquery中find与filter区别 1.find()会在div元素内 寻找 class为classname的元素.2.filter()则是筛选div的class为classname的元素.3.基本是f

当filter使用函数而非选择器来过滤元素时的一个有趣的地方

JQuery官方API关于filter方法的介绍有这么一个实例: <div id="first"></div> <div id="second"></div> <div id="third"></div> <div id="fourth"></div> <div id="fifth"></div

jQuery-过滤not()与filter();

$(function(){ $("li").not(":even").css("color","red"); $("li").filter(":odd").css("color","red"); }) $(function(){ $("li").filter(function(index) { return index%2 ==

Filter技术+职责链模式

Filter是一个过滤器,存在Web客户端与请求的资源之间,这里的资源可以说是jsp或servlet.它的作用就是在请求达到资源之前,先对请求进行预处理,并且也可以对servlet处理后的response进行修改. Filter可以是有很多个,当一个个Filter组合成起来,就形成了一个FilterChain.也就是我们说的过滤链,这个过滤链处理的过程,就是我们前面学的职责链模式的一个体现. 下面是一个修改字符串的小例子: 1.FilterChain内包含各个子filter,利用dofilter

jQuery filter函数使用方法

利用filter函数可以从wrapper set中过滤符合条件的DOM元素. 如果有一个内容如下的html文件,要获取类为external的<a>元素,使用filter可以很easy地搞定. <a href="#" class="external">link</a> <a href="#" class="external">link</a> <a href=&q

[ jquery 过滤器 filter(expr|obj|ele|fn) ] 筛选出与指定表达式匹配的元素集合,这个方法用于缩小匹配的范围,用逗号分隔多个表达式

筛选出与指定表达式匹配的元素集合,这个方法用于缩小匹配的范围,用逗号分隔多个表达式 当参数是函数时,函数里面的参数解释如下: 一个函数用来作为测试元素的集合.它接受一个参数index,这是元素在jQuery集合的索引.在函数, this指的是当前的DOM元素 实例:<!DOCTYPE html> <html lang='zh-cn'> <head> <title>Insert you title</title> <meta http-equ