Browse Source

修复移动端触发不了右键点击事件问题

master
许孟阳 1 week ago
parent
commit
e28702074d
  1. 6
      src/components/dialog.vue
  2. 2
      src/store/mutation.ts
  3. 1
      src/tool/index.ts
  4. 4
      src/tool/mixins/popoverMenu.ts
  5. 47
      src/tool/mobile.ts
  6. 1
      src/views/backpack/backpack.vue
  7. 24
      src/views/backpack/grid.vue
  8. 3
      src/views/index.vue
  9. 33
      src/views/shop/shop.vue

6
src/components/dialog.vue

@ -1,6 +1,7 @@
<template> <template>
<teleport to="#app"> <teleport to="#app">
<div class="dialog" v-show="show" @contextmenu.prevent="console.log('禁用浏览器默认右键功能')"> <div class="dialog" v-show="show" @contextmenu.prevent="console.log('禁用浏览器默认右键功能')"
@click=" commit('close_equip_tip');">
<div class="content" @click.native.stop> <div class="content" @click.native.stop>
<div class="title" v-if="title"> <div class="title" v-if="title">
<span>{{ title }}</span> <span>{{ title }}</span>
@ -63,6 +64,9 @@ const prop = defineProps({
}) })
watch(show, (n, o) => { watch(show, (n, o) => {
emit('update:modelValue', n); emit('update:modelValue', n);
if (!n) {
commit('close_equip_tip');
}
}) })
watch(() => prop.modelValue, (n, o) => { watch(() => prop.modelValue, (n, o) => {
show.value = n; show.value = n;

2
src/store/mutation.ts

@ -41,11 +41,9 @@ export const show_equip_tip = (state, data) => {
state.equipTip.tipsStyle = styles[0]; state.equipTip.tipsStyle = styles[0];
state.equipTip.tipsStyle2 = styles[1]; state.equipTip.tipsStyle2 = styles[1];
state.equipTip.tipsShow = true; state.equipTip.tipsShow = true;
console.log('show');
}; };
export const close_equip_tip = (state) => { export const close_equip_tip = (state) => {
state.equipTip.tipsShow = false; state.equipTip.tipsShow = false;
console.log('close');
}; };
export const clear_sys_info = (state, data) => { export const clear_sys_info = (state, data) => {
state.sysInfo.splice(1, state.sysInfo.length); state.sysInfo.splice(1, state.sysInfo.length);

1
src/tool/index.ts

@ -2,6 +2,7 @@ export * from './caller';
export * from './formatter'; export * from './formatter';
export * from './random'; export * from './random';
export * from './mixins'; export * from './mixins';
export * from './mobile';
export const getArrayEmptyIdx = (array) => { export const getArrayEmptyIdx = (array) => {
for (let i = 0; i < array.length; i++) { for (let i = 0; i < array.length; i++) {

4
src/tool/mixins/popoverMenu.ts

@ -9,8 +9,8 @@ export default class PopoverMenu {
open = (idx, e) => { open = (idx, e) => {
this.index.value = idx; this.index.value = idx;
this.left.value = e.x + 20 + 'px'; this.left.value = e.pageX + 20 + 'px';
this.top.value = e.y + -50 + 'px'; this.top.value = e.pageY + -50 + 'px';
this.show.value = true; this.show.value = true;
}; };

47
src/tool/mobile.ts

@ -0,0 +1,47 @@
// 长按弹出上拉操作面板
class Mobile {
toucheX: number = 0;
toucheY: number = 0;
timeOutEvent: number = 0;
data?: any;
onLongTouch?: Function;
onClick?: Function;
e: any;
onTouchStart(e, data) {
this.toucheX = e.targetTouches[0].screenX;
this.toucheY = e.targetTouches[0].screenY;
this.data = data;
this.e = e;
// 开启定时器前先清除定时器,防止重复触发
this.timeOutEvent && clearTimeout(this.timeOutEvent);
// 显示上拉面板
this.timeOutEvent = setTimeout(() => {
this.onLongTouch && this.onLongTouch(e, data);
this.timeOutEvent = 0;
}, 1000);
e.preventDefault(); // 阻止系统默认事件
}
onTouchMove(e) {
const moveX = e.targetTouches[0].screenX;
const moveY = e.targetTouches[0].screenY;
// 解决vivo机型,手指没有move,touchmove事件仍然会调用而导致setTimeout被clear
if (this.toucheX !== moveX || this.toucheY !== moveY) {
// 手指滑动,清除定时器,中断长按逻辑
this.timeOutEvent && clearTimeout(this.timeOutEvent);
}
}
onTouchEnd() {
// 清除定时器,结束长按逻辑
this.timeOutEvent && clearTimeout(this.timeOutEvent);
// 若手指离开屏幕,时间小于我们设置的长按时间,则为点击事件
if (this.timeOutEvent !== 0) {
this.onClick && this.onClick(this.e, this.data);
}
}
}
export const userMobile = () => {
return new Mobile();
};

1
src/views/backpack/backpack.vue

@ -33,6 +33,7 @@ const show = computed(() => {
const equipMenu = ref(); const equipMenu = ref();
const openEquipMenu = (idx, event) => { const openEquipMenu = (idx, event) => {
event.preventDefault();
commit('close_equip_tip'); commit('close_equip_tip');
equipMenu.value?.open(idx, event) equipMenu.value?.open(idx, event)
} }

24
src/views/backpack/grid.vue

@ -2,7 +2,8 @@
<div class="body"> <div class="body">
<span class="grid" v-for="(v, idx) in grid"> <span class="grid" v-for="(v, idx) in grid">
<div class="equip" v-if="v" @contextmenu.prevent.stop="emit('openEquipMenu', idx, $event)" <div class="equip" v-if="v" @contextmenu.prevent.stop="emit('openEquipMenu', idx, $event)"
@dblclick="commit('close_equip_tip'); dispatch('useEquip', idx);" @touchstart="mobile.onTouchStart($event, [v, idx])" @touchmove="mobile.onTouchMove"
@touchend="mobile.onTouchEnd" @dblclick="commit('close_equip_tip'); dispatch('useEquip', idx);"
@mouseover="commit('show_equip_tip', { equip: v, compare: true, e: $event })" @mouseover="commit('show_equip_tip', { equip: v, compare: true, e: $event })"
@mouseleave="commit('close_equip_tip')"> @mouseleave="commit('close_equip_tip')">
<EquipIcon :equip="v" /> <EquipIcon :equip="v" />
@ -30,6 +31,7 @@ import { useI18n } from "vue3-i18n";
import EquipIcon from "@/components/equip-icon.vue"; import EquipIcon from "@/components/equip-icon.vue";
import { lock_icon, backpack_num } from "@/config"; import { lock_icon, backpack_num } from "@/config";
import AutoSell from "./auto-sell.vue"; import AutoSell from "./auto-sell.vue";
import { userMobile } from "@/tool";
const { t } = useI18n(); const { t } = useI18n();
const { state, commit, dispatch } = useStore(); const { state, commit, dispatch } = useStore();
@ -67,6 +69,14 @@ const sellAll = () => {
}) })
} }
const mobile = userMobile();
mobile.onLongTouch = (e, data) => {
e.touches[0].preventDefault = () => { };
emit('openEquipMenu', data[1], e.touches[0]);
}
mobile.onClick = (e, data) => {
commit('show_equip_tip', { equip: data[0], compare: true, e: e.touches[0] })
}
onMounted(() => { }); onMounted(() => { });
</script> </script>
@ -95,6 +105,18 @@ onMounted(() => { });
width: 100%; width: 100%;
cursor: pointer; cursor: pointer;
position: relative; position: relative;
-webkit-touch-callout: none;
/*系统默认菜单被禁用*/
-webkit-user-select: none;
/*webkit浏览器*/
-khtml-user-select: none;
/*早起浏览器*/
-moz-user-select: none;
/*火狐浏览器*/
-ms-user-select: none;
/*IE浏览器*/
user-select: none;
/*用户是否能够选中文本*/
} }
.equip-lock { .equip-lock {

3
src/views/index.vue

@ -1,5 +1,6 @@
<template> <template>
<div id="main" class="main" @click="playBackgound" @contextmenu.prevent="playBackgound"> <div id="main" class="main" @click="playBackgound; commit('close_equip_tip')"
@contextmenu.prevent="playBackgound()">
<div class="infomation"> <div class="infomation">
<Message /> <Message />
</div> </div>

33
src/views/shop/shop.vue

@ -9,7 +9,8 @@
</div> </div>
<div class="items"> <div class="items">
<div class="item" v-for="(v, k) in shopItems" :key="k" <div class="item" v-for="(v, k) in shopItems" :key="k"
@contextmenu.prevent.stop="commit('close_equip_tip'); v && open(k, $event)" @contextmenu.prevent.stop="openPropMenu(v, k, $event)" @touchstart="mobile.onTouchStart($event, [v, k])"
@touchmove="mobile.onTouchMove" @touchend="mobile.onTouchEnd"
@mouseover="commit('show_equip_tip', { equip: v, compare: true, e: $event })" @mouseover="commit('show_equip_tip', { equip: v, compare: true, e: $event })"
@mouseleave="commit('close_equip_tip')"> @mouseleave="commit('close_equip_tip')">
<EquipIcon :equip="v" @dblclick="commit('close_equip_tip'); buyEquip(k);" /> <EquipIcon :equip="v" @dblclick="commit('close_equip_tip'); buyEquip(k);" />
@ -48,7 +49,7 @@ import { useI18n } from "vue3-i18n";
import { Tooltip, EquipIcon, Dialog, PopoverMenu, Confirm } from "@/components" import { Tooltip, EquipIcon, Dialog, PopoverMenu, Confirm } from "@/components"
import { randomEquipQuality } from '@/tool'; import { randomEquipQuality } from '@/tool';
import { menu_icons, qualitys } from '@/config'; import { menu_icons, qualitys } from '@/config';
import { usePopoverMenu, conisOfBuy, getArrayEmptyIdx } from "@/tool"; import { usePopoverMenu, conisOfBuy, getArrayEmptyIdx, userMobile } from "@/tool";
const { t } = useI18n(); const { t } = useI18n();
const { state, commit, dispatch } = useStore(); const { state, commit, dispatch } = useStore();
@ -157,6 +158,22 @@ const showMenu = () => {
state.curMenu = showShop.value ? null : 'shop'; state.curMenu = showShop.value ? null : 'shop';
} }
const openPropMenu = (equip, idx, e) => {
e.preventDefault();
commit('close_equip_tip');
equip && open(idx, e);
}
const mobile = userMobile();
mobile.onLongTouch = (e, data) => {
commit('close_equip_tip');
data[0] && open(data[1], e.touches[0]);
}
mobile.onClick = (e, data) => {
commit('show_equip_tip', { equip: data[0], compare: true, e: e.touches[0] })
}
const keydown = (e) => { const keydown = (e) => {
if (e.keyCode == 83 && !e.ctrlKey) { if (e.keyCode == 83 && !e.ctrlKey) {
showMenu(); showMenu();
@ -203,6 +220,18 @@ onBeforeUnmount(() => {
.item { .item {
float: left; float: left;
margin: 1rem; margin: 1rem;
-webkit-touch-callout: none;
/*系统默认菜单被禁用*/
-webkit-user-select: none;
/*webkit浏览器*/
-khtml-user-select: none;
/*早起浏览器*/
-moz-user-select: none;
/*火狐浏览器*/
-ms-user-select: none;
/*IE浏览器*/
user-select: none;
/*用户是否能够选中文本*/
} }
.icons { .icons {

Loading…
Cancel
Save