Actually,simplicity is not simple

JS中函数调用的奇异写法

今天看不到一JS代码很是奇异,很久后才明白它的意思,佩服写这Coder,

$('#tip')[['show','hide'][$.getCookie('tip')]]();

这代码是基于jQuery的,要理解就得知道拆分,$('#tip')是jQuery的选择器,$.getCookie('tip')是使用jQuery的Cookie的插件,返回的是数值0、1,这些都不用多说。

主要看这部分[['show','hide'][1]](),如何拆呢?这也是让我想了一段时间的原因,如果作者这样写相信很多人一下就能明白。

$('#tip')['show']();

这不就是使用数组的方式调用函数嘛!再看中间[['show','hide'][1]],这下就明白了,只不是个数组吧了!

这代码的全意就是将一个jQuery的object的两个属性创建了一个数组,然后由$.getCookie('tip')的值进行选择,再应用jQuery的函数。拆分为一般的写法就像下面这样:

$.getCookie('tip') ? $('#tip').hide() : $('#tip').show();

有点绕,呵呵,但对于熟悉JS的调用很好处!

读Cross-Browser Inline-Block后的笔记

看到一篇很讲解inline-block的文章,相当不错,能在所有浏览器上使用,记录下。

比如有以下的HTML结构,想让其平行的显示:

<ul>
    <li>
        <img src="http://studynote.cn/blog/wp-content/themes/Asinsimple/images/logo.png" alt="简单其实不简单" />
        <h4>This is awesome</h4>
    </li>
    <li>
        <img src="http://studynote.cn/blog/wp-content/themes/Asinsimple/images/logo.png" alt="简单其实不简单" />
        <h4>This is awesome</h4>
    </li>
……
</ul>

一般说来,这种类型的布局是小菜一桩。固定宽度,固定高度,向左浮动就解决了,理想中的CSS代码如下:

li {
    width: 200px;
    min-height: 250px;
    border: 1px solid #000;
    display: inline-block;
    margin: 5px;
    vertical-align: top;
}

事实上上面的代码在 Firefox 3, Safari 3 和 opera 中的效果没有问题,就算

中的文字发生变化也能有很好的效果。但IE6、IE7、Firefox2 就没那么好了,全都乱七八糟的。 原文中介绍了如何解决这些问题,涉及到了很多CSS的知识点,其原文的HTML结构如下:

<ul>
    <li><div>
        <img src="http://studynote.cn/blog/wp-content/themes/Asinsimple/images/logo.png" alt="简单其实不简单" />
        <h4>This is awesome</h4>
    </div></li>
    <li><div>
        <img src="http://studynote.cn/blog/wp-content/themes/Asinsimple/images/logo.png" alt="简单其实不简单" />
        <h4>This is awesome</h4>
    </div></li>
……
</ul>

CSS如下:

li {
    width: 200px;
    min-height: 250px;
    border: 1px solid #000;
    display: -moz-inline-stack;
    display: inline-block;
    vertical-align: top;
    margin: 5px;
    zoom: 1;
    *display: inline;
    _height: 250px;
}

这段CSS解决了IE6、IE7、 Firefox2不支持inline-block的问题。做下笔记吧!自己的学习还是不到家啊!

  1. 使用display: -moz-inline-stack;属性解决 Firefox2 不支持inline-block的问题,但又带来了新的问题(所有FF对于所有的属性为stack(包括-moz-inline-stack)的元素,它的第一级子元素会继承该元素的宽度和高度,但是子元素的子元素不会再继承)。解决的办法是在DIV内加入个新的标签,但就我个人而言完全没有这个必要,99.9%的使用Firefox用户都是勤于更新版本的。
  2. 使用zoom:1;激发IE的 hasLayout 属性, 再加上*display:inline;之后,在 IE7 中它们就可以像 inline-block 一样显示了(其实我对这方面的了解也不多,还没有理解,所以写不出达多的文字)。还使用了display: inline;这一属性,display前面加个星号()的写法是用来区分于其它浏览器的,*display这种写法只有IE7以下的浏览器才能支持。
  3. 使用 _height: 250px; 解决IE6不支持min-height属性的问题,因为IE6 对 height 属性的不正确处理(即当内容的高度超过了容器设置的高度后,IE6会自动改变窗口的高度),使得我们可以这样使用。_height这种法写只有IE7以下的浏览器才能支持。

综上我认为比较好的写法是不考虑Firefox2的问题,

<ul>
    <li>
        <img src="http://studynote.cn/blog/wp-content/themes/Asinsimple/images/logo.png" alt="简单其实不简单" />
        <h4>This is awesome</h4>
    </li>
    <li>
        <img src="http://studynote.cn/blog/wp-content/themes/Asinsimple/images/logo.png" alt="简单其实不简单" />
        <h4>This is awesome</h4>
    </li>
……
</ul>

li {
    width: 200px;
    min-height: 250px;
    border: 1px solid #000;
    **display: inline-block;**
    vertical-align: top;
    margin: 5px;
    **zoom: 1;**
    ***display: inline;**
    _height: 250px;
}

原文地址:http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/

译文地址:http://www.qianduan.net/cross-browser-inline-block.html

有些涉及到的知识点可以阅读以下文章:

区分浏览器的 hack:http://www.ejeliot.com/blog/63

IE hasLayout:http://adamghost.com/2008/12/ie-haslayout-详解/

PS:从上面可以知道想让现有浏览器都支持display:inle-block;可以这样写:

