2016年12月27日 星期二

(js)Area88_transition.js

////////////////////////////////////////////////////////////////////////////////
/**
 * (jquery)擴充
 *
 * 處理transition
 */
////////////////////////////////////////////////////////////////////////////////

(function($) {
    /**
     * 取得(transitionEnd)事件的名字
     */
    $.support = $.support || {};
    $.support.transition = getTransitionEndName();

    function getTransitionEndName() {
        var el = document.createElement('div')
        var transitionendName;

        var data = {
            WebkitTransition: 'webkitTransitionEnd',
            MozTransition: 'transitionend',
            OTransition: 'oTransitionEnd otransitionend',
            transition: 'transitionend'
        }

        for (var k in data) {
            if (el.style[k] !== undefined) {
                transitionendName = data[k];
            }
        }
        return transitionendName;
    }
})(Area88_);
///////////////////////////////////////////////////////////////////////////////
(function($) {
    /**
     * 確保(transitionend)有被執行完
     *
     * @param {int | string} option: 可以指定(time),或指定要監看的(transition-property)
     */
    $.fn.tsEndCheck_ = function(option) {
        debugger;

        var time;
        (typeof option == 'number') && (time = option);

        this.each(function(i, dom) {
            debugger;

            var check = false;
            /* ---------------------------------- */
            if (typeof option == 'string') {
                // 取得 transitionDuration
                time = $(dom).tsTime_(option);
            }
            /* ---------------------------------- */
            debugger;
            // 再綁定一個'transitionend'事件,但事件中有包含一個通知結束的動作
            dom.addEventListener($.support.transition, eventFun);

            function eventFun(e) {
                alert('eventFun()');
                debugger;
                check = true;
                dom.removeEventListener($.support.transition, eventFun);
            };
            /* ---------------------------------- */
            // 檢查
            setTimeout(function() {
                debugger;
                alert('check: ' + check);
                if (check) {
                    return;
                }
                // 若'transitionend'未被觸發過
                var evt = document.createEvent('Event');
                evt.initEvent($.support.transition, true, true);
                dom.dispatchEvent(evt);
            }, time + 50);
        });

        return this;
    };
    /* ========================================================================== */

})(Area88_);


///////////////////////////////////////////////////////////////////////////////

// 取得,設定(動畫時間)

(function($) {
    $.tsTime_ = function(elem, setting) {
        debugger;
        if (setting == null || typeof setting == 'string') {
            var data = getTransitionProperty(elem);

            if (typeof setting == 'string') {
                return (data[setting] || data['all'] || undefined);
            } else {
                return data;
            }
        } else if ($.isPlainObject(setting)) {
            setTransitionProperty(elem, setting);
            return;
        } else {
            throw new Error('arguments type error');
        }
    };
    /* ====================================================================== */
    /**
     * 取得或設定(transition-property)(transition-duration)
     *
     * @param {plaineObject, string, undefined} setting (若'{}'是設定,
     * 'string'則返回特定項目的時間, 'undefined'返回所有項目的時間)
     * @return {[type]} [description]
     */
    $.fn.tsTime_ = function(setting) {
        debugger;
        var result = null;

        // 若是要設定(transition)

        /* -------------------------------------------- */
        this.each(function(index, el) {
            debugger;

            result = $.tsTime_(this, setting);

            if (setting == null || typeof setting == 'string') {
                return false;
            }
        });
        /* -------------------------------------------- */
        if (setting == null || typeof setting == 'string') {
            return result;
        } else {
            return this;
        }
    };
    /* ====================================================================== */
    /**
     * 取得(dom)相關初始的(transitionProperty)
     * 包含了(css)(style)的設定
     *
     * @param {[type]} dom [description]
     * @return {[null]}
     *
     */
    function getTransitionProperty(dom) {
        debugger;

        var result = {};

        var transitionProperty_array = [];
        var transitionDuration_array = [];

        var css = dom.currentStyle || window.getComputedStyle(dom, null);

        var property = css.transitionProperty || '';
        var duration = css.transitionDuration || '';

        property = property.replace(/\s/g, '');
        duration = duration.replace(/\s/g, '');

        property_array = property.split(',');
        duration_array = duration.split(',');

        /* -------------------------------------------- */
        // 若(transitionDuration)數目沒有匹配(transitionProperty)

        for (var i = 0; i < property_array.length; i++) {
            var property = property_array[i];

            // 若沒有對應的時間,會取第一個作為預設
            var duration = duration_array[i] || duration_array[0];
            duration = Number(duration.replace(/[a-zA-Z]*/gi, '')) * 1000; // 去掉(s)

            result[property] = duration;

            if (/all/gi.test(property)) {
                // 若遇到(property = all)會複寫前面屬性的時間
                for (var j = 0; j < i; j++) {
                    property = property_array[j];
                    result[property] = duration;
                }
            }
        }
        return result;
    };
    /* ====================================================================== */
    /**
     * 設定(dom.style.transitionProperty)
     *
     * @param  {[type]} dom            [description]
     * @param {plaineObject} setting 要設定的(transition)選項
     * @return {[type]}
     */
    function setTransitionProperty(dom, setting) {
        debugger;

        setting = setting || {};
        /* -------------------------------------------- */
        var style = dom.style;

        var property = [];
        var duration = [];

        for (var k in setting) {
            property.push(k);

            var _duration = setting[k];

            if (typeof _duration == 'number') {
                _duration = _duration / 1000;
                duration.push(_duration + 's');
            }
        }

        if (property.length > 0 && duration.length > 0) {
            style.transitionProperty = property.join(',');
            style.transitionDuration = duration.join(',');

        }
    };
})(Area88_);
////////////////////////////////////////////////////////////////////////////////