bug记录:h5中,点击A元素上方的位置,获取到的event.target却是A元素

241 阅读2分钟

h5中,点击A元素上方的位置,获取到的event.target却是A元素,期望的应该是A外面的元素

场景

image.png 点击上方红色框区域时,期望获取的event.target是jiangthis is a word...元素,但是实际上却是下方黑色弹框元素.quci-container(图中的body是个变量,实际上就是window)

在pc模式下不会有这问题,而h5会有

解决方案1

将黑色弹窗的z-index设为-1

解决方案2

利用document.elementFromPoint,根据event的坐标获取真实的点击元素。由于我监听的是touch事件,因此图中是touches[0].clientX

解决后

具体产生原因尚不清楚,但尝试过将htmlcss都copy放到新的html文件中,再去添加监听事件,并没有出现这种情况,因此,可以判定的是代码某些地方导致了这个问题

通过chatGpt分析,说是可能用了event.stopPropagationpreventDefault或css的pointer-event,但检查后发现并没有。后续再排查了....


后续原因排查

页面中的代码是,在window监听了touch事件,然后通过touch事件获取event.target。另外对于黑框元素加了click事件的监听,就出现这个问题,哪怕click事件中什么都没做(一开始以为和stopPropagation有关,但实际并没有)。

image.png

分析大致原因,是事件冒泡时被黑框元素截了,因此event.target是它(但明明没点击到,比较玄学了)

因此,最后的解决方案,将这个黑框元素的click监听处理了

可重现的代码:

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0,user-scalable=0,maximun-scale=1.0"
    />
    <title>取词测试</title>
    <style id="catchword-style">
      .hl {
        text-align: center;
        background-color: #202124;
        color: #fff;
        padding: 0 2px;
        border-radius: 4px;
        position: absolute;
      }
    </style>
    <style>
      .quci-container {
        position: fixed;
        left: 50%;
        margin-left: -172.5px;
        width: 345px;
        padding: 19px 24px 21px 24px;
        box-sizing: border-box;
        background: #202124;
        z-index: 11;
        border-radius: 6px;
        font-size: 16px;
      }

      h3.source {
        font-family: AvertaStd-Semibold;
        font-size: 24px;
        color: #e1e3e6;
        line-height: 24px;
      }

      .quci-collect {
        position: absolute;
        top: 24px;
        right: 23px;
        width: 22px;
        height: 22px;
        background-position: 50% 50%;
        background-size: contain;
        background-repeat: no-repeat;
      }

      .collected {
        background-image: url("https://ydlunacommon-cdn.nosdn.127.net/6408487e48e102ed0c0fd2d6f1a8a9e5.png");
      }

      .uncollected {
        background-image: url("https://ydlunacommon-cdn.nosdn.127.net/3fa57a5c6eef4a6de38c53503edaf4de.png");
      }

      .speechBar {
        display: block;
        margin: 5px 0;
      }
      .speech-item {
        display: inline-block;
        vertical-align: middle;
        margin-right: 24px;
        line-height: 30px;
        cursor: pointer;
      }
      .speech-icon {
        display: inline-block;
        width: 22px;
        height: 22px;
        background-image: url("https://ydlunacommon-cdn.nosdn.127.net/beddd615af7d72fa26d8e94f82f00aad.png");
        background-position: 50% 50%;
        background-size: contain;
        background-repeat: no-repeat;
        vertical-align: middle;
        margin-right: 6px;
      }
      span.speech-phonetic {
        font-family: HYQiHei-EES;
        font-size: 14px;
        color: #969799;
        line-height: 15px;
        vertical-align: middle;
      }

      .speech-item:hover,
      .speech-item:link {
        opacity: 0.7;
      }

      .trans-list {
        display: block;
      }
      ul,
      li {
        list-style: none;
      }
      ul li {
        display: block;
        font-family: HYQiHei-EES;
        font-size: 14px;
        color: #e1e3e6;
        line-height: 25px;
      }

      .triangle {
        position: fixed;
      }

      .triangle-up {
        width: 0;
        height: 0;
        border-left: 7.5px solid transparent;
        border-right: 7.5px solid transparent;
        border-bottom: 12.5px solid #202124;
        z-index: 11;
      }

      .triangle-down {
        width: 0;
        height: 0;
        border-left: 7.5px solid transparent;
        border-right: 7.5px solid transparent;
        border-top: 12.5px solid #202124;
        z-index: 11;
      }

      .light .quci-container {
        box-shadow: 0px 4px 26px rgba(52, 88, 146, 0.14);
      }

      .dark .quci-container {
        box-shadow: none;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <div>pc模式下,双击单词</div>
      <div>h5模式下,单击</div>
      <div>this is a word translate test</div>
      do a test
    </div>

    <div
      class="hl"
      style="
        display: block;
        width: 66.2px;
        height: 21.8px;
        left: 113.787px;
        font-family: 'Microsoft YaHei';
        top: 49.6px;
        font-size: 16px;
      "
    >
      translate
    </div>
    <div class="quci-container below" style="top: 77.5px">
      <h3 class="source">translate</h3>
      <div class="speechBar">
        <div class="speech-item" data-speech="translate&amp;type=1">
          <i class="speech-icon"></i>
          <span class="speech-phonetic color_text_2">英/trænzˈleɪt/</span>
        </div>
        <div class="speech-item" data-speech="translate&amp;type=2">
          <i class="speech-icon"></i>
          <span class="speech-phonetic color_text_2">美/trænzˈleɪt/</span>
        </div>
      </div>
      <div class="trans-list">
        <ul>
          <li>
            v.
            译,翻译;(使)转变,(使)变化;意同,相当于,(把……)解释为;(以易于理解的方式)解释,说明;导致,造成;改编,改写;转换(计算机程序或语言所含的信息);(生)转译(信使RNA中的一组核苷酸);转移,调动,转变;&lt;正式&gt;调换(主教,苏格兰牧师)的教区;&lt;正式&gt;移葬(圣徒遗骸);&lt;&gt;送(人,尤指活人)进天堂;(物理)平移(主干部分);(数)平移(几何图形)
          </li>
        </ul>
      </div>
    </div>
    <div class="triangle triangle-up" style="left: 140.5px; top: 71px"></div>
    <script>
      window.addEventListener(
        "touchend",
        function (e) {
          console.log(event.target);
        },
        false
      );
      document
        .querySelector(".quci-container")
        .addEventListener("click", () => {});
    </script>
  </body>
</html>