溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Vue在chrome44偶現(xiàn)點(diǎn)擊子元素事件無(wú)法冒泡怎么解決

發(fā)布時(shí)間:2022-05-05 17:41:42 來(lái)源:億速云 閱讀:190 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要介紹“Vue在chrome44偶現(xiàn)點(diǎn)擊子元素事件無(wú)法冒泡怎么解決”的相關(guān)知識(shí),小編通過(guò)實(shí)際案例向大家展示操作過(guò)程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“Vue在chrome44偶現(xiàn)點(diǎn)擊子元素事件無(wú)法冒泡怎么解決”文章能幫助大家解決問(wèn)題。

前言

公司的一個(gè)項(xiàng)目大致是這樣的:一個(gè)左側(cè)列表,點(diǎn)擊左側(cè)列表的文章標(biāo)題,右側(cè)展開(kāi)該文章對(duì)應(yīng)的內(nèi)容的。
現(xiàn)在的問(wèn)題出現(xiàn)在極少部分客戶有時(shí)左側(cè)的標(biāo)題,無(wú)法打開(kāi)對(duì)應(yīng)的右側(cè)的內(nèi)容,給人的改進(jìn)就是‘卡'、點(diǎn)不動(dòng)、點(diǎn)了沒(méi)反應(yīng)。

再大致介紹下項(xiàng)目環(huán)境:

chrome 44(打包到用戶客戶端內(nèi))
Vue 2.6.10

左側(cè)列表布局

Vue在chrome44偶現(xiàn)點(diǎn)擊子元素事件無(wú)法冒泡怎么解決

列表的每個(gè)綠色方框是一個(gè)vue組件,名叫ListItem,列表的組件叫List

代碼類似這樣

// List.vue
<template>
 <div class="blue">
  <list-item v-for="item in dataList" :data="item" @click="handleClick">
 </div>
</template>
<script>
 export default {
  ...
  methods: {
   handleClick() {
    ... 請(qǐng)求文章內(nèi)容相應(yīng)的邏輯
   }
  }
 }
</script>
// ListItem.vue
<template>
 <div class="green" @click="onClick">
  <div class="red circle"></div>
  <div class="red square">
   <div class="yellow square1"></div>
   <div class="yellow square2"></div>
  </div>
 </div>
</template>
<script>
 export default {
  ...
  methods: {
   onClick(e) {
    console.log('點(diǎn)擊', e.target);
    this.$emit('click');
   }
  }
 }
</script>

首先大家不要評(píng)論這個(gè)click是不是多此一舉,為什么不直接在Lisit.vue里面寫(xiě)@click.native="handleClick" 。原項(xiàng)目就是這樣寫(xiě)的,其中的部分邏輯我簡(jiǎn)化了,最重要的是這個(gè)不是我們討論的重點(diǎn)。

根據(jù)上面的代碼我們只要在綠色的方框內(nèi)點(diǎn)擊,均可以實(shí)現(xiàn)請(qǐng)求文章內(nèi)容。實(shí)測(cè)也是沒(méi)有問(wèn)題的,但是上線以來(lái),有部分用戶報(bào)障“文章列表點(diǎn)不動(dòng)(其實(shí)就是onClick -> handleClick沒(méi)有調(diào)用”,作為開(kāi)始說(shuō)實(shí)話一開(kāi)始是不信,這么簡(jiǎn)單的邏輯,這時(shí)vue的常規(guī)操作好嗎,怎么可能有問(wèn)題。

但是經(jīng)過(guò)遠(yuǎn)程和實(shí)地確認(rèn),確實(shí)是有這樣的問(wèn)題。

經(jīng)過(guò)調(diào)查發(fā)現(xiàn),當(dāng)點(diǎn)擊上圖紅色圓圈下方時(shí),是可以觸發(fā)onClick的。其實(shí)此時(shí)是剛好直接點(diǎn)到綠方框這個(gè)元素了,也就是說(shuō)我們直接點(diǎn)到綁定了點(diǎn)擊事件的div上時(shí)是可以觸發(fā)onClick。我們的第一反應(yīng)是這<div class="green">的子元素是否使用了阻止冒泡,可惜沒(méi)有,如果有,開(kāi)發(fā)自測(cè)和測(cè)試人員測(cè)試早就會(huì)發(fā)現(xiàn),該問(wèn)題不可能到線上才被發(fā)現(xiàn)。

我們有懷疑是除了click以外其他事件的影響,比如mousedown、mouseup被阻止冒泡,是否存在使用事件捕獲并且還阻止冒泡的情況,經(jīng)過(guò)排除后,發(fā)現(xiàn)是有一部分的,按照寧愿錯(cuò)殺不能漏殺的原則,我們針對(duì)這些事件都進(jìn)行調(diào)整,但是是否真的解決了這個(gè)問(wèn)題,我們不知道,因?yàn)檫@個(gè)問(wèn)題我們開(kāi)發(fā)人員本地、測(cè)試人員在測(cè)試環(huán)境和生產(chǎn)環(huán)境均無(wú)法復(fù)現(xiàn)。每次只能在發(fā)版的時(shí)候帶上去一點(diǎn)點(diǎn)改動(dòng),改動(dòng)的前提是不保證能改好,但是一定不會(huì)改壞,面對(duì)客戶的報(bào)障我們只能叫他們用臨時(shí)的解決方案,也是點(diǎn)擊紅色圓圈下面那塊區(qū)域。

