当transition遇到display

实现淡入淡出时,可以使用jQuery的fadeIn()/fadeOut()。使用css3的transition(过渡)也能实现。
现在我们借助transition模仿jQuery实现盒子的淡入淡出:
通过button的click事件,给div#box添加或删除classname实现效果
HTML结构:

<button>动画按钮</button>
<div class="box" id="box"></div>

过渡改变opacity属性值

css代码:

.box {
    background-color: goldenrod;
    width: 300px; height: 200px;
    margin: 100px auto;
    transition: all 1s linear;
}
.hide { 
    /* display: none; */
    opacity: 0 
}

JS代码:

var $box = $('#box');
$('button').on('click', function() {
    if($box.hasClass('hide')) {
        $box.removeClass('hide');
    }else {
        $box.addClass('hide');
    }
});

在点击按钮后可以看到淡入淡出效果,但是在css代码中解除对display属性注释后,在刷新页面,淡出淡入效果没有了。究其原因在于transition不支持display的none值与其它值之间的过渡,进而影响到盒子对opacity的过渡效果。
我们可以按照下面的步骤,实现效果:

  • 当盒子可见时,先实现opacity动画,动画结束后添加display: none
  • 当盒子不可见时,首先使其可见display: block,然后执行opacity动画。

解决办法

opacity: 0从.hide抽离。
css代码:

.hide { display: none; }
.opacity0 { opacity: 0; }

JS代码如下:

var $box = $('#box');
$('button').on('click', function() {
    if($box.hasClass('hide')) {
        $box.removeClass('hide');
        requestAnimationFrame(function() {          // 合适时机执行淡入动画
            $box.removeClass('opacity0');
        });
    }else {
        $box.addClass('opacity0');
        $box.one('transitionEnd, webkitTransitionEnd', function() {
            $box.addClass('hide');                 // 动画结束后, 隐藏盒子
        });
    }
});

参考:
http://ued.ctrip.com/blog/when-on-transition-display.html
http://www.impressivewebs.com/animate-display-block-none/
http://oli.jp/2010/css-animatable-properties/

为图片添加半透明遮罩效果

平时为图片添加半透明遮罩效果,我的做法如下:
利用标签i实现背景半透明遮罩。当鼠标hover时, 提高i的背景色透明度值background-color: rgba(0, 0, 0, .6)

1
<p class="opacity-black-position"><a href="#"><img src="images/4601.jpg" alt=""><i></i></a></p>

为html结构添加如下css样式:

1
2
3
4
5
6
7
8
/* 利用标签i实现背景半透明遮罩, 兼容性不好 */
.opacity-black-position { width: 460px; height: 460px; position: relative; }
.opacity-black-position i {
position: absolute; top: 0; right: 0; bottom: 0; left: 0;
background-color: rgba(0, 0, 0, 0);
transition: background-color .5s;
}

.opacity-black-position a:hover i { background-color: rgba(0, 0, 0, .6); }

利用opacity简单实现

昨天看到京东商品图片上的半透明黑色遮罩,是这样实现的。

当hover时设置图片父容器a的半透明度0.4

1
<p class="opacity-black"><a href="#"><img src="images/4601.jpg" alt=""></a></p>

为html结构添加如下css样式:

1
2
3
.opacity-black { width: 460px; height: 460px; background-color: #000; }
.opacity-black a { transition: opacity .5s; opacity: 1; }
.opacity-black a:hover { opacity: 0.4; }

通过降低自身及子标签img的透明度来显示父辈容器的背景色, 达到的效果和上面是一样一样的。

狠狠滴点这里(演示): http://codepen.io/mackxu/pen/mJtvh

顺序表查找算法及其优化

顺序查找算法实现如下:

var arr = [5, 2, 4, 3, 1]
    , sequentialSearch = function(arr, val) {
        var i = 0
            , len = arr.length;
        for ( ; i < len; i++) {             // 比较一次
            if (arr[i] === val) {           // 比较二次
                return i;
            }
        }
        return i;                           // 返回len,则说明查找失败
    }

这里并不是足够完美, 因为每次循环时都需要对i是否越界, 即是否小于len做判断。事实上,还可以有更好的办法,设置一个哨兵, 就可以解决不需要每次让i与len做比较了。

顺序表查找优化

var arr = [5, 2, 4, 3, 1]
    // 有哨兵的顺序表查找
    , sequentialSearchOpt = function(arr, val) {
        var i = 0
            , arr = arr.slice(0)            // 保证函数内操作不影响外部的arr数组 
            , len = arr.length;
        arr[len] = val;                     // 设置arr[len]为关键字值作为哨兵
        // arr.push(val);
        while (arr[i] !== val) {            // 比较一次
            i++;
        }
        return i;                           // 返回len,则说明查找失败
    }

如果arr[i]中有值等于val则返回i,否则一定会在循环结束处等于val, 此时返回len值。说明数组中没有关键字等于val,查找失败。

在测试过程中, 发现因为由于对象是按地址传递的,在函数中改变数组arr[len] = val会影响到外部的数组,因此需要在函数内clone一份数组出来

这种在查找方向的尽头设置‘哨兵’免去了在查找过程中每一次比较后都要判断查找位置是否越界的小技巧,看似与原先差别不大,但在总数较多时,效率提高很大,是非常好的编程技巧。

参考: 大话数据结构

google-analytics的使用 解析页面引入代码

代码整理和注释

// 创建ga()方法, 加载analytics.js文件
// a, m 作为形参,确保下面的执行不会修改外部的同名变量
(function(win, doc, o, g, ga, a , m){

    win['GoogleAnalyticsObject'] = ga;      // 向外暴露出ga对象
    // 确保只执行一次analytics.js的插入
    win[ga] = win[ga] || function() {

        (win[ga].q = win[ga].q || []).push(arguments)},
        win[ga].l = 1 * new Date();         // 把时间格式转换成数字型

        // 动态加载analytics.js
        a = doc.createElement(o),
        m = doc.getElementsByTagName(o)[0]; // script
        a.async = 1;
        a.src = g;
        m.parentNode.insertBefore(a, m);
})(window, document, 'script','//www.google-analytics.com/analytics.js','ga');

短短的代码, 还是蛮有货的,呵呵。

压缩的代码

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');

参考: https://developers.google.com/analytics/devguides/collection/analyticsjs/advanced?hl=zh-TW