jQuery实现一个日期时间轴进度条播放代码

jQuery实现一个日期时间轴进度条播放代码

在一次开发中需要时间轴就找到这个案例了,本文是转载,出处已经忘记,仅仅用来学习,侵权删!

HTML代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery日期时间轴进度条播放代码</title>

<link rel="stylesheet" href="css/index.css">

</head>
<body>

<div id="progressTime"></div>

<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.progressTime.js"></script>
<script type="text/javascript">
var hourTimestamp = 3600 * 1000;
var dayTimestamp = hourTimestamp * 24;

$("#progressTime").ProgressTime({
	container: "progressTime",
	startTime: new Date(formatDate(new Date(new Date().getTime() - dayTimestamp * 5), "YYYY/MM/DD 00:00:00")),
	endTime: new Date(formatDate(new Date(), "YYYY/MM/DD 00:00:00")),
	currentTime: new Date(formatDate(new Date(new Date().getTime() - dayTimestamp * 4), "YYYY/MM/DD 12:00:00")),
	interval: 300,
	delay: 2000,
	callback: function (config) {
		console.log(config);
	},
	animateCallback: function (config) {

		// 假如动画完成之后请求数据需要两秒
		var timer = setTimeout(function () {
			progressTime.options.toPlay = true; // 两秒之后再继续走播放条
			clearTimeout(timer);
		}, 0);
	}
});
</script>

</body>
</html>

js代码:jquery.progressTime.js

