|
|
<template>
|
|
|
<ul class="side-idx">
|
|
|
<v-touch tag="ul"
|
|
|
class="side-idx"
|
|
|
@tap="tap"
|
|
|
@panup="showZoom"
|
|
|
@pandown="showZoom"
|
|
|
@panend="hideZoom"
|
|
|
@press="showZoom"
|
|
|
@pressup="hideZoom">
|
|
|
<div class="bg"></div>
|
|
|
<div class="zoom-in">M</div>
|
|
|
<li v-for="item in items" :key="item.name">
|
|
|
<a class="no-intercept" href="javascript:;"
|
|
|
@click="() => {loc(item.index)}">{{item.name}}</a>
|
|
|
<div class="zoom-in"
|
|
|
:class="{show: zoomSwitch}">
|
|
|
{{zoomName}}
|
|
|
</div>
|
|
|
<li v-for="(item, index) in items"
|
|
|
:key="item.name"
|
|
|
:data-idx="item.name">
|
|
|
<a class="idx-item no-intercept"
|
|
|
:class="{zoom: index === zoomIdx}"
|
|
|
href="javascript:;">
|
|
|
{{item.name}}
|
|
|
</a>
|
|
|
</li>
|
|
|
</ul>
|
|
|
</v-touch>
|
|
|
</template>
|
|
|
<script>
|
|
|
export default {
|
...
|
...
|
@@ -16,22 +31,74 @@ |
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
items: []
|
|
|
items: [],
|
|
|
timer: '',
|
|
|
zoomName: '',
|
|
|
zoomIdx: '',
|
|
|
$zoomIn: '',
|
|
|
$sideIdx: '',
|
|
|
sideRect: {},
|
|
|
firstIdxRect: {},
|
|
|
zoomSwitch: false
|
|
|
};
|
|
|
},
|
|
|
watch: {
|
|
|
indexList() {
|
|
|
if (this.indexList) {
|
|
|
this.items = this.indexList;
|
|
|
this.$nextTick(function() {
|
|
|
this.recordIdxRect();
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
loc(index) {
|
|
|
this.$emit('loc-index', index);
|
|
|
tap(e) {
|
|
|
this.showZoom(e);
|
|
|
clearTimeout(this.timer);
|
|
|
this.timer = setTimeout(() => {
|
|
|
this.hideZoom();
|
|
|
}, 500);
|
|
|
},
|
|
|
hideZoom() {
|
|
|
this.zoomIdx = '';
|
|
|
this.zoomSwitch = false;
|
|
|
},
|
|
|
showZoom(e) {
|
|
|
const eX = e.center.x;
|
|
|
const eY = e.center.y;
|
|
|
const outRect = eX < this.sideRect.left || eY < this.sideRect.top || eY > this.sideRect.bottom;
|
|
|
|
|
|
if (outRect) {
|
|
|
return this.hideZoom();
|
|
|
}
|
|
|
|
|
|
let len = this.items.length;
|
|
|
let idx = Math.floor((eY - this.firstIdxRect.top) / this.firstIdxRect.height);
|
|
|
|
|
|
if (idx < 0) {
|
|
|
idx = 0;
|
|
|
}
|
|
|
|
|
|
if (idx === len || idx > len) {
|
|
|
idx = len - 1;
|
|
|
}
|
|
|
|
|
|
this.zoomIdx = idx;
|
|
|
this.zoomName = this.items[idx].name;
|
|
|
this.$zoomIn.style.top = this.calcZoomInTop(idx);
|
|
|
this.zoomSwitch = true;
|
|
|
this.$emit('loc-index', this.zoomName);
|
|
|
},
|
|
|
calcZoomInTop(idx) {
|
|
|
return (idx + 0.5) * this.firstIdxRect.height - this.$zoomIn.getBoundingClientRect().height / 2 +
|
|
|
this.firstIdxRect.top - this.sideRect.top + 'px';
|
|
|
},
|
|
|
touch() {
|
|
|
console.log('touch')
|
|
|
recordIdxRect() {
|
|
|
this.$sideIdx = document.querySelector('.side-idx');
|
|
|
this.$zoomIn = this.$sideIdx.querySelector('.zoom-in');
|
|
|
this.sideRect = this.$sideIdx.getBoundingClientRect();
|
|
|
this.firstIdxRect = this.$sideIdx.querySelector('li').getBoundingClientRect();
|
|
|
}
|
|
|
},
|
|
|
created() {
|
...
|
...
|
@@ -84,11 +151,17 @@ |
|
|
height: 58px;
|
|
|
padding-left: 20px;
|
|
|
color: #fff;
|
|
|
text-align: left;
|
|
|
line-height: 58px;
|
|
|
background: resolve("product/zoom-in-bg.png");
|
|
|
background-size: cover;
|
|
|
}
|
|
|
transition: opacity 0.4s ease;
|
|
|
opacity: 0;
|
|
|
|
|
|
&.show {
|
|
|
opacity: 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
li {
|
|
|
position: relative;
|
...
|
...
|
@@ -96,6 +169,7 @@ |
|
|
text-align: center;
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
|
a {
|
|
|
color: #fff;
|
|
|
font-size: 18px;
|
...
|
...
|
|