功能
- 節點樣式動態變化,模擬未進行、當前、已進行三種效果
- 自動播放,也可以手動點擊節點切換
- 根據節點數量改變佈局,節點較少時均勻分佈,節點較多時固定節點間距離,通過控制左右箭頭實現橫向滾動,滾動到最右(左)時隱藏右(左)箭頭
效果
節點數少於規定值(我這裏定<=10),隱藏左右箭頭,節點均勻分佈
節點數大於規定值,出現左右箭頭,固定節點間距離,可以橫向滾動
重點
- 偽類樣式及修改
- 監聽滾動事件
完整代碼
html
<div v-show="imgChange" class="bar">
<!-- 左箭頭 -->
<div :class="['toLeft', menuLeft ? '' : 'hide']" @click="toLeft">
<img src="../../static/img/to_left.png" />
</div>
<!-- 要控制的面板 -->
<div class="box">
<ul class="ul" ref="menu" @scroll="orderScroll">
<div class="ul-content">
<li v-for="(point,i) in list" :key="i" :class="['point', (activeIndex == undefined || i > activeIndex) ? '': i == activeIndex ? 'active' : 'over']">
<div class="curPoint">{{point.name}}</div>
<div class="marker-out" @click="pointChange(point, i)">
<div class="marker-in"></div>
</div>
<div class="label" @click="pointChange(point, i)">
<el-tooltip class="item" effect="dark" :content="point.label" placement="bottom">
<span>{{point.label}}</span>
</el-tooltip>
</div>
</li>
</div>
</ul>
</div>
<!-- 右箭頭 -->
<div :class="['toRight', menuRight ? '' : 'hide']" @click="toRight">
<img src="../../static/img/dataCenter/to_right.png" />
</div>
</div>
data
list: [
{
label: '標籤1',
name: '名稱1'
}
],
activeIndex: undefined,
menuLeft: false,
menuRight: true,
maxScrollLeft: undefined,
interval: undefined
mounted
this.init()
document.addEventListener('scroll',this.Scroll())
methods
init(){
let that = this
if(this.list.length <= 10){ //根據節點數量改變佈局方式
document.getElementsByClassName('ul')[0].classList.add("flex")
document.getElementsByClassName('toLeft')[0].classList.add("hide")
document.getElementsByClassName('toRight')[0].classList.add("hide")
}
this.$nextTick(() => {
document.getElementsByClassName('marker-out')[0].classList.add("first")
})
},
autoProcess(){
let that = this;
this.activeIndex = undefined
let length = this.list.length
this.interval = setInterval(() => {
if(that.activeIndex == undefined){
that.activeIndex = 0
that.makePopup(that.list[that.activeIndex]) //切換節點同時切換彈窗
}else if(that.activeIndex < length-1){
that.activeIndex++
that.makePopup(that.list[that.activeIndex])
}else{
clearInterval(that.interval)
}
}, 1000);
},
layoutAdaptation(){
let that = this
this.$nextTick(() => {
let elWidth = document.getElementsByClassName('point')[0].scrollWidth
let lineWidth = elWidth - 22
let lineLeft = 0 - lineWidth
for(let i=0;i<document.styleSheets.length;i++){
document.styleSheets[i].addRule('.flex .marker-out:before', `width:${lineWidth}px;left:${lineLeft}px`)
} //這裏不能用foreach
that.calMaxScrollLeft() //計算最大橫向滾動像素值
})
},
pointChange(point, i){
this.activeIndex = i
this.makePopup(point)
},
handlePointChange(index){
this.pointChange(this.list[index], index)
},
makePopup(point){ //切換彈窗
this.$emit('switchPopup', point)
},
calMaxScrollLeft(){
let menuUl = document.getElementsByClassName('ul')[0]
this.maxScrollLeft = menuUl.scrollWidth - menuUl.offsetWidth
},
toLeft(){
this.$refs.menu.scrollLeft = this.$refs.menu.scrollLeft - 50 //滾動步長自行設置
},
toRight(){
this.$refs.menu.scrollLeft = this.$refs.menu.scrollLeft + 50
},
Scroll(e){
// console.log('scrollLeft',this.$refs.menu.scrollLeft)
},
orderScroll(){
// console.log('this.$refs.menu.scrollLeft',this.$refs.menu.scrollLeft)
if(this.$refs.menu.scrollLeft > 0){
this.menuLeft = true
}else{
this.menuLeft = false
}
if(this.$refs.menu.scrollLeft >= (this.maxScrollLeft - 1)){
this.menuRight = false
}else{
this.menuRight = true
}
}
watch
flag: function(newVal,oldVal) {
if(this.flag){
this.autoProcess()
this.layoutAdaptation()
}else{
clearInterval(this.interval)
}
}
css
.bar{
height: 143px;
width: 1162px;
background: url('../../static/img/tourBar.png') 100% 100% no-repeat;
display: flex;
}
/* 左右箭頭 */
.toLeft, .toRight{
width: 70px;
line-height: 143px;
}
.toLeft img, .toRight img{
cursor: pointer;
}
.toLeft{
text-align: right;
padding-right: 10px;
}
.toRight{
text-align: left;
padding-left: 10px;
}
/* 要控制的面板 */
.box{
width: 1022px;
}
.ul{
display: -webkit-box;
color: white;
padding: 30px 0 0;
overflow: auto;
}
.ul-content{
display: flex;
}
.point{
width: 103px;
}
.curPoint{
font-size: 12px;
color: #FF9702FF;
font-weight: bold;
visibility: hidden;
}
.marker-out{
width: 22px;
height: 22px;
background: #1358B3;
border-radius: 50%;
padding: 4px;
margin: 0 auto;
position: relative;
cursor: pointer;
}
.marker-in{
width: 14px;
height: 14px;
background: #35FFF5;
box-shadow: 2px 1px 8px 0px rgba(9, 53, 117, 0.71);
border-radius: 50%;
}
/* 節點左邊的線段 */
.marker-out:before{
height: 0;
width: 81px;
border-top: 3px dashed #0B4A8A;
position: absolute;
left: -81px;
top: 50%;
content: "";
pointer-events: none;
}
.label{
margin: 0 auto;
margin-top: 14px;
width: 86px;
height: 26px;
line-height: 26px;
font-size: 12px;
background: url('../../static/img/pane.png') no-repeat;
background-size:100% 100%;
opacity: 0.9;
position: relative;
cursor: pointer;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
padding: 0 5px;
}
/* 原本是用偽類做標籤左上角和右下角的形狀的,但是左上角的梯形實現起來有點麻煩,最後用了切圖(感謝美工大哥) */
/* .label:before{
width: 3px;
height: 6px;
background: #00A3FF;
position: absolute;
left: -1px;
top: -1px;
content: "";
}
.label:after{
width: 0;
height: 0;
border: solid transparent;
border-width: 3px 4px;
border-right-color: #00A3FF;
border-bottom-color: #00A3FF;
position: absolute;
right: -1px;
bottom: -1px;
content: "";
} */
/* 當前活動狀態的節點,圓圈替換成攝像頭gif */
.active .marker-out {
background: url('../../static/img/icon_video.gif') no-repeat;
background-position: center;
}
.active .marker-in {
display: none;
}
/* 當前節點顯示下箭頭指向標籤 */
.active .marker-out:after{
width: 0;
height: 0;
border: solid transparent;
border-width: 7px 6px;
border-top-color: #FF9702;
position: absolute;
bottom: -19px;
left: 5px;
content: "";
}
.active .label{
color: #FF9702FF;
background: url('../../static/img/pane_active.png') no-repeat;
background-size:100% 100%;
}
/* 當前節點上方顯示名稱 */
.active .curPoint{
visibility: visible;
}
/* 當前節點改變左邊線段樣式 */
.active .marker-out:before, .over .marker-out:before{
border-top: 2px solid #369EFF;
border-bottom: 2px solid #369EFF;
}
/* 已經過的節點 */
.over .marker-in{
background: #359EFF;
box-shadow: 2px 1px 8px 0px rgba(9, 53, 117, 0.71);
}
/* 節點少時均勻分佈 */
.flex{
display: flex;
flex-direction: row;
}
.flex .point{
flex: 1;
}
.flex .ul-content{
width: 100%;
}
/* 節點少時或滾動到最左/最右側時隱藏箭頭 */
.hide{
visibility: hidden;
pointer-events: none;
}
.ul::-webkit-scrollbar {
height: 0;
}
/* 隱藏第一個節點左側的線段 */
.first:before{
display: none;
}
本文章為轉載內容,我們尊重原作者對文章享有的著作權。如有內容錯誤或侵權問題,歡迎原作者聯繫我們進行內容更正或刪除文章。