$(function ($, window) {
    var hourTimestamp = 3600 * 1000; // 一个小时的时间戳
    var dayTimestamp = hourTimestamp * 24; // 一天的时间戳

    window.formatDate = function (date, type) {
        if ((date.getTime || new Date(date).getTime()) && typeof type === "string") {
            date = type.replace(/YYYY|MM|DD|HH|hh|MM|mm|SS|ss/g, function ($) {
                switch ($) {
                    case "YYYY":
                        return date.getFullYear();
                    case "MM":
                        return date.getMonth() >= 9 ? date.getMonth() + 1 : "0" + (date.getMonth() + 1);
                    case "mm":
                        return date.getMonth() + 1;
                    case "DD":
                        return date.getDate() > 9 ? date.getDate() : "0" + date.getDate();
                    case "dd":
                        return date.getDate();
                    case "HH":
                        return date.getHours() > 9 ? date.getHours() : "0" + date.getHours();
                    case "hh":
                        return date.getHours();
                    case "MM":
                        return date.getMinutes() > 9 ? date.getMinutes() : "0" + date.getMinutes();
                    case "mm":
                        return date.getMinutes();
                    case "SS":
                        return date.getSeconds() > 9 ? date.getSeconds() : "0" + date.getSeconds();
                    case "ss":
                        return date.getSeconds();
                    default:
                        return $;
                }
            });
        }
        return date;
    }

    function ProgressTime(options) {
        this.options = {
            container: "container", // 容器ID名称 
            startTime: new Date(formatDate(new Date(new Date().getTime() - dayTimestamp * 10), "YYYY/MM/DD 00:00:00")), // 开始时间:2000/10/20 00:00:00
            endTime: new Date(formatDate(new Date(), "YYYY/MM/DD 00:00:00")), // 结束时间:2000/10/30 00:00:00
            currentTime: new Date(new Date().getTime() - dayTimestamp * 7), // 当前时间: 2000/10/25 00:00:00
            delay: 2000, // 自动播放动画时间                                            
            isNow: true, // 是否显示右侧回到当前时间
            toPlay: true, // 渲染是否完成
            animateFinish: true, // 动画是否完成
            hoursInterval: 3,
            formatterDate: function (timer) { // 自定义时间格式
                return formatDate(new Date(timer), "YYYY年MM月DD日");
            },
            animateCallback: function (config) { // 动画完成回调

            },
            callback: function (config) { // 单击事件回成回调

            }
        }
        this.options = $.extend(this.options, options);
        this.id = this.options.container;
        this.startTime = this.options.startTime;
        this.endTime = this.options.endTime;
        this.currentTime = this.options.currentTime;
        this.currentTimeTemp = null;
        this.timer = null;
        this.init();

    }
    ProgressTime.prototype.init = function () {
        this.createDom();
        this.bindEvent();
        this.resize();
        return this;
    }

    ProgressTime.prototype.createDom = function () {
        var left = $("<div class='" + this.id + "-left'></div>");
        var center = $("<div class='" + this.id + "-center'></div>");
        var isRight = this.options.isNow ? "" : "hide";
        var right = $("<div class='" + this.id + "-right " + isRight + "'></div>");

        var leftHtml = "<div class='" + this.id + "-left-t'></div><div class='" + this.id + "-left-b'><span class='" + this.id + "-left-b-start'></span></div>";
        left.append(leftHtml);

        var centerHtml = "<div class='" + this.id + "-center-t'><div class='" + this.id + "-center-t-bar'></div></div><div class='" + this.id + "-center-c'></div><div class='" + this.id + "-center-b'></div>";
        center.append(centerHtml);

        var rightHtml = "<div class='" + this.id + "-right-now'>回到当前</div>";
        right.append(rightHtml);

        $("#" + this.id).append(left).append(center).append(right);

        this.createCenter(); // 创建内容的DOM
    }
    ProgressTime.prototype.createCenter = function () {
        var cTop = $("." + this.id + "-center-t");

        var cCenter = $("." + this.id + "-center-c");
        var cbottom = $("." + this.id + "-center-b");

        cTop.append("<div class='" + this.id + "-center-t-tooltip'></div><div class='" + this.id + "-center-t-tooltipTemp hide'></div>");
        var days = (this.endTime.getTime() - this.startTime.getTime()) / dayTimestamp;


        var tempTime, cTopHtml = "",
            cCenterHtml = "",
            cBottomHtml = "",
            width = (cTop.width() / days) / cTop.width() * 100 + "%"; // 计算出每一天的时间轴长度,必需用百分比不然计算不准确

        // 循环天数
        for (var i = 0; i < days; i++) {
            var tempTime2 = new Date(this.startTime.getTime() + (i * dayTimestamp)); // 当前时间
            tempTime = this.options.formatterDate(tempTime2);
            cTopHtml += "<li style='width:" + width + ";'></li>";
            cCenterHtml += "<li class='" + this.id + "-center-c-ul-li' style='width:" + width + ";'></li>";
            cBottomHtml += "<li style='width:" + width + ";'>" + tempTime + "</li>";
        }
        cTop.append("<ul class='" + this.id + "-center-t-ul'>" + cTopHtml + "</ul>");
        cCenter.append("<ul class='" + this.id + "-center-c-ul'>" + cCenterHtml + "</ul>");
        cbottom.append("<ul class='" + this.id + "-center-b-ul'>" + cBottomHtml + "</ul>");

        // 按3小时来间隔
        var spanHtml = "";
        var liWidth = $("." + this.id + "-center-c-ul-li")[0].getBoundingClientRect().width; //
        var hoursWidth = liWidth / 24; // 计算每个小时所占的宽度
        var intervalCount = 24 / this.options.hoursInterval;
        for (var i = 1; i < intervalCount; i++) {
            var temp = (hoursWidth * i * this.options.hoursInterval) / liWidth * 100 + "%";
            spanHtml += "<span style='left:" + temp + ";'>" + (i * this.options.hoursInterval) + "</span>";
        }
        $("." + this.id + "-center-c-ul-li").append(spanHtml)

        this.setTime();
    }
    ProgressTime.prototype.setConfig = function (config) {
        var _this = this;
        var text = formatDate(new Date(config.time), "YYYY年MM月DD日 hh时");

        var widthPercent = (config.width / $("." + this.id + "-center-t").width()) * 100 + "%"; // 用百分比,解决时间播放结束出现自适应问题
        // 灵活的tooltip
        if (config.type === "mousemove") {
            $("." + this.id + "-center-t-tooltipTemp").removeClass("hide").text(text).css({
                "left": widthPercent
            });
            return;
        }

        // 时间轴的长度
        $("." + this.id + "-center-t-tooltip").text(text).stop().animate({
            "left": widthPercent
        });

        // 固定的tooltip
        $("." + this.id + "-center-t-bar").stop().animate({
            width: widthPercent
        }, function () { // 动画完成 
            _this.options.animateFinish = true;
            typeof _this.options.animateCallback === "function" && _this.options.animateCallback(config);
        });

        typeof this.options.callback === "function" && this.options.callback(config);
    }
    ProgressTime.prototype.setTime = function (e) {
        var layerX = e && e.originalEvent.layerX;
        var type = e && e.type;
        var hoursWidth = $("." + this.id + "-center-t-ul li")[0].getBoundingClientRect().width / 24; // 计算每个小时所占的宽度
        var tooltipTimestamp = this.currentTimeTemp || this.currentTime.getTime(); // 返回当前的时间的时间戳
        var num = Math.floor((tooltipTimestamp - this.startTime.getTime()) / hourTimestamp); // 计算出多少小时
        num = layerX !== undefined ? Math.round(layerX / hoursWidth) : num;
        var progressWidth = num * hoursWidth; // 计算出时间条的长度

        if (layerX) { // 移动或点击重新求距离
            tooltipTimestamp = Math.floor(this.startTime.getTime() + num * hourTimestamp);

            if (type === "click") {
                this.currentTimeTemp = tooltipTimestamp; // 点击储存当前时间,自适应用
            }
        }
        var time = formatDate(new Date(tooltipTimestamp), "YYYY/MM/DD hh:00:00");
        this.setConfig({
            time: time,
            width: progressWidth,
            type: type
        });
    }

    ProgressTime.prototype.bindEvent = function () {
        var _this = this;

        // 点击
        $("." + this.id + "-center-t-ul").on("click", function (e) {
            _this.setTime(e);
        });

        // 移动移出
        $("." + this.id + "-center-t-ul").on("mousemove", function (e) {
            _this.setTime(e);
        }).on("mouseleave", function () {
            $("." + _this.id + "-center-t-tooltipTemp").addClass("hide");
        });

        // 回到当前
        $("." + this.id + "-right-now").on("click", function () {
            _this.currentTimeTemp = _this.currentTime.getTime(); // 重置
            _this.setTime();
        });

        // 播放
        var flag = true;
        $("." + this.id + "-left-b-start").on("click", function () {
            var self = $(this);
            if (flag && _this.currentTimeTemp < _this.endTime) {
                _this.currentTimeTemp = _this.currentTimeTemp ? _this.currentTimeTemp : _this.currentTime.getTime(); // 加一小时的时间戳
                flag = false;
                self.addClass("stop");
                if (!_this.timer) {
                    _this.timer = setInterval(function () {
                        if (_this.options.toPlay && _this.options.animateFinish) { // 动画完成后,并且页面渲染后再调用
                            console.log("aaa");
                            _this.options.toPlay = false;
                            _this.options.animateFinish = false;
                            _this.currentTimeTemp += hourTimestamp;
                            if (_this.currentTimeTemp >= _this.endTime) { // 时间边界判定
                                flag = true;
                                self.removeClass("stop");
                                clearInterval(_this.timer);
                                _this.timer = null;
                            }
                            _this.setTime();
                        }
                    }, _this.options.delay);
                }
            } else {
                flag = true;
                self.removeClass("stop");
                clearInterval(_this.timer);
                _this.timer = null;
            }
        });
    }

    ProgressTime.prototype.resize = function () { // 自适应只调用一次,解决浏览器触发多次resize方法
        var _this = this;
        var tempTimer = null;
        $(window).resize(function () {
            if (!tempTimer && !_this.timer) { // 浏览器缩放会重置时间轴,这里判断_this.timer是否存在再重置
                tempTimer = setTimeout(function () {
                    _this.setTime();
                    clearTimeout(tempTimer);
                    tempTimer = null;
                }, 0);
            }
        });
    }
    $.fn.extend({
        ProgressTime: function (options) {
            window.progressTime = new ProgressTime(options);
        }
    });
}(jQuery, window));

