给知乎加上显示LaTeX公式的脚本

鉴于大半年了,知乎都一直不愿意加上个显示LaTeX公式的功能,最近一次更新也完全没这意思。有时候讨论问题的时候不能显示公式着实不便,就花了点时间写了这么一个脚本工具。在知乎页面上导入MathJax,并且在每次Ajax之后都重新排版下页面上的公式。

顺便一说,Chrome在userscript里真是憋屈,页面上的变量获取起来真难。最后迫不得已只能注入页面脚本了。
知乎页面 http://www.zhihu.com/question/19817384
代码地址在这里 http://userscripts.org/scripts/review/110433
点击这里可以直接安装 http://userscripts.org/scripts/source/110433.user.js

八卦:HTML 5的由来

这篇文章纯属八卦,不过会给出消息来源,可信度尽量保证。

首先要说,HTML5的发展历史,下面引用维基百科上关于HTML5的阐述:

HTML 5草案的前身名为Web Applications 1.0,是在2004年由WHATWG提出,再于2007年获W3C接纳,并成立了新的HTML工作团队。在2008年1月22日,第一份正式草案发布。WHATWG表示该规范是目前仍在进行的工作,仍须多年的努力。目前Firefox、Chrome、Opera、Safari(版本4以上)及Internet Explorer 9(Platform Preview)已支援HTML5技术。

HTML 5的标准草案目前已进入W3C制定标准5大程序的第1步。负责编纂标准格式文件的Google代表Ian Hickson预期,可能得等到2012年才会推出建议候选版(W3C Candidate Recommendation)。

可以看到,这里HTML 5的前身就是WHATWG提出的Web Applications 1.0,要问知道HTML 5怎么来的,进一步要探讨WHATWG这个组织是怎么来的。

根据WHATWG官方FAQ上显示,这个组织最早是由Apple、 the Mozilla Foundation 和 Opera Software 这三家公司,在2004年的时候成立了。那当时到底是谁先发起的,这三家如何纠结在一起的呢?这里我首当其冲猜测是Apple公司勾引了另两家公司。乔布斯狼子野心想通过HTML 5的video标签和canvas标签来灭掉Adobe!苹果和Adobe有恩怨大家都知道~咳咳……似乎04年的时候Adobe还没收购Flash呢,当时还在Macromedia手中呢……呃,那一定是乔布斯那个时候就已经打算灭掉Flash了!嗯!

当时在群里讨论的时候,神飞飘来w3上的一个地址 ,里边提到,最早是由Mozilla基金会和Opera两家公司在一起弄的这个WHATWG组织。Apple是后来才加入进来的。呃………………看来我错怪乔布斯大爷了。但我还有个问题,当年Mozilla和Opera,到底是谁最先勾结对方的呢……

一筹莫展之际,有一个人引起了我的注意,此人就是刚才维基条目中提到的Ian Hickson。此人目前在Google工作。这位仁兄何许人也?仔细一查,发现不得了。在W3C 的 HTML 5 规范中,他就是编辑。而最早WHATWG写的文档,也都是放在Ian Hickson的个人网站上的。看来HTML 5的诞生与此人有着莫大的关系。继续扒一扒他吧。

用Google搜Ian Hickson,第一条就是他维基百科的条目(有其他人为自己建立维基条目,那这人这辈子也值了吧……),原来此人就是大名鼎鼎的 Acid 2Acid 3的作者。在上面找到了Ian Hickson简历的地址。哈哈,基本上找到了事情的全貌了。

================

事情的原委是这样的,自从02年,W3C终于把 XHTML 1.0 的第二版作为推荐标准之后,开始被胜利冲昏了头脑,他们妄图让HTML 完全进化成 XML。在02到06年之间,他们都在使劲折腾XHTML 2.0,这是个完美的标准,完美到与先前“污秽”“肮脏”的HTML完全不兼容。

而Ian Hickson,02年时候刚从英国巴斯大学物理系本科毕业,00年起就在W3C的CSS工作组有活动了。并且大学时起就已经混迹在Mozilla基金会里了。03年的时候受雇于Opera的研发部门,主要工作之一就是作为Opera的代表,在W3C中施加影响,促进标准的推进。

