vuejs / vue

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
http://v2.vuejs.org
MIT License
208.08k stars 33.69k forks source link

Event bubbling does not trigger on older iOS devices #10964

Open chenjiahan opened 4 years ago

chenjiahan commented 4 years ago

Version

2.6.11

Reproduction link

https://github.com/chenjiahan/vue-event-bubble-issue

Steps to reproduce

This is a browser quirk on iOS <= 11.3

  1. Find an old iOS device. (I reproduced the issue on an iOS 8.4 device)
  2. Binding click events on parent and child elements
  3. Click child element
  4. Event listener for parent element is not firing

What is expected?

Correct event bubbling behavior

What is actually happening?

Mobile safari has buggy event.timeStamp implementations, the value of event.timestamp is abnormal when the page is first loaded. But event.timestamp will return to normal value after refreshing the page.

We receive a lot of feedback from vant users, it is currently observed that the problem may occur on iOS 8.4、10.2、10.3、11.3 (mobile safari and wechat browser)

Screenshot:


posva commented 4 years ago

Tested on iOS 8, iPhone 6 Plus and it works fine:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>

    <style>
      #app {
        font-family: 'Avenir', Helvetica, Arial, sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-align: center;
        color: #2c3e50;
        margin-top: 60px;
      }

      .father {
        width: 300px;
        height: 300px;
        background-color: red;
      }

      .child {
        width: 100px;
        height: 100px;
        background-color: blue;
      }
    </style>
  </head>

  <script src="https://unpkg.com/vue"></script>

  <body>
    <div id="app">
      <div class="father" @click="onClickFather">
        Father
        <div class="child" @click="onClickChild">Child</div>
      </div>

      <ul>
        <li v-for="event in events">{{ event }}</li>
      </ul>
    </div>

    <script>
      new Vue({
        el: '#app',
        data: { events: [] },
        methods: {
          onClickFather: function() {
            this.events.push('father')
            console.log('father clicked')
          },
          onClickChild: function() {
            this.events.push('child')
            console.log('child clicked')
          },
        },
      })
    </script>
  </body>
</html>

Next time, please provide a runnable repro for the target device, code sandbox doesn't run on iOS 8

chenjiahan commented 4 years ago

@posva Sorry about the codesandbox link, this is the a repository that reproduced the problem:

https://github.com/chenjiahan/vue-event-bubble-issue

The timeStamp is only incorrect in some cases. I am now looking for a way to reproduce the problem steadily, and found some possible related links:

chenjiahan commented 4 years ago

event.timeStamp is unreliable, maybe we should use some alternatives.

posva commented 4 years ago

Thanks for the extra links! Let's keep this open in case someone manage to reproduce it more consistently or even do a PR to fix it

rx-837 commented 4 years ago

@posva event.timestamp on safari devices in some cases is more then 0 but less then attachedTimestamp.

It seems, that current issue is similar to issue.

To resolve safari timestamp behavior, rule e.target === e.currentTarget is used.

But the rule, doesn't work when event started from child element.

I make PR, but still no response.