Repository: incubator-weex
Updated Branches:
  refs/heads/0.16-dev 495fc6b24 -> b11c4e113


* [html5] bind click listener to event tap.


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

Branch: refs/heads/0.16-dev
Commit: a35c690c1f4e3d43ed93151215bdbe9457942d91
Parents: d20e0d8
Author: MrRaindrop <tekk...@gmail.com>
Authored: Thu Jun 29 17:37:02 2017 +0800
Committer: MrRaindrop <tekk...@gmail.com>
Committed: Thu Jun 29 17:37:02 2017 +0800

----------------------------------------------------------------------
 html5/render/vue/core/node.js | 122 +++++++++++++++++++++++++------------
 1 file changed, 84 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a35c690c/html5/render/vue/core/node.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/core/node.js b/html5/render/vue/core/node.js
index 87981d8..196d061 100644
--- a/html5/render/vue/core/node.js
+++ b/html5/render/vue/core/node.js
@@ -54,10 +54,25 @@ function getListeners (vnode, evt) {
 }
 
 const supportedEvents = [
-  'tap', 'click', 'longpress', 'appear', 'disappear',
+  'longpress', 'appear', 'disappear',
   // 'touchstart', 'touchmove', 'touchend',
   'panstart', 'panmove', 'panend', 'swipe', 'longpress'
 ]
+
+/**
+ * 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
+  }
+}
+
 /**
  * emit native events to enable v-on.
  * @param {VComponent} context: which one to emit a event on.
@@ -66,52 +81,83 @@ const supportedEvents = [
 export function createEventMap (context, extras = []) {
   const eventMap = {}
   /**
-   * bind name with evt event. e.g. bind 'click' with 'tap' event.
+   * Bind some original type event to your specified type event handler.
+   * e.g. bind 'tap' event to 'click' event listener: bindFunc('tap')('click').
+   * Or bind certian event with your specified handler: bindFunc('click', 
someFunction)
    */
-  const bindFunc = (evt) => {
-    return name => {
-      const evtType = evt || name
-      eventMap[evtType] = function (e) {
-        /**
-         * allow original bubbling.
-         * use '_triggered' to control actural bubbling.
-         */
-        if (e._triggered) {
-          return
-        }
-        // but should trigger the closest parent which has bound the
-        // event handler.
-        let vm = context
-        while (vm) {
-          const ons = getListeners(vm.$vnode, name)
-          const len = ons.length
-          let idx = 0
-          while (idx < len) {
-            let on = ons[idx]
-            if (on && on.fn) {
-              on = on.fn
-            }
-            on && on.call(vm,
-              evtType === name ? e : extend({}, e, { type: name })
-            )
-            idx++
+  const bindFunc = (originalType) => {
+    return listenTo => {
+      let handler
+      if (typeof listenTo === 'function') {
+        handler = listenTo
+      }
+      else if (typeof listenTo === 'string') {
+        if (!originalType) { originalType = listenTo }
+        handler = function (e) {
+          /**
+           * allow original bubbling.
+           * use '_triggered' to control actural bubbling.
+           */
+          if (e._triggered) {
+            return
           }
-
-          // once a parent node (or self node) has triggered the handler,
-          // then it stops bubble immediately, and a '_triggered' object is 
set.
-          if (len > 0) {
-            e._triggered = {
-              el: vm.$el
+          // but should trigger the closest parent which has bound the
+          // event handler.
+          let vm = context
+          while (vm) {
+            const ons = getListeners(vm.$vnode, listenTo)
+            const len = ons.length
+            if (len > 0) {
+              let idx = 0
+              while (idx < len) {
+                let on = ons[idx]
+                if (on && on.fn) {
+                  on = on.fn
+                }
+                on && on.call(vm,
+                  originalType === listenTo ? e : extend({}, e, { type: 
listenTo })
+                )
+                idx++
+              }
+              // once a parent node (or self node) has triggered the handler, 
then
+              // it stops bubbling immediately, and a '_triggered' object is 
set.
+              e._triggered = {
+                el: vm.$el
+              }
+              return
             }
-            return
+            vm = vm.$parent
           }
-          vm = vm.$parent
         }
       }
+      eventMap[originalType] = handler
     }
   }
   supportedEvents.concat(extras).forEach(bindFunc())
-  // bindFunc('tap')('click')
+  bindFunc('tap')('click')
+  /**
+   * Special treatment for click event:
+   * we already use tap to trigger click event, so the click event should:
+   * 1. trigger none of any vm's click listeners.
+   * 2. prevent default behaviour for a `<a>` element.
+   * This means the click event should always be swallowed in silence.
+   */
+  bindFunc('click')(function (e) {
+    if (e._triggered) {
+      return
+    }
+    let vm = context
+    while (vm) {
+      const ons = getListeners(vm.$vnode, 'click')
+      const len = ons.length
+      if (len > 0 && vm.$el && isInANode(vm.$el)) {
+        e.preventDefault()
+        e._triggered = { el: vm.$el }
+        return
+      }
+      vm = vm.$parent
+    }
+  })
 
   return eventMap
 }

Reply via email to