CSS代码

* {
  margin: 0;
  padding: 0;
  list-style: none;
  text-decoration: none;
}

html,
body {
  height: 100%;
}
.hide{
    display: none;
}
#progressTime {
  height: 50px;
  width: 80%;
  border: 1px red solid;
  margin: 50px auto 0;
  display: flex;
  background-color: rgba(0, 0, 0, 0.7);
  min-width: 1024px;
}
.progressTime-left {
  width: 48px;
  height: 100%;
  display: flex;
  flex-direction: column;
}
.progressTime-left-t {
  height: 8px;
  background-color: #25d096;
  position: relative;
}
.progressTime-left-b {
  flex: 1;
  position: relative;
}
.progressTime-left-b-start {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  border: 6px solid;
  border-color: #fff #fff transparent transparent;
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
  margin-left: -9px;
  margin-top: -6px;
  cursor: pointer;
}
.progressTime-left-b-start.stop{
    width: 16px;
    height: 12px;
    border: none;
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    transform: rotate(0deg);
    cursor: pointer;
}
.progressTime-left-b-start.stop::before{
    content: "";
    position: absolute;
    width: 4px;
    height: 12px;
    background-color: #FFF;
}
.progressTime-left-b-start.stop::after{
    content: "";
    position: absolute;
    width: 4px;
    height: 12px;
    background-color: #FFF;
    margin-left: 10px;
}
.progressTime-center {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.progressTime-center-t {
  height: 8px;
  background-color: rgba(255, 255, 255, 0.7);
  box-sizing: border-box;
  cursor: pointer;
  position: relative;
}
.progressTime-center-t-bar {
  background-image: linear-gradient(
    to right,
    rgba(37, 208, 150, 1),
    rgba(45, 182, 205, 1)
  );
  height: 100%;
}
.progressTime-center-t-tooltip, .progressTime-center-t-tooltipTemp {
  position: absolute;
  padding: 0 8px;
  height: 24px;
  line-height: 24px;
  top: -35px;
  text-align: center;
  font-size: 14px;
  color: #fff;
  background-color: gray;
  border-radius: 3px;
  -webkit-transform: translateX(-50%);
  -o-transform: translateX(-50%);
  -moz-transform: translateX(-50%);
  -ms-transform: translateX(-50%);
  transform: translateX(-50%);
  min-width: 20px;
  white-space: nowrap;
}
.progressTime-center-t-tooltip::after, .progressTime-center-t-tooltipTemp::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -8px;
  border: 8px solid;
  border-color: gray transparent transparent transparent;
}
.progressTime-center-t-tooltipTemp{
    background-color: #ccc;
}
.progressTime-center-t-tooltipTemp::after{
    border-color: #ccc transparent transparent;
}
.progressTime-center-t-ul {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  z-index: 1;
}
.progressTime-center-t-ul::after {
  content: "";
  display: block;
  clear: both;
}
.progressTime-center-t-ul,
.progressTime-center-t-ul li {
  height: 100%;
}