刚才已经说到了,W3C的那帮子天才们太过激进了(以Stephen Pemberton为首),完全无视浏览器厂商的诉求。一次W3C内部会议上,Ian提出对HTML进行一些扩展和改进,跟XHTML2标准制定的工作并行展开。结果投票结果是——“反对”。他们认为HTML已死,XHTML2才是我们的未来!于是,Ian Hickson怀着对W3C深深的忧虑,因爱生恨。干脆自立门户了。由于他本身就在Opera中,又在Mozilla基金会里混的脸熟。很快他们俩家就在Ian的牵线搭桥下,成立了WHATWG组织。后来他们觉得势单力薄,又拉拢了Apple公司一起入伙搞这个标准。

他没把微软拉进来,以及成立WHATWG组织的初衷之一就是为了替Opera公司来牵制微软的IE。很明显IE当时是市场的老大,老二老三老四抱团联合起来对抗老大是再正常不过的事情了。之前他们还可以对W3C施加影响来垂帘听政,现在可好,W3C那帮子疯子以为自己多么了不起了,没浏览器厂商给你们实现标准,你们得瑟个P啊。于是乎,三家人家一拍即合,组团成立一个新的政权,架空W3C的权利,来制衡微软。(其实被架空的只是W3C中的HTML小组,其他的如CSS、SVG之类的小组都还挺好的)

到了05年,Ian跳槽到了Google。Google是很有野心的。自从04年Google推出Gmail起就已经意识到了,自己的未来不能被帮浏览器厂商掌控,自己也要有话语权,也要参与制定标准。雇佣Ian的主要目的恐怕就在于此,一方面Ian代表Google在W3C的CSS小组以及其他小组施加影响,另一方面推进WHATWG的工作。并且Google确实在08年末的时候推出了Chrome,来实现自己的霸业。

06年的时候,W3C终于意识到自己被架空了……HTML的发明者之一Tim Berners-Lee发表了一篇博客,表示我们错了……次年,W3C宣布正式接纳并合并WHATWG的工作为HTML 5。于是乎,后面的事情,大家都知道了。

================
八卦的最后,是两篇扩展阅读:
成长的烦恼 — HTML5 标准之争 这篇会告诉你一些最新的八卦,HTML 5 现在又遇到了什么麻烦了。
HTML5设计原理 这篇会告诉你 HTML 5 如何从实用的角度出发来设计出来的。强烈推荐!!!

Be Pro

我的博客很少有转载的文章,今天难得转一篇,因为文中我也客串了一把,呵呵,并且文中的观点非常认同,所以转载过来,供大家探讨。原文地址:糖伴西红柿的Be Pro

=======================================

最近再次仔细把《HTML5设计原理》重新过了一遍,比起上次粗粗的浏览,收获更多,这篇文章没有任何关于 HTML5 标签、api 的使用的详细解释,而是对其背后的设计原理做了详细说明。这是 HTML5 一切纷繁表象背后的真义,值得每个前端工作者多次阅读。

下午和小飞 @shawphy 讨论一些问题的时候,说到了中文书写里的“的、得、地”地区别。据说现在已经把这三个 de 统一,不做区分了。想想也是,虽然我受教育的时候是区分三者使用的,但是我也一直没弄清楚它们之间的区别。因为最近的一些书写要求,还想趁过年期间回去请教下俺那当了一辈子语文教师的爹来着。

小飞说:“有一种观点认为,语言是活的,随着人们的使用而变化的。如果大部分人都不分了,那也就不要再分了。感觉着就像是HTML5一样。HTML5 很宽容,比如关于属性引号。按理需要有引号,但现在有没有都无所谓了。”

这就不得不提到 HTML5 设计原理其中的一条:“发送时要保守;接收时要开放。” HTML5 以包容的心接受开发者书写的文档,这些文档发送到同样敞开胸怀的浏览器,以使得那些不够标准的文档也可以渲染出来。

与之相对的是已经死去的 XHTML2 ,(呃,突然发现 XHTML 。。。2。想起郭德纲的一句玩笑:“CCTV。。。2,多大的勇气,谁好意思承认这个,人家还写上了。”)XHTML2 是绝对的理想派,要求严格使用 XML 的错误处理模型,也就是遇到一个错误就会停止解析。这对文档书写着的要求得多高啊。当然最为开发者,我们应该遵从最佳实践,尽量保证文档格式的正确。但是谁也不能保证 100% 的正确性,作为开放的互联网,对错误零容忍,导致浏览器无法渲染确实不是那么回事。

尤其是技术就像数码产品,越来越先进,但是价格(门槛)越来越低。我之前有私心,眼看国内一些人对技术的滥用,导致的网上的虚假信息、垃圾信息泛滥,甚至一度希望一些技术应该保有一定的门槛。但是后来想明白了,互联网本身就是开放到,技术生来也应该是服务每一个人的,至于怎么使用,那就要看人自己的选择了。

