移動web app開發必備 - zepto事件問題


問題描述:

項目在祖先元素上綁定了 touchstart,touchmove,touchend事件,用來處理全局性的事件,比如滑動翻頁

正常狀態下:

  • 用戶在子元素上有交互動作時,默認狀態下都是會冒泡到祖先元素響應

特定情況下:

  • 子元素單獨綁定了事件
  • 特性情況下需要阻止全局事件

常規的做法就是stopPropagation阻止即可

但如果子元素綁定的是 click,touchmove,touchend這類事件的話,問題就來了

全局的touchstart事件也會被冒泡觸發

發一段項目圖:

/**
 * ppt事件接口
 *
 * 允許用戶自定義其行為
 *     1 支持14種操作行為
 *     2 默認對象都具有滑動翻頁的特性
 *     3 翻頁的特性在遇到特性的情況可以被覆蓋
 *     比如
 *         行為1:用戶定義該名字可以支持  click 點擊行為, 那么該元素左右滑動能過翻頁
 *         行為2:用戶如果定義swipeLeft 行為,該元素左右滑動將不會翻頁,因為默認翻頁已經被覆蓋
 * 
 * 此接口函數有作用域隔離
 */
Xut.define('Xut.PPTevent', {
 
    //數據庫預定義14個事件接口
    defauleEventType: ['null', 'auto', 'tap', 'drag', 'dragTag',
            'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap',
            'longTap', 'mTouchMagnify', 'mTouchNarrow', 'mTouchRotate'
    ],
 
   //綁定事件
    bind: function(element, evtName, fn) {
        element.on(Xut.START_EV, function(e) { //阻止 mousedown事件冒泡
            e.stopPropagation();
        });
        element.on(evtName, fn); //綁定真正事件
    },
on綁定的事件替換成硬編碼容易理解
   bind: function(element, evtName, fn) {
        element.on('mousedown', function(e) { //阻止 mousedown事件冒泡
            e.stopPropagation();
        });
        element.on('swipeLeft', fn); //綁定真正事件
    },

給元素綁定'swipeLeft'滑動事件,同時阻止'mousedown'冒泡到祖先元素,此時理論上就可行了

這樣處理之后zepto移動事件確失效了

Zepto事件綁定

    $(document.body)
      .bind('touchstart', function(e){
        now = Date.now()
        delta = now - (touch.last || now)
        touch.el = $(parentIfText(e.touches[0].target))
        touchTimeout && clearTimeout(touchTimeout)
        touch.x1 = e.touches[0].pageX
        touch.y1 = e.touches[0].pageY
        if (delta > 0 && delta <= 250) touch.isDoubleTap = true
        touch.last = now
        longTapTimeout = setTimeout(longTap, longTapDelay)
      })
      .bind('touchmove', function(e){
        cancelLongTap()
        touch.x2 = e.touches[0].pageX
        touch.y2 = e.touches[0].pageY
        if (Math.abs(touch.x1 - touch.x2) > 10)
          e.preventDefault()
      })
      .bind('touchend', function(e){
         cancelLongTap()

zepto移動事件失效的根源找到了,不能阻止事件冒泡了,不能攔截了

偏偏Zepto不讓你這么安逸,學jquery的live()方法一樣,把事件給綁到body元素上了, jquery1.7后就去掉了,zepto你也要跟上呀

處理的辦法:

子元素上增加一個hack標記, 控制器冒泡過濾排除

        onTouchStart: function (e) {

            var point = Xut.hasTouch ? e.touches[0] : e;

            if (!point) return;

            this.bindDefaultEventId = null;

            var children = point.target.offsetParent.children[0];

            //處理默認特性
           if (children.getAttribute('bindDefaultEvent')) {
                this.bindDefaultEventId = children.id;
            } else {
                var className = point.target.className;

                if (className && className === 'triggerAction') {
                    //Actoin熱點,通過冒泡捕獲到
                } else {
                    if (className !== 'widgetwapper') {
                        this.start = void 0;
                        return;
                    }
                }
            }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM