用element的el-slider写时间轴

1、源码,因为是在jq上用,所以用了new Vue,用的朋友请提前在jq引入element组件
<div class="customTimeline" id="timeline">
    <div class="container-timeline">
        <div class="btn-box">
            <i :class="['play-icon', isPlay ? 'el-icon-video-pause' : 'el-icon-video-play']" @click="playFn"></i>
        </div>
        <el-slider v-model="value" range :max="max" :marks="marks" :format-tooltip="formatTooltip"
            @input="onChage"></el-slider>
        <div class="tick-mark">
            <div :class="['tick-mark-box-line', index % 5 === 0 ? 'tick-mark-box-splitline' : 'tick-mark-box-line']"
                v-for="(item, index) in 101" :key="index"></div>
        </div>
        <div class="tooltip-box">
            <template v-for="(item, index) in dateTimeRange">
                <div class="tooltip-box-line" :style="{left: Object.keys(marks)[index] / max * 100 + '%'}"
                    v-if="item.name">
                    <div class="tooltip-box-content">{{ item.name }}</div>
                </div>
            </template>
        </div>
    </div>
</div>

<script>
    var timeline = new Vue({
        el: "#timeline",
        data() {
            return {
                isPlay: false, // 是否播放
                value: [0, 0],
                max: 100, // 最大值
                marks: {}, // 标注对象
                stepToSecond: 1, // 1步长代表多少分(默认1步长代表1分钟)
                dateTimeRange: [],
                timer: null,
                pageName: '',
            };
        },
        methods: {
       
            // 获取传参,进行初始化
            setDateTimeRange(val) {
                if (Array.isArray(val)) {
                    this.dateTimeRange = val
                    this.init()
                }
            },
            // 初始化方法,定义最大值、标注对象、添加信息展示
            init() {
                this.marks = {}
                if (this.dateTimeRange.length > 0) { // 判断传进来的参数是非空参数
                    let totalTime = new Date(this.dateTimeRange[this.dateTimeRange.length - 1].date).getTime() - new Date(this.dateTimeRange[0].date).getTime()
                    totalTime = Math.round(totalTime / 1000 / 60) // 总时长(分)
                    this.stepToSecond = totalTime > 500 ? Math.floor(totalTime / 500) : 1;
                    this.max = Math.round(totalTime / this.stepToSecond)
                    for (let i = 0, j = this.dateTimeRange.length - 1; i < j; i++) { // 循环数据,根据数据中的时间计算标注的位置
                        let arr = this.dateTimeRange[i].date.substring(11, 19).split(':')
                        arr = arr.slice(0, 2)
                        this.marks[Math.round((new Date(this.dateTimeRange[i].date).getTime() - new Date(this.dateTimeRange[0].date).getTime()) / 60 / 1000 / this.stepToSecond)] = arr.join(':')
                    } // marks对象的属性名称是数字,表示该标注的位置
                }
            },
            // 拖动滑块时tooltip的格式化方法
            formatTooltip(val) {
                let time = new Date(val * this.stepToSecond * 60 * 1000 + new Date(this.dateTimeRange[0]?.date).getTime())
                return `${time.getHours()}:${time.getMinutes().toString().padStart(2, 0)}`
            },
            // 播放方法
            playFn() {
                this.isPlay = !this.isPlay
                this.timer && clearInterval(this.timer)
                if (this.isPlay) {
                    this.value = [0, 0]
                    this.timer = setInterval(() => { // 添加定时器,重复进行滑块移动直到最大值时停止
                        if (this.value[1] < this.max) {
                            this.value = [0, this.value[1] + this.stepToSecond * 2]
                        } else {
                            this.isPlay = false
                            this.timer && clearInterval(this.timer)
                        }
                    }, 20)
                }
            },
        },
    })
</script>

<style lang="less">
    .customTimeline {
        width: 100%;
        height: 100%;
        padding: 10px 40px;
    }

    .container-timeline {
        width: 100%;
        height: 100%;
        position: relative;
        display: flex;
        align-items: center;

        .btn-box {
            position: absolute;
            left: -33px;
            top: 17px;

            .play-icon {
                font-size: 22px;
                cursor: pointer;
            }
        }

        .el-slider {
            width: 100%;
        }

        .tick-mark {
            width: calc(100% + 1px);
            position: absolute;
            height: 50%;
            top: 0;
            display: flex;
            justify-content: space-between;
            align-items: flex-end;
            z-index: -2;

            .tick-mark-box-line {
                width: 0;
                height: 50%;
                border-right: 2px solid #8CEDEC;
            }

            .tick-mark-box-splitline {
                height: 70%;
            }
        }

        .tooltip-box {
            width: 100%;
            position: absolute;
            height: 50%;
            top: 0;
            z-index: -1;

            .tooltip-box-line {
                height: 100%;
                position: absolute;
                width: 0;
                border-right: 2px solid #FFF;

                .tooltip-box-content {
                    position: absolute;
                    top: calc(-100% - 50px);
                    width: 140px;
                    height: 60px;
                    padding: 7px;
                    background-color: #0342caab;
                    border-radius: 7px;
                    left: -69px;
                    font-size: 14px;
                }

                .tooltip-box-content::before {
                    content: '';
                    width: 0;
                    height: 0;
                    display: block;
                    border-style: solid;
                    border-width: 8px 6px 0 6px;
                    border-color: #0342caab transparent;
                    position: absolute;
                    bottom: -8px;
                    left: 50%;
                    transform: translate(-50%);
                }
            }
        }
    }
</style>
2、这里是动态传入的标题,不管有几个标题,都需要传一个结束时间
         $('#customTimeline').show() 
           //这里是动态传入的标题,不管有几个标题,都需要传一个结束时间
                    timeline.setDateTimeRange([
                        {
                            date: '2024-02-25 9:00:00',
                            name: '课程的要素',
                        }, {
                            date: '2024-02-25 14:00:00',
                            name: '课程的内容',
                        }, {
                            date: '2024-02-25 19:00:00',
                            name: ''
                        }
                    ])

效果图:

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Element UI 并没有提供横向时间线的组件,但可以通过自定义样式来实现。 以下是一个简单的示例代码,实现了横向时间线的效果: ``` <template> <div class="timeline-horizontal"> <div class="timeline-item" v-for="(item, index) in timelineData" :key="index"> <div class="timeline-dot"></div> <div class="timeline-content"> <h4>{{ item.title }}</h4> <p>{{ item.content }}</p> </div> </div> </div> </template> <style scoped> .timeline-horizontal { display: flex; flex-direction: row; } .timeline-item { display: flex; flex-direction: column; align-items: center; margin-right: 20px; } .timeline-dot { width: 16px; height: 16px; border-radius: 50%; background-color: #409EFF; margin-bottom: 10px; } .timeline-content { text-align: center; color: #666; } .timeline-content h4 { font-size: 16px; margin-bottom: 5px; } .timeline-content p { font-size: 14px; } </style> <script> export default { data() { return { timelineData: [ { title: '2022', content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' }, { title: '2021', content: 'Pellentesque euismod mauris sed nibh ultricies, ac efficitur enim commodo.' }, { title: '2020', content: 'Nullam convallis turpis nec neque interdum, a vulputate lectus consectetur.' }, { title: '2019', content: 'Sed euismod ipsum quis metus bibendum, vel rhoncus arcu lacinia.' } ] } } } </script> ``` 在这个示例中,我们使用了 flex 布局实现了横向排列,并通过 margin-right 属性控制了每个时间点之间的间距。同时,设置了 timeline-dot 的圆形样式,来展示时间点。 你也可以根据自己的需求修改样式,来达到更好的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值