伸縮自如的時光軸實現——改進版

葡萄乾是個程式設計師發表於2016-05-01

       上回講到的是時光軸“伸縮自如”的實現,如果基於響應式製作的話,可能存在著許多潛在的BUG。如:視窗變化時,時光軸的”收起“和”展開“,都發生了一些變形。為此,對原來的 timeline.js 進行了改進,Demo的效果仍與此前一致,沒有多大的區別。

       但是卻了基於響應式進行操作,而不發生一些 奇葩 的結果。

       改進版 timeline.js

/**
 * Created by DreamBoy on 2016/5/1.
 */
$(function() {
    $.fn.initPutAway = function () {
        $(this).each(function() {
            initTimeLine(this);
        });

        //對 每一個條時間軸上的“收起”按鈕 初始化
        function initTimeLine(putAwayBtn) {
            var timeline = $(putAwayBtn).parents('.vertical-timeline');
            //對應時光軸上的“時間點”
            var timelineChild = timeline.children('.vertical-timeline-block');
            //對應時光軸上的“時間點”個數
            var len = timelineChild.length;
            //儲存各“時間點”的高度;//對應時光軸的總高度
            var hArr = [], totalH;

            $(putAwayBtn).on('click', function () {
                if($(this).html() == "收起") {
                    if(len > 1) { //要先判斷是否有子元素可以收縮,如果沒有的話,只是改變按鈕的內容為“展開”
                        for(var i = 0; i < len; i++) {
                            hArr[i] = $(timelineChild[i]).outerHeight();
                        }
                        totalH = timeline.outerHeight();

                        //設定收起時間軸後時間軸的高度
                        var top = $(timelineChild[0]).css("top");
                        if(top == 'auto') {
                            top = 30;
                        }

                        //需要設定收起後時光軸(vertical-timeline)的高度,並進行設定
                        //(因為子元素將進行position absolute定位,在父容器中不佔位置。為使父容器撐開應該提前計算好高度並進行設定)
                        var h1 = top + 50 * len;
                        var h2 = totalH; //除去除第一個 時間點 的所有時間點高度
                        for(var i = 1; i < len; i++) {
                            h2 -= $(timelineChild[i]).outerHeight();
                        }
                        var ph = h1 >= h2 ? h1 : h2;
                        timeline.outerHeight(ph);

                        //設定時間軸上各“時間點”收縮後的位置,根據top進行設定
                        var h = hArr[0];
                        $.each(timelineChild, function(i) {
                            if(i == 0) {
                                //不對時間軸上的第一個“時間點”進行position設定
                                $(this).css("z-index", 1000);
                            } else {
                                top += 50;
                                var _this = $(this);
                                // 注意:這裡必須先將position設定為absolute。(因為設定了position為absolute,top屬性設定才有效果)
                                // 那麼設定了position,同樣就必須定義top屬性的初始值,
                                // 否則,會按預設沒有top進行顯示,為保證在開始移動前,它還在“原來”的地方,就需要計算它的top值。
                                _this.css({"position" : "absolute", "top" : h});
                                _this.animate({"top" : top});

                                _this.children(".vertical-timeline-content").animate({"opacity" : 0}, function() {
                                    $(this).css("display", "none"); //隱藏對應時間點的內容
                                });

                                h += hArr[i];
                            }
                        });
                    }

                    $(this).html("展開");
                } else if($(this).html() == "展開"){
                    if(len > 1) { //要先判斷是否有子元素可以展開,如果沒有的話,只是改變按鈕的內容為“收起”
                        var top = totalH;

                        //設定展開時間軸之後時間軸的高度
                        timeline.outerHeight(totalH);

                        for(var i = len - 1; i >= 0; i--) {
                            if(i == 0) {
                                //不對時間軸上的第一個“時間點”進行關於position操作
                                $(timelineChild[i]).css("z-index", 0);
                            } else {
                                top -= hArr[i];
                                var _this = $(timelineChild[i]);
                                _this.animate({"top" : top});

                                //判斷是否是最後一個,如果是的話負責把 timeline時間軸 的高度設定為 100%,達到自適應的效果
                                if(i == 1) {
                                    _this.children(".vertical-timeline-content").css("display", "block").animate({"opacity" : 1}, function() {
                                        //修改為 relative 定位,方便“佔位”。
                                        $(this).parents('.vertical-timeline-block').css({"position": "relative", "top" : 0});
                                        timeline.outerHeight("100%");
                                    });
                                } else {
                                    _this.children(".vertical-timeline-content").css("display", "block").animate({"opacity" : 1}, function() {
                                        //修改為 relative 定位,方便“佔位”。
                                        $(this).parents('.vertical-timeline-block').css({"position": "relative", "top" : 0});
                                    });
                                }
                            }
                        }
                    }

                    $(this).html("收起");
                }
            });
        }
    }
});

       timeline.css

