提交 2ef3852d 编写于 作者: D DCloud_LXH

feat(h5): swiper add navigation

上级 feaa4d1f
<script>
import touchtrack from 'uni-mixins/touchtrack'
import { deepClone } from 'uni-shared'
......@@ -66,6 +65,18 @@ export default {
disableTouch: {
type: [Boolean, String],
default: false
},
navigation: {
type: [Boolean, String],
default: false
},
navigationColor: {
type: String,
default: '#fff'
},
navigationActiveColor: {
type: String,
default: 'rgba(53, 53, 53, 0.6)'
}
},
data () {
......@@ -74,7 +85,12 @@ export default {
currentItemIdSync: this.currentItemId || '',
userTracking: false,
currentChangeSource: '',
items: []
items: [],
isNavigationAuto: false,
hideNavigation: false,
prevDisabled: false,
nextDisabled: false
}
},
computed: {
......@@ -114,8 +130,11 @@ export default {
height: !this.vertical ? '100%' : value
}
},
swiperEnabled () {
return this.items.length > this.displayMultipleItemsNumber
},
circularEnabled () {
return this.circular && this.items.length > this.displayMultipleItemsNumber
return this.circular && this.swiperEnabled
}
},
watch: {
......@@ -137,6 +156,7 @@ export default {
currentSync (val, oldVal) {
this._currentChanged(val, oldVal)
this.$emit('update:current', val)
this._setNavigationState()
},
currentItemId (val) {
this._currentCheck()
......@@ -146,6 +166,21 @@ export default {
},
displayMultipleItemsNumber () {
this._resetLayout()
},
navigation (val) {
this.isNavigationAuto = val === 'auto'
this.hideNavigation = val !== true || this.isNavigationAuto
this._navigationSwiperAddMouseEvent()
},
items () {
this._setNavigationState()
},
swiperEnabled (val) {
if (!val) {
this.prevDisabled = true
this.nextDisabled = true
this.isNavigationAuto && (this.hideNavigation = true)
}
}
},
created () {
......@@ -168,6 +203,7 @@ export default {
}, this._inintAutoplay)
this._inintAutoplay(this.autoplay && !this.userTracking)
this.$watch('items.length', this._resetLayout)
this._navigationSwiperAddMouseEvent()
},
beforeDestroy () {
this._cancelSchedule()
......@@ -464,6 +500,8 @@ export default {
position += length
}
}
} else if (source === 'click') {
current = current + this.displayMultipleItemsNumber - 1 < length ? current : 0
}
this._animating = {
......@@ -586,6 +624,91 @@ export default {
return false
}
}
},
/**
* navigation
*/
_onSwiperDotClick (index) {
this._animateViewport(
(this.currentSync = index),
(this.currentChangeSource = 'click'),
this.circularEnabled ? 1 : 0
)
},
_navigationClick (type) {
const swiperItemLength = this.items.length
let _current = this.currentSync
switch (type) {
case 'prev':
_current--
if (_current < 0 && this.circularEnabled) {
_current = swiperItemLength - 1
}
break
case 'next':
_current++
if (_current >= swiperItemLength && this.circularEnabled) {
_current = 0
}
break
}
this._onSwiperDotClick(_current)
},
_navigationMouseMove (e) {
const { clientX, clientY } = e
const {
left,
right,
top,
bottom,
width,
height
} = this.$refs.slidesWrapper.getBoundingClientRect()
if (this.vertical) {
this.hideNavigation = !(
clientY - top < height / 3 || bottom - clientY < height / 3
)
} else {
this.hideNavigation = !(
clientX - left < width / 3 || right - clientX < width / 3
)
}
},
_navigationMouseOut () {
this.hideNavigation = true
},
_navigationSwiperAddMouseEvent () {
if (__PLATFORM__ === 'h5') {
const rootRef = this.$refs.slidesWrapper
if (rootRef) {
rootRef.removeEventListener('mousemove', this._navigationMouseMove)
rootRef.removeEventListener('mouseout', this._navigationMouseOut)
if (this.isNavigationAuto) {
rootRef.addEventListener('mousemove', this._navigationMouseMove)
rootRef.addEventListener('mouseout', this._navigationMouseOut)
}
}
}
},
_navigationHover (event, type) {
const target = event.currentTarget
if (!target) return
target.style.backgroundColor =
type === 'over' ? this.navigationActiveColor : ''
},
_setNavigationState () {
const swiperItemLength = this.items.length
const notCircular = !this.circularEnabled
this.prevDisabled = this.currentSync === 0 && notCircular
this.nextDisabled =
(this.currentSync === swiperItemLength - 1 && notCircular) ||
(notCircular &&
this.currentSync + this.displayMultipleItemsNumber >= swiperItemLength)
}
},
render (createElement) {
......@@ -602,9 +725,7 @@ export default {
const currentSync = this.currentSync
slidesDots.push(createElement('div', {
on: {
click: () => {
this._animateViewport(this.currentSync = index, this.currentChangeSource = 'click', this.circularEnabled ? 1 : 0)
}
click: () => this._onSwiperDotClick(index)
},
class: {
'uni-swiper-dot': true,
......@@ -634,6 +755,70 @@ export default {
}, slidesDots))
}
if (__PLATFORM__ === 'h5') {
if (this.navigation) {
const navigationClass = {
'uni-swiper-navigation-hide': this.hideNavigation,
'uni-swiper-navigation-vertical': this.vertical
}
const iconElement = createElement(
'i',
{
domProps: {
innerHTML: '&#xe601;'
},
class: 'uni-btn-icon',
style: { color: this.navigationColor, fontSize: '26px' }
}
)
const navigationEvent = {
mouseover: event => this._navigationHover(event, 'over'),
mouseout: event => this._navigationHover(event, 'out')
}
slidesWrapperChild.push(
createElement(
'div',
{
on: {
click: () => this._navigationClick('prev'),
...navigationEvent
},
class: [
'uni-swiper-navigation',
'uni-swiper-navigation-prev',
{
'uni-swiper-navigation-disabled': this.prevDisabled,
...navigationClass
}
]
},
[iconElement]
),
createElement(
'div',
{
on: {
click: () => this._navigationClick('next'),
...navigationEvent
},
class: [
'uni-swiper-navigation',
'uni-swiper-navigation-next',
{
'uni-swiper-navigation-disabled': this.nextDisabled,
...navigationClass
}
]
},
[iconElement]
)
)
}
}
return createElement(
'uni-swiper', {
on: this.$listeners
......@@ -734,4 +919,71 @@ uni-swiper .uni-swiper-dot {
uni-swiper .uni-swiper-dot-active {
background-color: #000000;
}
uni-swiper .uni-swiper-navigation {
width: 26px;
height: 26px;
cursor: pointer;
position: absolute;
top: 50%;
margin-top: -13px;
display: flex;
align-items: center;
transition: all 0.2s;
border-radius: 50%;
opacity: 1;
}
uni-swiper .uni-swiper-navigation-disabled {
opacity: 0.35;
cursor: auto;
pointer-events: none;
}
uni-swiper .uni-swiper-navigation-hide {
opacity: 0;
cursor: auto;
pointer-events: none;
}
uni-swiper .uni-swiper-navigation-prev {
left: 10px;
}
uni-swiper .uni-swiper-navigation-prev i {
margin-left: -1px;
left: 10px;
}
uni-swiper .uni-swiper-navigation-prev.uni-swiper-navigation-vertical {
top: 18px;
left: 50%;
margin-left: -13px;
}
uni-swiper .uni-swiper-navigation-prev.uni-swiper-navigation-vertical i {
transform: rotate(90deg);
margin-left: auto;
margin-top: -2px;
}
uni-swiper .uni-swiper-navigation-next {
right: 10px;
}
uni-swiper .uni-swiper-navigation-next i {
transform: rotate(180deg);
}
uni-swiper .uni-swiper-navigation-next.uni-swiper-navigation-vertical {
top: auto;
bottom: 5px;
left: 50%;
margin-left: -13px;
}
uni-swiper .uni-swiper-navigation-next.uni-swiper-navigation-vertical i {
margin-top: 2px;
transform: rotate(270deg);
}
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册