遵从伯斯塔尔法则(Postel’s Law)的 HTML5 在于完美理想话的 XHTML2 的角力中胜利了。或者应该说是人性再一次取得了胜利,人人追求完美,但是最后还得面对现实。

我们应该看到伯斯塔尔法则其实是同时对发送者和接收者有要求的,”接收时要开放“是对标准和浏览器的要求,而”发送时保守“则是对文档作者的要求。

回到“的 得 地”这个问题。小飞问:”这些坚持 三个 de 不同的人,是不是就好像坚持 xhtml2 的人呢?“ 我认为不然,这些人是选择了发送时保守的“开发者”。不区分这三个 de 的人,如果是普通人,自然无可厚非,但是作为职业的作家,如果无法区分这三者,就算不上好的作家。

同样的产品,不同的工艺就决定了价值的不一样。A货再能以假乱真,也不能和真品等价。同样,作为一名职业的前端工程师,在职业的道路上,我们的选择决定了输出的产品的质量,产品质量反过来也决定了我们自身的价值。

啰哩巴嗦的说了这么多,其实是希望各位前端工程师(其实也可以延伸至各个行业的从业者)能更加专业些,在发送时更加”保守“些。Be pro,这也是 2011 我对自己的要求。

Eric Meyer又更新reset css了

前几天Eric Meyer又思考了一下reset.css的问题,于是有所更新,具体为何要这样做,请看原文Reset Revisited。注意最开始的那句

NOTE: WORK IN PROGRESS
USE WITH CAUTION AND TEST WITH ABANDON

使用需谨慎!


/* http://meyerweb.com/eric/tools/css/reset/
v2.0b1 | 201101
NOTE: WORK IN PROGRESS
USE WITH CAUTION AND TEST WITH ABANDON */

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure,
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: ”;
content: none;
}

/* remember to define visible focus styles!
:focus {
outline: ?????;
} */

/* remember to highlight inserts somehow! */
ins {
text-decoration: none;
}
del {
text-decoration: line-through;
}

table {
border-collapse: collapse;
border-spacing: 0;
}

前端开发中需要用到的变换矩阵

想写写关于矩阵变换的博文已经想了很久了,今天看到 winter 写的一篇博客CSS3:transform与transition背后的数学原理,于是就促成了本文。注意,下面的演示内容需要现代浏览器支持。比如Chrome/Firefox/Opera。阅读器中无法看到演示。

矩阵是线性代数中的内容,在计算机图形学中就拿来做矩阵变换。在以前,对于前端工作来说,几乎用不到矩阵变换。然而,随着浏览器的进步,HTML5和CSS3的普及,对于前端可以操作的东西越来越多,于是,矩阵变换也出现在视野当中了。

矩阵变换,听起来是一个挺高级的东西,其实本质上只不过是把一系列简单的数学运算给包装一下,赋予一个比较华丽和高深的外表而已。如果你之前没有接触过矩阵运算,也不用慌,跳过下面矩阵公式,直接看每条后面的黑体字公式即可。这些公式仅仅涉及高中水平的加减运算和三角函数而已。除了最开始的时候我会搬出那个矩阵,之后的讨论我会避开矩阵的公式,直接用容易理解的方式阐述问题。

最早浏览器中支持的矩阵变换可能是在SVG的标准中。之后跟图形带点边的CSS 3以及HTML5的Canvas中也有了矩阵变换,当然强大的Flash以及Flex中也有变换矩阵。他们的基本原理都是一样的。目前2D的矩阵变换已经有不少浏览器支持了,而3D的变换还需时日。

说了半天矩阵变换,其实本质上来说,一个元素渲染后就可以得到一张位图,然后对这个位图上每一点进行变换,就可以得到新的一张位图,从而产生平移、缩放、旋转,切变以及镜像反射等效果了。

基本公式

目前不论是SVG也好,CSS 3也好,还是Canvas,2D的矩阵变换都提供了6个参数a b c d e f,其使用基本公式是这样的:

其中,x和y是元素最开始的坐标,x’ 和y’则是通过矩阵变换后得到新的坐标。
通过中间的那个3×3的变换矩阵,对原先的坐标施加变换,就能得到新的坐标了。

注意!a b c d e f几个参数的排列方式,是竖着排的,网上有不少文章排列方向有误。

根据矩阵乘法的运算法则,上面的矩阵式子可以化成下面的两个式子

x’=ax+cy+e
y’=bx+dy+f