.vertical-timeline {
    color: #FFF;
    font-family: "微軟雅黑", "Microsoft YaHei";
    position: relative;
}

.vertical-timeline-block {
    border-left: 2px solid #DDD;
    position: relative;
    padding-bottom: 30px;
    width: 100%;
    cursor: pointer;
}

/* 時間軸的左側圖示 */
.vertical-timeline-icon {
    width: 40px;
    height: 40px;
    border-radius: 20px;
    position: absolute;
    left: -22px;
    top: 10px;
    z-index: 1000;

    text-align: center;
    line-height: 40px;
    cursor: pointer;
    transition: all 0.2s ease-in;
    -webkit-transition: all 0.2s ease-in;
    -moz-transition: all 0.2s ease-in;
    -o-transition: all 0.2s ease-in;
}

.vertical-timeline-block:hover .vertical-timeline-icon {
    width: 50px;
    height: 50px;
    border-radius: 25px;
    line-height: 50px;
    left: -27px;
    box-shadow: 0 0 5px #CCC;
    font-size: 25px;
}

/* 時間軸的左側圖示的各種樣式 */
.v-timeline-icon1 {
    background-color: #2aabd2;
}
.v-timeline-icon2 {
    background-color: #5cb85c;
}
.v-timeline-icon3 {
    background-color: #8c8c8c;
}
/* 時間軸的左側圖示上的序號*/
.vertical-timeline-icon i {
    font-style: normal;
    color: #FFF;
}
/* 時間軸上的具體內容 */
.vertical-timeline-content {
    background-color: #5bc0de;
    margin-left: 60px;
    padding: 20px 30px;
    border-radius: 5px;
    position: relative;
}
/* 時間軸上的具體內容左側箭頭 */
.vertical-timeline-content:before {
    content: '';
    width: 0;
    height: 0;

    border-top: 10px solid transparent;
    border-bottom: 10px solid transparent;
    border-right: 10px solid #5bc0de;
    border-left: 10px solid transparent;

    position: absolute;
    right: 100%;
    top: 20px;
}
/* 時間軸的具體內容的格式 */
.timeline-content {
    text-indent: 2em;
}
.time-more {
    overflow: hidden;
}
.time-more .time {
    float: left;
    line-height: 40px;
    display: inline-block;
}
.time-more .more {
    float: right;
}
.time-more .more a {
    display: inline-block;
    height: 20px;
    padding: 8px 15px;
    color: #FFF;
    text-decoration: none;
    font-size: 15px;
}
/* “更多資訊”的風格 */
.more-style1 {
    border-radius: 5px;
    background-color: #565656;
}
.more-style1:hover {
    background-color: #696969;
}
.more-style2 {
    border-radius: 5px;
    background-color: #1AB394;
}
.more-style2:hover {
    background-color: #18A689;
}

.more-style3 {
    border-radius: 5px;
    background-color: #1C84C6;
}
.more-style3:hover {
    background-color: #1A7BB9;
}

/*時光軸對應的標題*/
.vtb-tit {
    padding: 0 10px;
    height: 50px;
    line-height: 50px;
    text-align: center;

    background-color: #1A7BB9;
    border-radius: 5px;

    position: absolute;
    left: -150px;
    top: 10px;
}

