You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by da...@apache.org on 2017/08/21 06:17:43 UTC

[5/7] incubator-weex git commit: * [html5] add click bubbles bug showcase and fixed it.

* [html5] add <a>  click bubbles bug showcase and fixed it.


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/87831dc2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/87831dc2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/87831dc2

Branch: refs/heads/0.16-dev
Commit: 87831dc2ab954323e0237db4ebbb2c8f0f8a462e
Parents: 8a4ea14
Author: erha19 <fa...@gmail.com>
Authored: Fri Aug 18 18:10:42 2017 +0800
Committer: erha19 <fa...@gmail.com>
Committed: Fri Aug 18 18:10:42 2017 +0800

----------------------------------------------------------------------
 examples/vue/index.vue                 |  2 +
 examples/vue/showcase/a-node-click.vue | 74 +++++++++++++++++++++++++++++
 html5/render/vue/core/node.js          | 36 ++++++++++++--
 3 files changed, 109 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/87831dc2/examples/vue/index.vue
----------------------------------------------------------------------
diff --git a/examples/vue/index.vue b/examples/vue/index.vue
index 9711e2b..31027d2 100644
--- a/examples/vue/index.vue
+++ b/examples/vue/index.vue
@@ -46,6 +46,8 @@
           {name: root + '/showcase/itemlist', title: 'List (Advanced)'},
           {name: root + '/showcase/calculator', title: 'Calculator'},
           {name: root + '/showcase/tap-penetrate', title: 'TapPenetrate'},
+          {name: root + '/showcase/a-node-click', title: 'ANodeClick'},
+          {name: root + '/showcase/minesweeper', title: 'Minesweeper'},
           // {name: root + '/showcase/minesweeper', title: 'Minesweeper'},
           // {name: root + '/showcase/ui', title: 'UI Gallery'},
           // {name: root + '/showcase/dropdown/dropdown-demo', title: 'Dropdown'}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/87831dc2/examples/vue/showcase/a-node-click.vue
----------------------------------------------------------------------
diff --git a/examples/vue/showcase/a-node-click.vue b/examples/vue/showcase/a-node-click.vue
new file mode 100644
index 0000000..bf4d5a4
--- /dev/null
+++ b/examples/vue/showcase/a-node-click.vue
@@ -0,0 +1,74 @@
+<template>
+  <list class="list">
+    <cell class="cell" @click="clickCell">
+      <xlink style="width: 400px;height: 400px;background-color: yellow;" :href = "url">
+        <div class="ct" @click="click">
+          <text >CLICK ME</text>
+        </div>
+      </xlink>
+    </cell>
+  </list>
+</template>
+
+<style scoped>
+.list {
+  height: 2000px;
+}
+.cell {
+  height: 400px;
+  background-color: blue;
+}
+.txt {
+  font-size: 64px;
+  height: 84px;
+  line-height: 84px;
+  padding: 10px;
+}
+.ct {
+  width: 200px;
+  height: 200px;
+  background-color: #fff;
+}
+</style>
+
+<script>
+export default {
+  data () {
+    return {
+      // url: '//m.taobao.com'
+      url: '#'
+    }
+  },
+  components: {
+    xlink: {
+      props: {
+        href: String
+      },
+      render (createElement) {
+        return createElement('a', {
+          ref: 'link',
+          attrs: {
+            'component-name': 'link',
+            'href': this.href
+          }
+        }, this.$slots.default)
+      }
+    }
+  },
+  methods: {
+    click (evt) {
+      evt.preventDefault()
+      // var d = Date.now()
+      // while (true) {
+      //   var now = Date.now()
+      //   if (now - d > 2000) { break }
+      // }
+      // throw new Error('test')
+      console.log('click on inner')
+    },
+    clickCell (evt) {
+      console.log('click on cell')
+    }
+  }
+}
+</script>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/87831dc2/html5/render/vue/core/node.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/core/node.js b/html5/render/vue/core/node.js
index 23603aa..d515ea5 100644
--- a/html5/render/vue/core/node.js
+++ b/html5/render/vue/core/node.js
@@ -35,6 +35,20 @@ export function trimTextVNodes (vnodes) {
 }
 
 /**
+ * is a element in a '<a>' tag?
+ * @param {HTMLElement} el
+ */
+function isInANode (el) {
+  let parent = el.parentNode
+  while (parent && parent !== document.body) {
+    if (parent.tagName.toLowerCase() === 'a') {
+      return true
+    }
+    parent = parent.parentNode
+  }
+}
+
+/**
  * get listeners from on config and v-on binding.
  * v-on binding has a priority over on config.
  * @param {vnode} vnode
@@ -102,8 +116,6 @@ export function createEventMap (context, ...extras) {
             const len = ons.length
             if (len > 0) {
               let idx = 0
-              // dispatch real target click event befor calling listeners
-              e.target.dispatchEvent(createBubblesEvent(e.target, 'click', { _triggered: { el: e.target }}))
               while (idx < len) {
                 let on = ons[idx]
                 if (on && on.fn) {
@@ -111,7 +123,14 @@ export function createEventMap (context, ...extras) {
                 }
                 let evt = e
                 if (originalType && evtName !== listenTo) {
-                  evt = createEvent(e.target, listenTo)
+                  if (listenTo === 'click') {
+                    // dispatch real target click event befor calling listeners
+                    evt = createBubblesEvent(e.target, 'click', { _triggered: { el: e.target }})
+                    e.target.dispatchEvent(evt)
+                  }
+                  else {
+                    evt = createEvent(e.target, listenTo)
+                  }
                 }
                 on && on.call(vm, evt)
                 idx++
@@ -184,6 +203,7 @@ export function createEventMap (context, ...extras) {
    * This means the click event should always be swallowed in silence.
    */
   bindFunc('click')(function (e) {
+    let vm = context
     if (e._triggered) {
       return
     }
@@ -195,6 +215,16 @@ export function createEventMap (context, ...extras) {
       // prevent click events from bubbling,because event bubbling has been handled in the tap event
       e.stopPropagation()
     }
+    // if an element(not <a>) handler click event in <a> element,call stopPropagation and preventDefault on event
+    while (vm) {
+      const ons = getListeners(vm.$vnode, 'click')
+      const len = ons.length
+      if (len > 0 && vm.$el) {
+        e._triggered = { el: vm.$el }
+        return isInANode(vm.$el) && e.preventDefault()
+      }
+      vm = vm.$parent
+    }
   })
   return eventMap
 }