@@ -99,7 +99,7 @@ import SlideItem from '@/components/slide/SlideItem.vue'
import { reactive, ref } from 'vue'
import { useNav } from '@/utils/hooks/useNav'
import { Icon } from '@iconify/vue'
-import { _checkImgUrl } from '@/utils'
+import Utils, { _checkImgUrl } from '@/utils'
const nav = useNav()
@@ -181,7 +181,6 @@ function close() {
height: 100%;
width: 100%;
object-fit: cover;
- touch-action: none;
}
.indicator-bar {
diff --git a/src/utils/dom.ts b/src/utils/dom.ts
index 49ef771..b80756f 100644
--- a/src/utils/dom.ts
+++ b/src/utils/dom.ts
@@ -81,8 +81,6 @@ export default class Dom {
//情况一:获取样式
if (typeof args[0] === 'string') {
return window.getComputedStyle(this.els[this.els.length - 1], null)[args[0]]
- // return globalMethods.$getCss2
- // return this.els[0].style[args[0]]
} else {
//情况三:设置多个样式
Object.keys(args[0]).map((key) => {
@@ -142,3 +140,48 @@ export default class Dom {
return parseInt(val)
}
}
+
+export function _css(el, key, value?) {
+ const reg = /^\d+(px|pt|em|rem|vw|vh|%|rpx)$/i
+ if (value === undefined) {
+ let val = null
+ if ('getComputedStyle' in window) {
+ val = window.getComputedStyle(el, null)[key]
+ } else {
+ val = el.currentStyle[key]
+ }
+ return reg.test(val) ? parseFloat(val) : val
+ // return parseFloat(val)
+ } else {
+ if (
+ [
+ 'top',
+ 'left',
+ 'bottom',
+ 'right',
+ 'width',
+ 'height',
+ 'font-size',
+ 'margin',
+ 'padding'
+ ].includes(key)
+ ) {
+ if (!reg.test(value)) {
+ value += 'px'
+ }
+ }
+ // console.log(value)
+ if (key === 'transform') {
+ //直接设置不生效
+ el.style.webkitTransform =
+ el.style.MsTransform =
+ el.style.msTransform =
+ el.style.MozTransform =
+ el.style.OTransform =
+ el.style.transform =
+ value
+ } else {
+ el.style[key] = value
+ }
+ }
+}
diff --git a/src/utils/index.tsx b/src/utils/index.tsx
index 88b09a1..3407671 100644
--- a/src/utils/index.tsx
+++ b/src/utils/index.tsx
@@ -204,26 +204,6 @@ const Utils = {
// return reg.test(val) ? parseFloat(val) : val
return parseFloat(val)
},
- $getCss2(curEle, attr) {
- let val = null,
- reg = null
- if ('getComputedStyle' in window) {
- val = window.getComputedStyle(curEle, null)[attr]
- } else {
- //ie6~8不支持上面属性
- //不兼容
- if (attr === 'opacity') {
- val = curEle.currentStyle['filter'] //'alpha(opacity=12,345)'
- reg = /^alphaopacity=(\d+(?:\.\d+)?)opacity=(\d+(?:\.\d+)?)$/i
- val = reg.test(val) ? reg.exec(val)[1] / 100 : 1
- } else {
- val = curEle.currentStyle[attr]
- }
- }
- // reg = /^(-?\d+(\.\d)?)(px|pt|em|rem)?$/i
- // return reg.test(val) ? parseFloat(val) : val
- return val
- },
$setCss(el, key, value) {
// console.log(value)
if (key === 'transform') {
diff --git a/src/utils/slide.js b/src/utils/slide.ts
similarity index 72%
rename from src/utils/slide.js
rename to src/utils/slide.ts
index d4bd343..ef3169e 100644
--- a/src/utils/slide.js
+++ b/src/utils/slide.ts
@@ -3,6 +3,22 @@ import Utils from '@/utils/index'
import GM from '@/utils/index'
import { SlideType } from '@/utils/const_var'
import { nextTick } from 'vue'
+import { _css } from '@/utils/dom'
+
+function checkEvent(e) {
+ const isMobile = /Mobi|Android|iPhone/i.test(navigator.userAgent)
+ if (!isMobile || (isMobile && e instanceof PointerEvent)) {
+ e.touches = [
+ {
+ clientX: e.clientX,
+ clientY: e.clientY,
+ pageX: e.pageX,
+ pageY: e.pageY
+ }
+ ]
+ }
+ return true
+}
//初始化信息,获取slide dom的长宽、子元素数量,用于move事件判断能否滑动
export function slideInit(el, state) {
@@ -13,26 +29,17 @@ export function slideInit(el, state) {
})
//获取偏移量
- let t = getSlideOffset(state, el)
+ const t = getSlideOffset(state, el)
let dx1 = 0,
dx2 = 0
if (state.type === SlideType.HORIZONTAL) dx1 = t
else dx2 = t
- Utils.$setCss(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
-}
-
-export function slidePointerDown(e, el, state) {
- Utils.$setCss(el, 'transition-duration', `0ms`)
- //记录起点坐标,用于move事件计算移动距离
- state.start.x = e.touches[0].pageX
- state.start.y = e.touches[0].pageY
- //记录按下时间,用于up事件判断滑动时间
- state.start.time = Date.now()
+ _css(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
}
/**
- * 检测能否滑动
- * @param state
+ * 检测在对应方向上能否允许滑动,比如SlideHorizontal组件就只处理左右滑动事件,SlideVertical只处理上下滑动事件
+ * * @param state
* @returns {boolean}
*/
export function canSlide(state) {
@@ -41,7 +48,7 @@ export function canSlide(state) {
//判断move x和y的距离是否大于判断值,因为距离太小无法判断滑动方向
if (Math.abs(state.move.x) > state.judgeValue || Math.abs(state.move.y) > state.judgeValue) {
//放大再相除,根据长宽比判断方向,angle大于1就是左右滑动,小于是上下滑动
- let angle = (Math.abs(state.move.x) * 10) / (Math.abs(state.move.y) * 10)
+ const angle = (Math.abs(state.move.x) * 10) / (Math.abs(state.move.y) * 10)
//根据当前slide的类型,判断能否滑动,并记录下来,后续不再判断,直接返回记录值
state.next = state.type === SlideType.HORIZONTAL ? angle > 1 : angle <= 1
// console.log('angle', angle, state.next)
@@ -66,6 +73,24 @@ function canNext(state, isNext) {
)
}
+/**
+ * 开始滑动
+ * @param e
+ * @param el
+ * @param state
+ */
+export function slideTouchStart(e, el, state) {
+ // console.log('e', e, state.name)
+ if (!checkEvent(e)) return
+ _css(el, 'transition-duration', `0ms`)
+ //记录起点坐标,用于move事件计算移动距离
+ state.start.x = e.touches[0].pageX
+ state.start.y = e.touches[0].pageY
+ //记录按下时间,用于up事件判断滑动时间
+ state.start.time = Date.now()
+ state.isDown = true
+}
+
/**
* move事件
* @param e
@@ -75,7 +100,7 @@ function canNext(state, isNext) {
* @param notNextCb 不能继续滑的回调
* @param slideOtherDirectionCb 滑动其他方向时的回调,目前用于图集进于放大模式后,上下滑动推出放大模式
*/
-export function slidePointerMove(
+export function slideTouchMove(
e,
el,
state,
@@ -83,16 +108,20 @@ export function slidePointerMove(
notNextCb = null,
slideOtherDirectionCb = null
) {
+ if (!checkEvent(e)) return
+ if (!state.isDown) return
+ // console.log('move', state.name)
+
//计算移动距离
state.move.x = e.touches[0].pageX - state.start.x
state.move.y = e.touches[0].pageY - state.start.y
// console.log('move', state.name)
//检测能否滑动
- let canSlideRes = canSlide(state)
+ const canSlideRes = canSlide(state)
- //是否是往下(右)滑动
- let isNext = state.type === SlideType.HORIZONTAL ? state.move.x < 0 : state.move.y < 0
+ //是否在往到头或尾滑动
+ const isNext = state.type === SlideType.HORIZONTAL ? state.move.x < 0 : state.move.y < 0
//特别处理:竖直的slide组件,在第一页往下滑动时,向外发送事件
//用于首页顶部导航栏的刷新动画
@@ -107,13 +136,14 @@ export function slidePointerMove(
//无限滑动组件,要特别判断,所以需要传canNextCb
if (!canNextCb) canNextCb = canNext
if (canNextCb(state, isNext)) {
+ window.isMoved = true
//能滑动,那就把事件捕获,不能给父组件处理
Utils.$stopPropagation(e)
if (state.type === SlideType.HORIZONTAL) {
bus.emit(state.name + '-moveX', state.move.x)
}
//获取偏移量
- let t = getSlideOffset(state, el) + (isNext ? state.judgeValue : -state.judgeValue)
+ const t = getSlideOffset(state, el) + (isNext ? state.judgeValue : -state.judgeValue)
let dx1 = 0,
dx2 = 0
//偏移量加当前手指移动的距离就是slide要偏移的值
@@ -122,8 +152,8 @@ export function slidePointerMove(
} else {
dx2 = t + state.move.y
}
- Utils.$setCss(el, 'transition-duration', `0ms`)
- Utils.$setCss(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
+ _css(el, 'transition-duration', `0ms`)
+ _css(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
} else {
//SlideAlbum.vue组件在用,用于捕获事件,阻止事件传递给父slide
notNextCb?.()
@@ -143,25 +173,28 @@ export function slidePointerMove(
* @returns {*}
*/
export function slideTouchEnd(e, state, canNextCb = null, nextCb = null, notNextCb = null) {
- let isHorizontal = state.type === SlideType.HORIZONTAL
- let isNext = isHorizontal ? state.move.x < 0 : state.move.y < 0
+ if (!checkEvent(e)) return
+ if (!state.isDown) return
+
+ const isHorizontal = state.type === SlideType.HORIZONTAL
+ const isNext = isHorizontal ? state.move.x < 0 : state.move.y < 0
if (state.next) {
//同move事件
if (!canNextCb) canNextCb = canNext
if (canNextCb(state, isNext)) {
//能滑动,那就把事件捕获,不能给父组件处理
- Utils.$stopPropagation(e)
+ // Utils.$stopPropagation(e)
//结合时间、距离来判断是否成功滑动
- let endTime = Date.now()
+ const endTime = Date.now()
let gapTime = endTime - state.start.time
- let distance = isHorizontal ? state.move.x : state.move.y
- let judgeValue = isHorizontal ? state.wrapper.width : state.wrapper.height
+ const distance = isHorizontal ? state.move.x : state.move.y
+ const judgeValue = isHorizontal ? state.wrapper.width : state.wrapper.height
//1、距离太短,直接不通过
if (Math.abs(distance) < 20) gapTime = 1000
//2、距离太长,直接通过
if (Math.abs(distance) > judgeValue / 3) gapTime = 100
- //3、若不在上面那个情况,那么只需要判断时间即可
+ //3、若不在上述两种情况,那么只需要判断时间即可
if (gapTime < 150) {
if (isNext) {
state.localIndex++
@@ -184,9 +217,11 @@ export function slideTouchEnd(e, state, canNextCb = null, nextCb = null, notNext
* @param state
* @param emit
*/
-export function slideReset(el, state, emit = null) {
- Utils.$setCss(el, 'transition-duration', `300ms`)
- let t = getSlideOffset(state, el)
+export function slideReset(e, el, state, emit = null) {
+ if (!checkEvent(e)) return
+
+ _css(el, 'transition-duration', `300ms`)
+ const t = getSlideOffset(state, el)
let dx1 = 0
let dx2 = 0
if (state.type === SlideType.HORIZONTAL) {
@@ -196,16 +231,21 @@ export function slideReset(el, state, emit = null) {
bus.emit(state.name + '-end')
dx2 = t
}
- Utils.$setCss(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
+ _css(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
state.start.x = state.start.y = state.start.time = state.move.x = state.move.y = 0
state.next = false
state.needCheck = true
+ state.isDown = false
+ // e.target.style.pointerEvents = null
+ setTimeout(() => {
+ window.isMoved = false
+ }, 200)
emit?.('update:index', state.localIndex)
}
//根据当前index,获取slide偏移距离
//如果每个页面的宽度是相同均为100%,只需要当前index * wrapper的宽(高)度即可: -state.localIndex * state.wrapper.width
-export function getSlideOffset(state, el) {
+export function getSlideOffset(state: any, el: HTMLDivElement) {
//横竖判断逻辑基本同理
if (state.type === SlideType.HORIZONTAL) {
let widths = []
@@ -222,7 +262,10 @@ export function getSlideOffset(state, el) {
return 0
// return -state.localIndex * state.wrapper.width
} else {
+ //VERTICAL_INFINITE 列表只需要计算index * 高就行
if (state.type === SlideType.VERTICAL_INFINITE) {
+ return -state.localIndex * state.wrapper.height
+ } else {
//同上
let heights = []
Array.from(el.children).map((v) => {
@@ -231,9 +274,6 @@ export function getSlideOffset(state, el) {
heights = heights.slice(0, state.localIndex)
if (heights.length) return -heights.reduce((a, b) => a + b)
return 0
- } else {
- //VERTICAL_INFINITE 列表只需要计算index * 高就行
- return -state.localIndex * state.wrapper.height
}
}
}
diff --git a/vite.config.ts b/vite.config.ts
index df599f3..e9eaf64 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -63,12 +63,6 @@ export default defineConfig(async () => {
name: 'mockjs',
var: 'Mock',
path: 'https://lib.baomitu.com/Mock.js/1.0.1-beta3/mock-min.js'
- },
-
- {
- name: 'jquery',
- var: '$',
- path: 'https://lib.baomitu.com/jquery/3.6.0/jquery.min.js'
}
]
})