span{display: inline-block;zoom:1;*display:inline;}

CSS的优先权

优先权问题其实就是一个冲突解决的问题,当同一个元素(或内容)被CSS选择符选中时,就要按照优先权取舍不同的CSS规则,这其中涉及到的问题其实很多。

首先就是CSS规则的specificity(特殊性),CSS2.1有一套关于specificity的计算方式,用一个四位的数字串(CSS2是三位)来表示,最终specificity越高的规则越特殊,在优先级判定时也就越有优势。关于specificity的具体计算在各种情况下的数字加成有如下一般规则:style

  • 每个ID选择符(#someid),加 0,1,0,0。
  • 每个class选择符(.someclass)、每个属性选择符(形如[attr=”"]等)、每个伪类(形如:hover等)加0,0,1,0
  • 每个元素或伪元素(:firstchild)等,加0,0,0,1
  • 其他选择符包括全局选择符*,加0,0,0,0。相当于没加,不过这也是一种specificity,后面会解释。
  • 按这些规则将数字串逐位相加,就得到最终计算得的specificity,然后在比较取舍时按照从左到右的顺序逐位比较。

举一些例子吧:

[CSS]
h1 {color: red;}
/* 只有一个普通元素加成,结果是 0,0,0,1 */
body h1 {color: green;}
/* 两个普通元素加成,结果是 0,0,0,2 */
/*0,0,0,1 小于 0,0,0,2 ,后者胜出*/

h2.grape {color: purple;}
/* 一个普通元素、一个class选择符加成,结果是 0,0,1,1*/
h2 {color: silver;}
/*一个普通元素,结果是 0,0,0,1 */
/*0,0,1,1 大于 0,0,0,1 ,前者胜出*/

html > body table tr[id=”totals”] td ul > li {color: maroon;}
/* 7个普通元素、一个属性选择符、两个其他选择符(子选择符 >),结果是0,0,1,7 */
li#answer {color: navy;}
/* 一个ID选择符,一个普通选择符,结果是0,1,0,1 */
/*0,0,1,7 小于 0,1,0,1,后者胜出*/

除了specificity还有一些其他规则

  • HTML文件内的样式优先级为1,0,0,0,所以始终高于外部定义。这里文内样式指形如blah 的样式,而外部定义指经由< link>或< style>标签定义的规则。
  • 有!important声明的规则高于一切。如果!important声明冲突,则比较优先权。
  • 如果优先权一样,则按照在源码中出现的顺序决定,后来者居上。
  • 由继承而得到的样式没有specificity的计算,它低于一切其他规则(比如全局选择符*定义的规则)。
  • 关于经由@import载入的外部样式,由于@import必须出现在所有其他规则定义之前(如不是,则浏览器应该忽略之),所以按照后来居上原则,一般优先权冲突时是占下风的。

这里需要提一下IE,IE是可以识别位置错误的@import的,但无论@import在什么地方,它都认为是位于所有其他规则定义之前的,这可能会引发一些误会。

所以优先权问题虽然看起来简单,但其背后还是有蛮复杂的机制的,需要多多留意。

文章来自old9, 过不了GFW自己想办法吧!

fixed 定位在 IE6 下的实现技巧一则

从蓝色理想看到这贴:固定在右下角的离奇方法

受上面帖子的启发,也做了一个demo:ie6_fixed_position.html

代码:

[HTML]
<div id="a" style="width: 300px; height: 100px; background: red">test</div>
<script>
    var ie6 = !window.XMLHttpRequest;

    var a = document.getElementById('a');
    a.style.position = ie6 ? 'absolute' : 'fixed';
    a.style.right = 0;
    a.style.bottom = 0;

    if (ie6) {
        window.onscroll = function() {
            a.className = a.className;
        };
    }
</script>

原理分析: * position: absolute的元素,直接放在position:static的 body 中时,绝对定位的参考物是 body 的 viewport 部分。这使得元素 a 在窗口 resize 时,自动就能准确定位到右下角。注意:body 的 position 不能为 relative 等值,否则失效。 * onscroll 时需要特殊处理一下,使得滚动时,也让绝对定位元素 a 的参考物能更新为当前的 viewport. 上面的a.className = a.className就是这样一个 hack: 使得 a 的定位参考物动态更新为当前的 viewport. 类似的 hack 还有a.style.background = 'red'. 这些 hack 会引发 reflow, 但反之不一定,进一步的规律没找到,不过有一个 hack,也就够用了。

耐心总结,快乐分享,欢迎讨论。

转自岁月如歌

局部变量对全局变量修改出现的问题

[javascript]
var x = [1,2,3], o = [];
document.body.onclick = function(){
o[0] = ‘new’;
o = x;
alert(o);
}

这样一段代码你觉得多次输出的结果是一样吗?如果不一样知道为什么吗?

结果是不一样,有点意思噢,第一次结果[1,2,3],但再次点击后结果为['new',2,3]

导致结果不一样又是指针搞的鬼,这不去认真看真不会发觉,第一次o=x后,由于o与x相同,x o被改成同一指针的引用了,相当于o=x=[1,2,3]

要解决这问题把var x = [1,2,3], o = [];这样的全局变量放到内部去就可以了。

[javascript]
document.body.onclick = function(){
    var x = [1,2,3], o = [];
    o[0] = ‘new’;
    o = x;
    alert(o);
}

这样多少点击后的结果也是一样的。