也就是说,别看上面有那么一大坨的东西,本质上就是上面这两条简简单单的公式而已。之后的讨论中,我将围绕着上面的两行来讨论,而不再涉及矩阵的内容了。

平移

原始位置
平移120px, 50px后

如果调用时提供参数matrix(1,0,0,1,tx,ty),即a=d=1,b=c=0,那么上面的式子就简化成

x’ = 1x+0y+tx = x+tx
y’ = 0x+1y+ty = y+ty

很容易看到,这里就是在原先x,y的基础上进行平移,变成x+tx,y+ty点而已。非常简单。如果数学上讲,tx和ty就好比是Δx和Δy。

x’ = x+Δx
y’ = y+Δy

CSS 3中的transform: translate(tx, ty);就等价于transform: matrix(1,0,0,1,tx,ty);注意,使用matrix的时候不需要单位,默认是px,而translate需要单位,可以是px、em之类的单位。

缩放和拉伸

原始大小
长宽放大1.5倍

如果调用时提供参数matrix(Sx,0,0,Sy,0,0),即a或d不等于1,比如a=Sx,d=Sy而b=c=e=f=0,于是公式简化成

x’ = Sx*x+0y+0 = Sx*x
y’ = 0x+Sy*y+0 = Sy*y

可以想到,这个操作,实际上是让x的坐标扩大Sx倍,而y的坐标扩大Sy倍。
这主要是用来让元素进行缩放效果的。如果Sx和Sy大于1,则是放大,而Sx和Sy小于1,就是缩小了,如果等于1,那就是保持原状了。并且,由于x方向和y方向是相互独立的,所以可以一个方向放大,另一个方向缩小。
上面的那个例子中,我设置的m和n都是0.5,于是图形长宽就各缩小了一半。另外,值得注意的是,他是以元素的中心作为缩放的基点的,而不是左上角。
CSS 3中的transform: scale(Sx, Sy);就等价于transform: matrix(Sx,0,0,Sy,0,0);

旋转

原始方向
旋转37°

这里用到的就相对高级一些了,需要使用三角函数的一些知识了
如果调用时提供参数matrix(cosθ,sinθ,-sinθ,cosθ,0,0)

x’ = x*cosθ-y*sinθ+0 = x*cosθ-y*sinθ
y’ = x*sinθ+y*cosθ+0 = x*sinθ+y*cosθ

由于计算机图形学中,通常向右为x轴正方向,向下为y轴正方向,所以这里的θ表示元素绕坐标原点顺时针旋转的角度。而这里的原点不是元素的左上角,而是元素的中心点。
上面的例子中,我把一个div顺时针旋转了37°,cos37°=0.8,sin37°=0.6,所以提供的矩阵的参数就是 matrix(0.8,0.6,-0.6,0.8,0,0)
CSS 3中,transform:rotate(37deg)就等价于我上面的那个变换了。注意CSS 3中的角度必须带单位 deg。好处是不用自己算sin和cos值了。

切变

x方向倾斜45°

切变,就是把一个元素往某一个方向倾斜一定的角度。传入的参数应当是matrix(1,tan(θy),tan(θx),1,0,0)

x’ = x+y*tan(θx)+0 = x+y*tan(θx)
y’ = x*tan(θy)+y+0 = x*tan(θy)+y

这里的θx和θy分别代表往x正方向和往y正方向倾斜的角度,两者是相互独立的。上面的例子中,我把元素往x方向倾斜了45°,因此他的tan(θx)=1
CSS 3中的transform: skew(θx, θy);就等价于transform: matrix(tan(θx),0,0,tan(θy),0,0); 如果使用skew的话,直接使用角度即可,但必须带单位deg,比如上面的例子用矩阵的话写成transform: matrix(1,0,1,1,0,0);等价于 transform: skew(45deg, 0);

镜像反射

镜像对称
镜像对称

镜像反射就是指元素对某一条直线做镜像对称。最基本的情况是可以对经过原点的某条直线进行反射。定义(ux,uy)为直线方向的单位向量。也就是说,如果直线方程是y=kx,那么ux=1/sqrt(1+k^2),uy=k/sqrt(1+k^2)
那么对这种镜像反射变化时传入的参数应当是
matrix(2*ux^2-1,2*ux*uy,2*ux*uy,2*uy^2-1,0,0)
于是最终的方程

x’ = (2*ux^2-1)*x+2*ux*uy*y
y’ = 2*ux*uy*x+(2*uy^2-1)*y

上面的例子中,就是对y=2x这条直线进行的镜像对称。CSS 3中目前没有简化的规则与之对应。

