惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
U
Unit 42
N
Netflix TechBlog - Medium
人人都是产品经理
人人都是产品经理
Hugging Face - Blog
Hugging Face - Blog
腾讯CDC
小众软件
小众软件
V
Visual Studio Blog
T
Tailwind CSS Blog
Engineering at Meta
Engineering at Meta
博客园 - 叶小钗
GbyAI
GbyAI
爱范儿
爱范儿
雷峰网
雷峰网
Microsoft Azure Blog
Microsoft Azure Blog
D
DataBreaches.Net
博客园_首页
D
Docker
A
About on SuperTechFans
G
Google Developers Blog
I
InfoQ
T
The Blog of Author Tim Ferriss
V
V2EX
博客园 - Franky

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活
了解web前端领域的undefined behavior未定义行为 « 张鑫旭-...
张鑫旭,zhangxinxu · 2015-04-18 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=4747

一、本文为超短篇

undefined behavior可以算是计算机世界中特有的一个名字,中文意思是“未定义行为”,维基百科上有解释。在C以及C++语言中,这可以算是一个比较明确的概念:

undefined behavior: use of an unspecified value, or other behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance

实际上,在web前端领域,也有undefined behavior未定义行为,且广泛程度远远超出了你的想象。

undefined behavior从web标准出现之后,实际上就广泛存在web网页前端技术中,我们很多时候遇到的浏览器兼容性问题,可能就属于undefined behavior。粗读这句话,好像web标准干了什么坏事。实际上并不是,在web标准没出现之前,很多浏览器都有各自的行为表现,我们称之为兼容性问题,但是,这不能称之为undefined behavior未定义行为。为什么呢?因为没有一个标准作为依据,未定义行为之所以称之为未定义行为,就是因其游离于标准之外。我们换种说法可能更好理解,undefined behavior又可以理解为法律空白。你要先有法律,才有法律空白。在法律界,典型的未定义行为就是「同性性侵」。所以伪娘深夜更不能独行,否则被占了便宜还不能法制了色狼,亏大了。

web标准的出现让浏览器间的行为越来越统一,做出了非常重要的贡献。基本上,在现代浏览器中,支持先后这个不算,就一般的CSS或JS,我们通常使用都没有兼容性问题。但是,凡事可能会发生的事情一定会发生。对于IE/Chrome/FireFox三大家族浏览器,一旦发现某个浏览器跟其他两个不一样,我们的反应可能会这样:

  1. 如果是IE使性子,和Chrome和FireFox表现都不一样,我们会认为IE出bug了!
  2. 如果是Chrome耍大牌,跟IE和FireFox表现不一样,我们会替Chrome辩护(就像下面这样的评论,来自这里)
    为Chrome浏览器辩护
  3. 如果是FireFox闹脾气,跟IE和Chrome表现不一样,我们会略同情,FireFox你怎么了,你不再振作怎么跟其他浏览器抗衡啊!

一旦货比三家,发现某一户跟其他所有人家都不一样,其实,我们更多地是认为这个搞特殊的浏览器出bug了!鄙人其实就这么认为了,汗~

但是,自动了解了undefined behavior未定义行为之后,我发现我之前的认知有些狭隘了。“Chrome absolute绝对定位display/visibility渲染bug”一文中提到的问题可能并不是bug,而只是“未定义行为”,也就是web标准并没有详细描述此时的行为表现,而Chrome浏览器根据自己的理解或者规则去处理了(无重绘、更高性能),人家只是在规则允许范围内做了点个性的事情,怎么能就叫人家bug呢!!当然,可能属于未定义行为,只是可能,我还是觉得是Chrome浏览器自己的问题。

但是,下面这个浏览器差异现象,我99%确信是“未定义行为”,一起来看下吧!

二、FireFox浏览器下“未定义行为”一则

我们都知道,CSS中有个伪类:active, IE9+之后的浏览器行为表现非常统一,鼠标按下,执行:active伪类对应的CSS样式,鼠标抬起还原。于是,我们可能很轻松地实现鼠标按下的效果(老IE浏览器失焦效果样式还原)。例如,下面这个红色区域,按下会变色,抬起又恢复:

按我

这个伪类是没有任何问题的,但是,当遭遇其他一些处理的时候,事情就会变得不一样,什么事情呢?

假设此按钮的DOM对象变量名为button, 则我们写一个小脚本,例如:

button.addEventListener("mousedown", function(event) {
    // 此处省略N行
    event.preventDefault();	
});

上面这段脚本,连不是圈子里的我的夫人都知道意思,就是按钮在按下的时候,阻止默认行为(这样拖动的时候就会很流畅)。

看似平淡无奇,但是,最后发生了不和谐的事情:IE和Chrome浏览器,:active伪类依然活蹦乱跳,但是,FireFox浏览器的:active伪类样式阵亡了,鼠标按下去没有UI变化!

百闻不如一见,您可以狠狠地点击这里:FireFox mousedown preventDefault使active伪类失效Demo

demo页面中,上一个按钮就是很普通的CSS按钮,下面一个按钮,CSS部分跟上面一样,但是,实际上,其被JS给玷污了下,绑定了个mousedown事件,同时还阻止了默认行为。但是,IE和Chrome浏览器,上面两个按钮点击都很开心,但是,FireFox浏览器,下面这个按钮,按下效果木有啦!

FireFox浏览器按下没有效果

这里,FireFox和IE, Chrome浏览器表现不一样,这是FireFox浏览器的bug吗?亲,这可不是bug, 而是w3规范上并没有对这种场景的具体描述,所以,FireFox认为active发生在mousedown事件之后,你也不能说他什么,对吧。就好像篮球比赛,我领先,我就用完24秒再出手,怎么着,你来咬我啊!

对吧,你不能说FireFox浏览器的不是,最多我们道德上谴责她,回头呢,我们还得老老实实想办法打个小布丁,例如,判断是FireFox浏览器,然后加个类名active(见下代码红色高亮)(移除类名active脚本略),CSS中再多个.active的样式:

button.addEventListener("mousedown", function(event) {
    // 此处省略N行
    if (typeof document.mozHidden != "undefined") this.classList.add("active");
    event.preventDefault();	
});

三、结语

昨晚看了部电影《地球上的星星》,上帝关上一扇门,也会关掉另外一扇。

地球上的星星

我平时话少,跟话痨相加,正好100%。但是,写东西时候,话却很多。下笔写标题时候,我真觉得几百字就结束了,结果,一写不可收拾,从预想的超短篇变成了短篇出头一点点。

擦,我在干什么,又在瞎扯淡了。速速结语……

结语就是没有结语!

本文为原创文章,包含脚本行为,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=4747

(本篇完)