refactor: handling click event conflicts

This commit is contained in:
zyronon 2024-04-25 02:12:55 +08:00
parent 6107b19d03
commit b18664a3a6
14 changed files with 63 additions and 73 deletions

View File

@ -84,10 +84,12 @@ export default {
let maskTemplate = `<div class="Mask fade-in ${this.maskMode}"></div>` let maskTemplate = `<div class="Mask fade-in ${this.maskMode}"></div>`
let mask = new Dom().create(maskTemplate) let mask = new Dom().create(maskTemplate)
mask.on('click', (e) => { setTimeout(() => {
_stopPropagation(e) mask.on('click', (e) => {
this.hide(false) _stopPropagation(e)
}) this.hide(false)
})
}, 200)
page.appendChild(mask.els[0]) page.appendChild(mask.els[0])
} else { } else {
page.style.position = this.pagePosition || 'fixed' page.style.position = this.pagePosition || 'fixed'

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import BaseMusic from '../BaseMusic' import BaseMusic from '../BaseMusic'
import { _formatNumber, _updateItem } from '@/utils' import { _dateFormat, _formatNumber, _updateItem } from '@/utils'
import bus, { EVENT_KEY } from '@/utils/bus' import bus, { EVENT_KEY } from '@/utils/bus'
import { Icon } from '@iconify/vue' import { Icon } from '@iconify/vue'
@ -38,9 +38,14 @@ function attention(e) {
} }
function showComments() { function showComments() {
console.log('showComments', _dateFormat(Date.now()))
// emit('showComments') // emit('showComments')
bus.emit(EVENT_KEY.OPEN_COMMENTS, props.item.id) bus.emit(EVENT_KEY.OPEN_COMMENTS, props.item.id)
} }
function s() {
console.log('ss', _dateFormat(Date.now()))
}
</script> </script>
<template> <template>
@ -50,45 +55,45 @@ function showComments() {
class="avatar" class="avatar"
:src="props.item.author.avatar_168x168.url_list[0]" :src="props.item.author.avatar_168x168.url_list[0]"
alt="" alt=""
@click.stop="bus.emit(EVENT_KEY.GO_USERINFO)" @pointerup="bus.emit(EVENT_KEY.GO_USERINFO)"
/> />
<transition name="fade"> <transition name="fade">
<div v-if="!props.item.isAttention" @click.stop="attention" class="options"> <div v-if="!props.item.isAttention" @pointerup="attention" class="options">
<img class="no" src="../../assets/img/icon/add-light.png" alt="" /> <img class="no" src="../../assets/img/icon/add-light.png" alt="" />
<img class="yes" src="../../assets/img/icon/ok-red.png" alt="" /> <img class="yes" src="../../assets/img/icon/ok-red.png" alt="" />
</div> </div>
</transition> </transition>
</div> </div>
<div class="love mb2r" @click.stop="loved($event)"> <div class="love mb2r" @pointerup="loved($event)">
<div> <div>
<img src="../../assets/img/icon/love.svg" class="love-image" v-if="!props.item.isLoved" /> <img src="../../assets/img/icon/love.svg" class="love-image" v-if="!props.item.isLoved" />
<img src="../../assets/img/icon/loved.svg" class="love-image" v-if="props.item.isLoved" /> <img src="../../assets/img/icon/loved.svg" class="love-image" v-if="props.item.isLoved" />
</div> </div>
<span>{{ _formatNumber(props.item.statistics.digg_count) }}</span> <span>{{ _formatNumber(props.item.statistics.digg_count) }}</span>
</div> </div>
<div class="message mb2r" @click.stop="showComments"> <div class="message mb2r" @pointerup="showComments">
<Icon icon="mage:message-dots-round-fill" class="icon" style="color: white" /> <Icon icon="mage:message-dots-round-fill" class="icon" style="color: white" />
<span>{{ _formatNumber(props.item.statistics.comment_count) }}</span> <span>{{ _formatNumber(props.item.statistics.comment_count) }}</span>
</div> </div>
<!--TODO --> <!--TODO -->
<div <div
class="message mb2r" class="message mb2r"
@click.stop="_updateItem(props, 'isCollect', !props.item.isCollect, emit)" @pointerup="_updateItem(props, 'isCollect', !props.item.isCollect, emit)"
> >
<Icon v-if="props.item.isCollect" icon="ic:round-star" class="icon" style="color: yellow" /> <Icon v-if="props.item.isCollect" icon="ic:round-star" class="icon" style="color: yellow" />
<Icon v-else icon="ic:round-star" class="icon" style="color: white" /> <Icon v-else icon="ic:round-star" class="icon" style="color: white" />
<span>{{ _formatNumber(props.item.statistics.comment_count) }}</span> <span>{{ _formatNumber(props.item.statistics.comment_count) }}</span>
</div> </div>
<div v-if="!props.isMy" class="share mb2r" @click.stop="bus.emit(EVENT_KEY.SHOW_SHARE)"> <div v-if="!props.isMy" class="share mb2r" @pointerup="bus.emit(EVENT_KEY.SHOW_SHARE)">
<img src="../../assets/img/icon/share-white-full.png" alt="" class="share-image" /> <img src="../../assets/img/icon/share-white-full.png" alt="" class="share-image" />
<span>{{ _formatNumber(props.item.statistics.share_count) }}</span> <span>{{ _formatNumber(props.item.statistics.share_count) }}</span>
</div> </div>
<div v-else class="share mb2r" @click.stop="bus.emit(EVENT_KEY.SHOW_SHARE)"> <div v-else class="share mb2r" @pointerup="bus.emit(EVENT_KEY.SHOW_SHARE)">
<img src="../../assets/img/icon/menu-white.png" alt="" class="share-image" /> <img src="../../assets/img/icon/menu-white.png" alt="" class="share-image" />
</div> </div>
<!-- <BaseMusic--> <!-- <BaseMusic-->
<!-- :cover="props.item.music.cover"--> <!-- :cover="props.item.music.cover"-->
<!-- @click.stop="$nav('/home/music')"--> <!-- @pointerup="$nav('/home/music')"-->
<!-- /> --> <!-- /> -->
<BaseMusic :item="props.item" /> <BaseMusic :item="props.item" />
</div> </div>

View File

@ -131,9 +131,9 @@ function touchEnd(e) {
<div <div
class="slide-list" class="slide-list"
ref="slideListEl" ref="slideListEl"
@pointerdown="touchStart" @pointerdown.prevent="touchStart"
@pointermove="touchMove" @pointermove.prevent="touchMove"
@pointerup="touchEnd" @pointerup.prevent="touchEnd"
> >
<slot></slot> <slot></slot>
</div> </div>

View File

@ -92,9 +92,9 @@ function touchEnd(e) {
<div <div
class="slide-list flex-direction-column" class="slide-list flex-direction-column"
ref="slideListEl" ref="slideListEl"
@pointerdown="touchStart" @pointerdown.prevent="touchStart"
@pointermove="touchMove" @pointermove.prevent="touchMove"
@pointerup="touchEnd" @pointerup.prevent="touchEnd"
> >
<slot></slot> <slot></slot>
</div> </div>

View File

@ -276,12 +276,17 @@ function touchEnd(e) {
if (state.localIndex > props.list.length - props.virtualTotal && state.localIndex > half) { if (state.localIndex > props.list.length - props.virtualTotal && state.localIndex > half) {
emit('loadMore') emit('loadMore')
} }
let addItemIndex = state.localIndex + half
let res = slideListEl.value.querySelector(`.${itemClassName}[data-index='${addItemIndex}']`) // console.log('props.list.length', props.list.length, state.localIndex)
if (!res) { if (state.localIndex > half && state.localIndex < props.list.length - half) {
slideListEl.value.appendChild(getInsEl(props.list[addItemIndex], addItemIndex)) let addItemIndex = state.localIndex + half
} let res = slideListEl.value.querySelector(
if (state.localIndex > half) { `.${itemClassName}[data-index='${addItemIndex}']`
)
if (!res) {
slideListEl.value.appendChild(getInsEl(props.list[addItemIndex], addItemIndex))
}
let index = slideListEl.value let index = slideListEl.value
.querySelector(`.${itemClassName}:first-child`) .querySelector(`.${itemClassName}:first-child`)
.getAttribute('data-index') .getAttribute('data-index')
@ -292,15 +297,14 @@ function touchEnd(e) {
}) })
} }
} else { } else {
let addIndex = state.localIndex - half if (state.localIndex >= half && state.localIndex < props.list.length - (half + 1)) {
if (addIndex >= 0) { let addIndex = state.localIndex - half
let res = slideListEl.value.querySelector(`.${itemClassName}[data-index='${addIndex}']`) if (addIndex >= 0) {
if (!res) { let res = slideListEl.value.querySelector(`.${itemClassName}[data-index='${addIndex}']`)
slideListEl.value.prepend(getInsEl(props.list[addIndex], addIndex)) if (!res) {
slideListEl.value.prepend(getInsEl(props.list[addIndex], addIndex))
}
} }
}
if (state.localIndex >= half) {
let index = slideListEl.value let index = slideListEl.value
.querySelector(`.${itemClassName}:last-child`) .querySelector(`.${itemClassName}:last-child`)
.getAttribute('data-index') .getAttribute('data-index')
@ -310,27 +314,6 @@ function touchEnd(e) {
_css(item, 'top', (state.localIndex - half) * state.wrapper.height) _css(item, 'top', (state.localIndex - half) * state.wrapper.height)
}) })
} }
// if (state.localIndex > 1 && state.localIndex <= props.list.length - 4) {
// if (!res) {
// slideListEl.value.prepend(getInsEl(props.list[addIndex], addIndex))
// let index = slideListEl.value
// .querySelector(`.${itemClassName}:last-child`)
// .getAttribute('data-index')
// appInsMap.get(Number(index)).unmount()
// // $(slideListEl.value).find(".base-slide-item:last").remove()
// slideListEl.value.querySelectorAll(`.${itemClassName}`).forEach((item) => {
// _css(item, 'top', (state.localIndex - 2) * state.wrapper.height)
// })
// }
// }
//
// if (state.wrapper.childrenLength > props.virtualTotal) {
// let index = slideListEl.value
// .querySelector(`.${itemClassName}:last-child`)
// .getAttribute('data-index')
// appInsMap.get(Number(index)).unmount()
// }
} }
state.wrapper.childrenLength = slideListEl.value.children.length state.wrapper.childrenLength = slideListEl.value.children.length
} }
@ -353,9 +336,9 @@ function canNext(state, isNext) {
class="slide-list flex-direction-column" class="slide-list flex-direction-column"
ref="slideListEl" ref="slideListEl"
@click="null" @click="null"
@pointerdown="touchStart" @pointerdown.prevent="touchStart"
@pointermove="touchMove" @pointermove.prevent="touchMove"
@pointerup="touchEnd" @pointerup.prevent="touchEnd"
> >
<slot></slot> <slot></slot>
</div> </div>

View File

@ -17,7 +17,7 @@ HTMLElement.prototype.addEventListener = new Proxy(HTMLElement.prototype.addEven
if (listener instanceof Function && eventName === 'click') { if (listener instanceof Function && eventName === 'click') {
args[1] = new Proxy(listener, { args[1] = new Proxy(listener, {
apply(target, ctx, args) { apply(target, ctx, args) {
// console.log('点击', window.isMoved) console.log('点击', window.isMoved)
if (window.isMoved) return if (window.isMoved) return
try { try {
return target.apply(ctx, args) return target.apply(ctx, args)

View File

@ -134,14 +134,14 @@ async function fetchData() {
//TODO 有个bug一开始只返回了6条数据但第二次前端传过来的pageNo是2了就是会从第10条数据开始返回导致中间漏了4条 //TODO 有个bug一开始只返回了6条数据但第二次前端传过来的pageNo是2了就是会从第10条数据开始返回导致中间漏了4条
export async function startMock() { export async function startMock() {
mock.onGet(/video\/recommended/).reply(async (config) => { mock.onGet(/video\/recommended/).reply(async (config) => {
const page = getPage2(config.params) const { start, pageSize } = config.params
console.log('allRecommendVideos', cloneDeep(allRecommendVideos.length), page) // console.log('allRecommendVideos', cloneDeep(allRecommendVideos.length), config.params)
return [ return [
200, 200,
{ {
data: { data: {
total: 844, total: 844,
list: allRecommendVideos.slice(page.offset, page.limit) // list: allRecommendVideos.slice(0, 6), list: allRecommendVideos.slice(start, start + pageSize) // list: allRecommendVideos.slice(0, 6),
}, },
code: 200, code: 200,
msg: '' msg: ''

View File

@ -69,25 +69,25 @@ const state = reactive({
index: props.index, index: props.index,
list: props.list, list: props.list,
totalSize: 0, totalSize: 0,
pageSize: 10, pageSize: 10
pageNo: 0
}) })
function loadMore() { function loadMore() {
console.log('load')
if (!baseStore.loading) { if (!baseStore.loading) {
state.pageNo++
getData() getData()
} }
} }
async function getData(refresh = false) { async function getData(refresh = false) {
if (!refresh && state.totalSize === state.list.length) return
if (baseStore.loading) return if (baseStore.loading) return
baseStore.loading = true baseStore.loading = true
let res = await props.api({ let res = await props.api({
pageNo: refresh ? 0 : state.pageNo, start: refresh ? 0 : state.list.length,
pageSize: state.pageSize pageSize: state.pageSize
}) })
// console.log('getSlide4Data-', 'refresh', refresh, res) // console.log('getSlide4Data-', refresh, res, state.totalSize, state.list.length)
baseStore.loading = false baseStore.loading = false
if (res.success) { if (res.success) {
state.totalSize = res.data.total state.totalSize = res.data.total
@ -95,8 +95,6 @@ async function getData(refresh = false) {
state.list = [] state.list = []
} }
state.list = state.list.concat(res.data.list) state.list = state.list.concat(res.data.list)
} else {
state.pageNo--
} }
} }

View File

@ -34,6 +34,7 @@ export default {
this.eventMap = new Map() this.eventMap = new Map()
}, },
emit(eventType, val?) { emit(eventType, val?) {
console.log('emit', eventType, val)
const cbs = this.eventMap.get(eventType) const cbs = this.eventMap.get(eventType)
if (cbs) { if (cbs) {
cbs.map((cb) => cb(val)) cbs.map((cb) => cb(val))

View File

@ -1,5 +1,5 @@
import SlideUser from '@/components/slide/SlideUser.vue' import SlideUser from '@/components/slide/SlideUser.vue'
import BVideo from '@/components/slide/BVideo.vue' import BaseVideo from '@/components/slide/BaseVideo.vue'
export function useSlideListItemRender(props) { export function useSlideListItemRender(props) {
return function render(item, index, play, uniqueId) { return function render(item, index, play, uniqueId) {
@ -20,7 +20,7 @@ export function useSlideListItemRender(props) {
break break
default: default:
node = ( node = (
<BVideo <BaseVideo
isPlay={play} isPlay={play}
item={item} item={item}
index={index} index={index}

View File

@ -62,7 +62,7 @@ export function _formatNumber(num) {
} }
} }
export function _dateFormat(val, type): string { export function _dateFormat(val, type?): string {
if (!val) return if (!val) return
if (String(val).length === 10) { if (String(val).length === 10) {
val = val * 1000 val = val * 1000

View File

@ -104,7 +104,7 @@ export default {
} }
}, },
love: { love: {
beforeMount: function (el, binding) { beforeMount: function (el: HTMLDivElement, binding) {
let isDbClick = false let isDbClick = false
let clickTimer = null let clickTimer = null
let dbClickTimer = null let dbClickTimer = null

View File

@ -183,7 +183,8 @@ export function slideTouchEnd(e, state, canNextCb = null, nextCb = null, notNext
if (!canNextCb) canNextCb = canNext if (!canNextCb) canNextCb = canNext
if (canNextCb(state, isNext)) { if (canNextCb(state, isNext)) {
//能滑动,那就把事件捕获,不能给父组件处理 //能滑动,那就把事件捕获,不能给父组件处理
// Utils.$stopPropagation(e) // _stopPropagation(e)
//结合时间、距离来判断是否成功滑动 //结合时间、距离来判断是否成功滑动
const endTime = Date.now() const endTime = Date.now()
let gapTime = endTime - state.start.time let gapTime = endTime - state.start.time