/*收起按鈕的樣式*/
.timeline-putAway {
    position: absolute;
    right: -80px;
    top: 10px;
}

.putAway-btn {
    border: none;
    outline: none;
    height: 30px;
    padding: 8px 15px;
    color: #FFF;
    text-decoration: none;
    font-size: 15px;
    cursor: pointer;
}
.putAway-btn:hover {
    background-color: #2aabd2;
}

       Demo 案例:

       index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>時光軸</title>
    <link rel="stylesheet" href="timeline.css">
    <style>
        .container {
            width: 800px;
            margin: 50px auto;
        }
    </style>
</head>
<body>
<div class="container">
    <div class="vertical-timeline">
        <div class="vtb-tit">
            總時間點1
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon1">
                <i class="icon">1</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點1</h2>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="time-more">
                    <span class="time">2016/4/30 13:48</span>
                    <span class="more more-style1"><a href="#">更多資訊</a></span>
                </p>
            </div>

            <div class="timeline-putAway">
                <button type="button" class="putAway-btn">收起</button>
            </div>
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon2">
                <i class="icon">2</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點2</h2>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="time-more">
                    <span class="time">2016/4/30 13:48</span>
                    <span class="more more-style2"><a href="#">更多資訊</a></span>
                </p>
            </div>
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon3">
                <i class="icon">3</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點3</h2>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="time-more">
                    <span class="time">2016/4/30 13:48</span>
                    <span class="more more-style3"><a href="#">更多資訊</a></span>
                </p>
            </div>
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon1">
                <i class="icon">4</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
            </div>
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon2">
                <i class="icon">5</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
            </div>
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon3">
                <i class="icon">6</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
            </div>
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon3">
                <i class="icon">7</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
            </div>
        </div>
    </div>

    <div class="vertical-timeline">
        <div class="vtb-tit">
            總時間點2
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon1">
                <i class="icon">1</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點1</h2>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="time-more">
                    <span class="time">2016/4/30 13:48</span>
                    <span class="more more-style1"><a href="#">更多資訊</a></span>
                </p>
            </div>

            <div class="timeline-putAway">
                <button type="button" class="putAway-btn">收起</button>
            </div>
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon3">
                <i class="icon">3</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點3</h2>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="time-more">
                    <span class="time">2016/4/30 13:48</span>
                    <span class="more more-style3"><a href="#">更多資訊</a></span>
                </p>
            </div>
        </div>
    </div>

    <div class="vertical-timeline">
        <div class="vtb-tit">
            總時間點3
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon1">
                <i class="icon">1</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點1</h2>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="time-more">
                    <span class="time">2016/4/30 13:48</span>
                    <span class="more more-style1"><a href="#">更多資訊</a></span>
                </p>
            </div>

            <div class="timeline-putAway">
                <button type="button" class="putAway-btn">收起</button>
            </div>
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon2">
                <i class="icon">2</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點2</h2>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="time-more">
                    <span class="time">2016/4/30 13:48</span>
                    <span class="more more-style2"><a href="#">更多資訊</a></span>
                </p>
            </div>
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon3">
                <i class="icon">3</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點3</h2>
                <p class="timeline-content">我去吃了個午飯</p>
                <p class="time-more">
                    <span class="time">2016/4/30 13:48</span>
                    <span class="more more-style3"><a href="#">更多資訊</a></span>
                </p>
            </div>
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon1">
                <i class="icon">4</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
            </div>
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon2">
                <i class="icon">5</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
            </div>
        </div>

        <div class="vertical-timeline-block">
            <div class="vertical-timeline-icon v-timeline-icon3">
                <i class="icon">6</i>
            </div>

            <div class="vertical-timeline-content">
                <h2>時間點1</h2>
                <h2>時間點1</h2>
                <h2>時間點1</h2>
            </div>
        </div>
    </div>
</div>

<script src="jquery-1.11.1.min.js"></script>
<script src="timeline.js"></script>
<script>
    $(function() {
        //進行初始化
        $('.putAway-btn').initPutAway();
    });
</script>
</body>
</html>

相關文章