.progressTime-center-t-ul li {
  float: left;
  border-left: 1px solid #999;
  box-sizing: border-box;
  height: 110%;
}

.progressTime-center-c {
  height: 12px;
  line-height: 12px;
}
.progressTime-center-c-ul::after {
  content: "";
  display: block;
  clear: both;
}
.progressTime-center-c-ul,
.progressTime-center-c-ul-li {
  height: 100%;
}
.progressTime-center-c-ul-li {
  float: left;
  border-left: 1px solid #999;
  border-bottom: 1px solid #999;
  box-sizing: border-box;
  position: relative;
}
.progressTime-center-c-ul-li span{
  position: absolute;
  color: #FFF;
  font-size: 12px;
  -webkit-transform: translateX(-50%) scale(.8);
  -moz-transform: translateX(-50%) scale(.8);
  -ms-transform: translateX(-50%) scale(.8);
  -o-transform: translateX(-50%) scale(.8);
  transform: translateX(-50%) scale(.8);
}
.progressTime-center-c-ul-li span::after{
  content: "";
  position: absolute;
  width: 1px;
  top: -90%;
  background-color: #FFF;
  height: 9px;
  -webkit-transform: translateX(-50%);
  -moz-transform: translateX(-50%);
  -ms-transform: translateX(-50%);
  -o-transform: translateX(-50%);
  transform: translateX(-50%);
  left: 50%;
}
.progressTime-center-b {
  flex: 1;
}
.progressTime-center-b-ul::after {
  content: "";
  display: block;
  clear: both;
}
.progressTime-center-b-ul,
.progressTime-center-b-ul li {
  height: 100%;
}
.progressTime-center-b-ul li {
  display: flex;
  justify-content: center;
  align-items: center;
  float: left;
  border-left: 1px solid #999;
  /* border-bottom: 1px solid #999; */
  color: #fff;
  font-size: 12px;
  box-sizing: border-box;
}
.progressTime-right {
  height: 100%;
  width: 120px;
  position: relative;
  border-left: 1px solid #999;
}
.progressTime-right-now {
  height: 28px;
  line-height: 28px;
  width: 80px;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  margin: auto;
  border-radius: 14px;
  background-color: #2db6cd;
  text-align: center;
  font-size: 12px;
  color: #fff;
  cursor: pointer;
}

实现效果:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值