记一个比较诡异的“bug”-快速点击下,ie下面a标签(javascript:void(0))打开新页面

来源:互联网 发布:网络宣传方式有哪些 编辑:程序博客网 时间:2024/05/19 21:01

我们的网站有这么一个功能,是可以选择播放器的皮肤。大概就是右侧有一些缩略图,左侧有一个大图那样子的。

大概就是这个样子,本来这个功能已经上线好久了,但是昨天上了一个相关的功能的时候,我突然发现,在ie下面,快速点击小图的时候,会打开一个新的窗口。

每一个小图的结构是这样子的,a标签包含img,a的href=javascript:void(0),来保证a标签本身没有跳转,同时click的事件是绑定在右侧整个大容器上的,通过事件代理来切换大图。快速点击小图的时候打开的新窗口就是一个空窗口,对应的实际是javascript:void(0),这不科学啊,正常上讲,一个a[href=javascript:void(0)]是不应该点击有反应的。

昨天遇到这个问题的第一反应是,在click的回调函数里面加一个return false, 阻止浏览器的默认行为,结果无效。那换成event.preventdefault()呢?也是不行。百度了一下,有提到用javascript:;的,还是无效,也有使用###的,然后在a标签上加oncllck="return false;"的,试了一下,问题依旧存在。

我又在click的回调里面加了一个console,我发现,在问题出现的瞬间,该出现的console并没有正常输出。昨天我的第一反应是,浏览器在捕获阶段触发了跳转,然后没有触发冒泡。所以我的思路又变成了,jquery事件绑定,绑定在冒泡阶段,就像addEventLister的第二个参数为false一样。查了一下,jquery为了方便,事件绑定是绑定在冒泡阶段的,那问题出在哪呢。

没办法google了一下,然后我发现了这个javascript:void(0)和window.open同时打开了新页面,里面所讲的和我的情况比较类似,也是a标签包含img的情况,他是在a标签上加了一个window.open的回调,结果打开了两个页面。这个问题,作者的回答,大概是因为click除了在a上触发以外,也在img上触发了,要用event.stoppropagation()。这个的意思就是因为冒泡引起的了,我试了一下阻止冒泡,没有用,⊙﹏⊙b汗。

而且上边说过的console表明了,出现问题的时候,根本就没有触发click的回调,在里面加上阻止冒泡也不会执行啊。不信邪的我,又给a标签绑定了回调事件,阻止默认事件,阻止冒泡,都木有生效。把整个事件代理放到a这一层呢?也是没用的。就这样,我折腾了一天。

下午的时候,我在想,会是因为css的问题吗,将页面的css去掉之后,还是不行。那将多余的dom注释掉呢,好像没什么用,把img注释掉呢,咦,问题为什么还是存在,我一直以为是因为a标签套img是这个问题的根源。既然单纯的a标签会有这个问题,那为什么呢?为什么我写的测试对照用的a的列表就没有问题。这俩有啥区别?好像是有问题的a的size比较大,等等,出问题的时候为什么光标的右下角有一个小箭头,我好像知道问题出在哪了。

问题的关键在于,ie下面快速切换点击的时候,可能某一个时刻,点中的时间太长,并且产生了移动,通俗的讲,就是产生了拖动的情况,然后ie下面就会打开一个新的页面,页面的url就是拖动的那个a标签的href也就是javascript:void(0)。怎么去验证这个问题呢,我写了一段脚本,连续切换点击了1000次,没有新页面打开~~~~

我们再回到之前的console的问题上来,即使是因为在捕获阶段触发了跳转而导致后续冒泡阶段的响应不正常没有输出,正常的javascript:void(0)也是不应该会打开一个新页的,之所以没有console出来,只是因为ie认为产生了拖动,没有产生点击罢了。

算是一个比较诡异的“bug”吧

0 0