有一次我們?cè)黾恿嗽诩t色圓圈和紅色方框上綁定同一個(gè)事件,也就是

<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script>
  (adsbygoogle = window.adsbygoogle || []).push({
   google_ad_client: "ca-pub-3013839362871866",
   enable_page_level_ads: true
  });
</script>
// ListItem.vue
<template>
 <div class="green" @click="onClick">
  <div class="red circle" @click="onClick"></div>
  <div class="red square" @click="onClick">
   <div class="yellow square1"></div>
   <div class="yellow square2"></div>
  </div>
 </div>
</template>

是的,我們就差在<div class="yellow square1"><div class="yellow square2">也綁上點(diǎn)擊事件了。我們太難了。。。

這樣上線后依然有問(wèn)題,大家應(yīng)該料到了,如果那些用戶點(diǎn)到了
<div class="yellow square1"><div class="yellow square2">上依然是無(wú)法觸發(fā)onClick的,作為一個(gè)程序員,我們絕不容忍在每個(gè)div上綁定同樣的事件啊,我們放棄了這樣的改動(dòng),做個(gè)有尊嚴(yán)的程序員,不是嗎?

在用戶發(fā)生“點(diǎn)不動(dòng)”的時(shí)候,我們實(shí)體去看的時(shí)候發(fā)現(xiàn):

1.我們?cè)谡{(diào)試工具里面將所有的dom上綁定的事件都移除,只保留自己綁定的<div class="green" @click="onClick">這一個(gè)事件,用戶依然“點(diǎn)不動(dòng)”,依然只有點(diǎn)擊紅圈才能觸發(fā)onClick。
2.我們?cè)诳刂婆_(tái)使用document.querySelect('.yellow .square1').click()的方式是可以觸發(fā)onClick的,也就是該點(diǎn)擊事件其實(shí)是可以冒泡到<div class="green">的。

為什么我們用鼠標(biāo)點(diǎn)擊就不行了,并且通過(guò)在控制打印出我們點(diǎn)擊的元素,我們可以100%確定我們用鼠標(biāo)點(diǎn)擊的就是document.querySelect('.yellow .square1')所對(duì)應(yīng)的這個(gè)元素。

這個(gè)發(fā)現(xiàn)完全顛覆了我們的認(rèn)知。到底是哪里錯(cuò)了,要么是Vue,要么是瀏覽器,都是大佬啊,它們錯(cuò)了?其他人都在用,都沒(méi)毛病啊,并且這個(gè)問(wèn)題無(wú)法復(fù)現(xiàn),沒(méi)有必現(xiàn)流程,使用按鍵精靈模擬用戶操作了一天也沒(méi)有復(fù)現(xiàn)。怎么跟其他人,大家只會(huì)覺(jué)得你連這么簡(jiǎn)單的問(wèn)題都搞不定?代碼也給很多前端同事、前端大佬review過(guò)了,沒(méi)毛病啊。但是生產(chǎn)上就是有人使用時(shí)會(huì)出現(xiàn)“點(diǎn)不動(dòng)”,這是事實(shí)啊。

瀏覽器是前端的根基,我們我只能開(kāi)始大膽懷疑下是Vue的問(wèn)題,或者我們的用法有問(wèn)題(怎么用沒(méi)有問(wèn)題),或者說(shuō)這個(gè)版本的Vue在這個(gè)版本的Chrome44在部分場(chǎng)景中有問(wèn)題。

搜了vue event propagation相關(guān)的內(nèi)容,有一點(diǎn)小小的發(fā)現(xiàn),之前確實(shí)有人反映過(guò)Vue 2.4.2在子元素事件冒泡相關(guān)的issue,并且vue的源碼里面也有相關(guān)的注釋。

Vue在chrome44偶現(xiàn)點(diǎn)擊子元素事件無(wú)法冒泡怎么解決

雖然上面提到的 #6566 issue并非跟我們的問(wèn)題一模一樣,但是既然有個(gè)提過(guò)這類bug,我們更有里有相信可能是Vue的問(wèn)題(或者說(shuō)我們用的不對(duì))了

最后我們決定放棄這個(gè)用Vue寫(xiě)的點(diǎn)擊事件的寫(xiě)法,改用jQuery了。
在上面列表的<div class="blue"></div>上綁定事件,然后根據(jù)對(duì)應(yīng)的文章id來(lái)實(shí)現(xiàn)打開(kāi)對(duì)應(yīng)文章的目的,這一部分沒(méi)什么技術(shù)含量,就不細(xì)說(shuō)了。

是的,最終我們放棄了尋找這個(gè)問(wèn)題的原因了,面對(duì)用戶的頻繁報(bào)障,再加上我們無(wú)法復(fù)現(xiàn)問(wèn)題,根本不知道改好了沒(méi)有,我們也不可能頻繁發(fā)版在生產(chǎn)上讓用戶幫我們測(cè)試(測(cè)試人員第一個(gè)不答應(yīng))。

這個(gè)到底解決好了沒(méi)有,從理論上應(yīng)該是沒(méi)問(wèn)題了,但是我們說(shuō)了不算,就看客戶還有沒(méi)有這樣的報(bào)障了,畢竟得靠他們來(lái)驗(yàn)證。

一個(gè)靈異問(wèn)題從入門(mén)到放棄,我們終于把Vue徹底用成了我們討厭的樣子。

關(guān)于“Vue在chrome44偶現(xiàn)點(diǎn)擊子元素事件無(wú)法冒泡怎么解決”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI