网站上有菜单。对于移动设备,它具有完整的宽度和高度。在 Android 设备上,它工作得很好,但是当在 iPhone (safari) 上使用菜单时,菜单开始表现得很奇怪,导致菜单下的点击起作用。
如果菜单项下没有任何内容,则工作正常。但是如果菜单项下面有一些按钮或链接,那么它就不算菜单项,有时在它下面点击一下就可以了
这是 vue 组件:
<div class="header-content-catalog">
<button v-click-outside="hideCategories" class="btn btn-warning" @click="toggleCategories(), showFirstRecommend()">
<i class="icofont-navigation-menu" />
<span>
catalog
</span>
</button>
<div :class="[{ 'show-categories': showCategories }, 'header-content-catalog-modal']">
<div class="catalog-modal-dismiss">
X
</div>
<div class="catalog-modal-list">
<ul>
<li
v-for="item in categories"
:key="item.id"
:class="[{hovering: item.id === +$route.params.id}, 'catalog-modal-list-item']">
<nuxt-link :to="`/mebel/${item.id}`" @click.stop>
{{ item.name }}
</nuxt-link>
<!-- this is a recommended product, displayed on the desktop, on mobile devices the block is hidden -->
<div v-if="item.recommended_product_id != 0" class="catalog-modal-list-item_recommended category-content__item">
<h5>Recommended products</h5>
<div class="card-wrapper">
<nuxt-link :to="'/mebel/product/' + item.recommended_product_id" @click.stop>
<div class="card" style="width: 18rem; height: auto;">
<div class="card-img-wrap">
<nuxt-img format="webp" :src="api_url + `uploads/` + item.product_photos[0]" class="card-img-top" :alt="item.product_name" loading="lazy" />
</div>
<div class="card-body">
<div class="card-stars">
<client-only>
<star-rating
:rating="+item.rating"
:rounded-corners="true"
:border-width="1"
:star-size="20"
:read-only="true"
:show-rating="false"
class="mb-2"
/>
</client-only>
</div>
<div class="card-available">
in stock
</div>
<h5 v-if="item.price > 0" class="card-title">
{{ item.price_from ? 'from' : '' }} {{ item.product_price }}$
</h5>
<p class="card-text">
{{ item.product_name }}
</p>
</div>
</div>
</nuxt-link>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
vue 组件在这里:
<!-- directive for click outside - close menu -->
directives: {
ClickOutside
},
data () {
return {
isHovering: false,
showCategories: false
}
},
methods: {
hideCategories () {
this.showCategories = false
const body = document.querySelector('body')
body.style.overflow = 'visible'
},
toggleCategories () {
this.showCategories = !this.showCategories
const body = document.querySelector('body')
if (this.showCategories) {
body.style.overflow = 'hidden'
} else {
body.style.overflow = 'visible'
}
},
showFirstRecommend () {
const listItems = document.querySelectorAll('.catalog-modal-list-item')
let isHovering = false
for (const item of listItems) {
isHovering = item.classList.contains('hovering')
if (item.classList.contains('hovering')) {
isHovering = true
break
}
}
if (!isHovering) {
document.querySelector('.catalog-modal-list-item').classList.add('hovering')
}
},
handleHoverCategories () {
const catalogItems = document.querySelectorAll('.catalog-modal-list-item')
for (const item of catalogItems) {
item.onmouseover = function () {
const listItems = document.querySelectorAll('.catalog-modal-list-item')
for (const item of listItems) {
item.classList.remove('hovering')
}
this.classList.add('hovering')
}
item.onmouseleave = function () {
let hovered = document.querySelectorAll('.hovering')
let clearHover = true
hovered = document.querySelectorAll('.hovering')
if (hovered.length === 0) {
clearHover = false
}
if (!clearHover) {
this.classList.remove('hovering')
}
}
}
}
}
CSS在这里:
.header-content-catalog {
position: relative;
button {
padding: 10px 20px;
}
&-modal {
position: absolute;
overflow: hidden;
max-height: 0;
top: 50px;
left: 0;
background-color: #e8e8e8;
color: black;
padding: 0;
border-radius: 10px;
box-shadow: 4px 4px 8px 0px rgba(34, 60, 80, 0.2);
transition: 0.2s all ease-in-out;
z-index: 100;
-webkit-overflow-scrolling: touch;
touch-action: none;
-ms-touch-action: none;
.catalog-modal-dismiss {
margin: 5px 20px 15px 0;
cursor: pointer;
font-weight: 800;
display: none;
justify-content: flex-end;
}
ul {
list-style-type: none;
padding-left: 0;
margin-bottom: 0;
position: relative;
min-width: 570px;
min-height: 450px;
li {
font-size: 14px;
font-weight: 700;
text-transform: uppercase;
display: flex;
& > a {
display: block;
padding: 10px 30px;
}
&.hovering {
color: #7845d1;
background-color: #fff;
& .catalog-modal-list-item_recommended {
display: block;
}
}
& .catalog-modal-list-item_recommended {
display: none;
position: absolute;
top: 0;
right: 0;
padding: 15px 40px;
height: 100%;
border-radius: 15px;
background-color: #fff;
color: #212121;
font-weight: 500;
h5 {
color: #212121;
text-transform: none;
}
& img {
width: 100%;
height: 100%;
object-fit: cover;
}
.card {
&-img-wrap {
height: 220px;
overflow: hidden;
img {
height: 100%;
width: 100%;
object-fit: cover;
}
}
}
}
}
}
&.show-categories {
max-height: 500px;
padding: 10px 0;
}
}
}
/* show modal(popup) on mobile */
@media (max-width: 767px) {
.header-content-catalog {
&-modal {
position: fixed;
top: 0;
width: 100%;
height: 100vh;
left: 0;
overflow: scroll;
&.show-categories {
max-height: 100vh;
}
.catalog-modal-dismiss {
display: flex;
}
}
}
}
@media (max-width: 575px) {
.header-content-catalog-modal {
ul {
min-width: auto!important;
min-height: auto!important;
}
/* hide recommended block */
.catalog-modal-list-item_recommended {
display: none!important;
}
}
}
@media (max-width: 575px) {
.header-content-catalog-modal {
ul {
min-width: auto!important;
min-height: auto!important;
}
/* hide recommended block */
.catalog-modal-list-item_recommended {
display: none!important;
}
}
}
参见工作站点:https://mebelvsem-dnr.ru/
没有什么特别的想法,在代码中可以看到,已经尝试过使用如下属性:
-webkit-overflow-scrolling: touch;
touch-action: none;
-ms-touch-action: none;
但这并没有帮助
问题是当您单击(触摸)元素事件
touch(start|end|move)
时触发,但您没有对此事件执行任何操作,尝试调用stopPropagation()
应该可以解决问题
<v-list-item
class="search-item v-list-item--link"
@touchstart="onTouch($event)"
@touchend="onTouch($event)"
@touchmove="onTouch($event)"
>
<v-list-item-avatar v-if="!!data.item.image">
<v-img :src="data.item.image"></v-img>
</v-list-item-avatar>
<v-list-item-content class="search-item-content">
<v-list-item-title v-html="data.item.title" />
<v-list-item-subtitle
v-if="!!data.item.barcode"
v-html="data.item.barcode"
/>
</v-list-item-content>
</v-list-item>
和功能
methods: {
onTouch(event) {
event.stopPropagation();
},
}