至于如何对一条不过原点的线对称,则需要设置原点所在的坐标了。由于默认情况下,原点坐标是这个元素的中心,如果改变了原点的坐标,就可以改变对称的直线,当然也可以改变前面所有效果的呈现方式,CSS 3中使用transform-origin方法修改坐标原点的位置。

最后,如果你想要玩的更High点,买本计算机图形学的书来看是不可避免的,这篇文章也仅仅是个皮毛而已。希望对你有所帮助。

扩展阅读

前端观察,你需要知道的CSS3 动画技术
维基百科中关于矩阵变换的条目
理解矩阵(1)
理解矩阵(2)
理解矩阵(3)
w3 文档,关于坐标系以及矩阵变换属性
w3 文档,SVG中的3D变换矩阵
w3 文档,CSS 3中的3D变换矩阵,基本跟上一条的差不多

CSS通用元素选择器的都市流言

本文尚未有测试数据支持,以下结论仅是根据现有情况的一种解释。

关于 * 这个选择器,一直有个疑惑,到底是否影响效率。在先前的观念中,这由于要匹配所有的元素,让每一个元素都带上这个属性,所以会影响页面的效率。但近来的思考,觉得这应该不会影响效率。为此还特地写过一篇博文,里边提到了这点:真的还需要reset.css么?

而这篇文章中我打算着重阐述为何 * 这个选择器不会影响效率。

上周六去参加了 web标准化交流会,席间 winter 从浏览器(webkit)的角度分享了关于页面渲染的过程。其PPT也可以在前面的链接中下载到。

其中一个很重要的过程是,当页面载入过程中,CSS 和 HTML 是并行下载的。并且通常CSS是在HEAD中引入的,并且体积不如HTML大,所以CSS会先下载完。下载的过程中浏览器就已经开始对CSS中的规则进行索引,也就是已经确定哪一个元素呈现的样式是如何的了。同时,浏览器根据HTML构建出的DOM树,其中的每一个元素会直接去CSS规则索引中去比对,构建出渲染树。这个过程都是并行的,并且CSS规则是进行了索引的,因此速度非常的快速。

那么我们看看CSS规则的来源主要有2个,一是浏览器内置的元素样式,Firefox 3.x版是放在目录下的res文件夹内,4.0版和Chrome中没找到(这里是我的主观臆断不太可靠,大家自行辨别),另一个就是页面提供的。根据查看 放在 res 文件夹下的 CSS 文件就可以得知,就是是什么样式都不写,已经为每一个HTML元素设定好了基本样式了。

那么看看我们所忌讳的事情,不用*{margin:0;padding:0},而是使用

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
}

看看这一大坨东西啊,难道不是跟上面的 * 选择器一个用途么?对每个元素(至少是常用元素),添加样式。其实作用是一样的,并且就算没有这一坨,浏览器内置样式也在对每个元素设置样式。之后 HTML 文件中的每一个元素,可以很容易找到自己应当呈现的样式了。

那么,对于之后添加的,会不会有性能影响呢?也不会,由于CSS规则已经确定并索引了,所以今后增加的元素也不过就是简单比对一下而已,不会多走一步的。

所以,由此得出结论,只要有需要,大胆的使用 * 吧,他不会给你从性能上增加额外的麻烦。

最后补两个前端优化小知识:
1,由于CSS规则和HTML是并行载入的,因此把CSS放在HEAD中是非常有必要的。
2,少使用 :last-child 。因为这个选择器无法索引起来,必须等DOM构件完,才能知道他是不是父元素中最后的那个 元素。这种就非常慢了,慎用。

jQuery.delay()方法简介

之所以说简介,就是因为这个方法真的很简单。这个方法从 jQuery 1.4 开始加入进来。中文文档中也早就有了,但是悄悄的添加进去的,很不起眼,不容易引起人的关注。

两年前写过一篇文章,介绍一个叫wait的插件,而在 jQuery 1.4中就把这个插件吸收进去了,成为了核心API了。

用法很简单,直接使用

$(‘#foo’).slideUp(300).delay(800).fadeIn(400);

这样的一句话,就可以在两次动画之间间隔800毫秒了。非常方便。

他除了可以控制动画之外,还能控制自定义队列:

delay(duration, [queueName])

第二个参数就是设置队列名的,如果不填,默认就是动画队列 fx。

介绍完啦,非常简单把?如果有兴趣,可以看看jQuery.delay()文档,以及jQuery中queue和dequeue的用法,或者看看如何自己写个控制队列来了解基本原理。