# HandlerProxy 类

# 概述

HandlerProxy 是一个什么样的角色? 应该是个中间层,监听 viewport dom 的鼠标事件, 对事件进行规范化处理,然后再次出发给 Handler 类;避免在 handler 中需要做各种判断。

# 关系

# 继承

继承 Eventful

# 构造函数

dom 和 painterRoot 是什么关系?

如果是 canvas 渲染, 总共分三层, div#root > dir#viewport > [canvas]

在构造函数的参数中,刚好需要最外面的两个 div:

  • dom viewport 是 painter 实例化过程中创建的 dom
  • painterRoot rootDom 是实例化所使用的 dom

需要判断浏览器类型,然后需要分别提供 mouse touch pointer 事件的处理和监听

然后在 touch 和 pointer 事件触发后,事件参数处理后重新触发为 mouse 事件

# 方法

# dispose

释放,需要将事件解绑

dispose = function () {
    unmountDOMEventListeners(this._localHandlerScope);
    if (globalEventSupported) {
        unmountDOMEventListeners(this._globalHandlerScope);
    }
}

# setCursor

设置鼠标样式

setCursor = function (cursorStyle) {
    this.dom.style && (this.dom.style.cursor = cursorStyle || 'default');
};

# 通用方法

# mountLocalDOMEventListeners

为了方便整个流程,暂时过滤掉所有的 touch 和 pointer 事件,需要了解的话,可以查看 HandlerProxy 详解

然后将dom的事件全部绑定到下面的匿名函数上

  • 兼容性获取 event ,兼容部分低版本的 IE, 意义不大
  • scope.touching 是否还在 touch 中,在的话不应该触发事件吗?
  • 然后调用相应事件的触发函数
function mountLocalDOMEventListeners(instance, scope) {
    var domHandlers = scope.domHandlers;
    zrUtil.each(localNativeListenerNames.mouse, function (nativeEventName) {
        mountSingleDOMEventListener(scope, nativeEventName, function (event) {
            // dom 绑定的事件都会在这里被触发
            event = getNativeEvent(event);
            if (!scope.touching) {
                // markTriggeredFromLocal(event);
                domHandlers[nativeEventName].call(instance, event);
            }
        });
    });
}

# mountSingleDOMEventListener

# globalDOMHandlers

指针移动非常敏感,以至于总是在触摸屏上点击(单击)时触发,这会影响上层应用程序的某些判断。 因此,我们尚不支持MS touch设备上的mousemove。

var globalDOMHandlers = {

    pointermove: function (event) {
        if (!isPointerFromTouch(event)) {
            globalDOMHandlers.mousemove.call(this, event);
        }
    },

    pointerup: function (event) {
        globalDOMHandlers.mouseup.call(this, event);
    },

    mousemove: function (event) {
        this.trigger('mousemove', event);
    },

    mouseup: function (event) {
        var pointerCaptureReleasing = this._pointerCapturing;
        togglePointerCapture(this, false);
        this.trigger('mouseup', event);
        if (pointerCaptureReleasing) {
            event.zrEventControl = 'only_globalout';
            this.trigger('mouseout', event);
        }
    }

};

# localDOMHandlers

Dom 的事件监听回调方法, 将 touch 事件和 pointer 事件全部抽象成为 mouse 事件触发

IE11 和 Edge 不支持 touch 事件,但是支持 pointer 事件

var localDOMHandlers = {

    mousedown: function (event) {
        event = normalizeEvent(this.dom, event);

        this._mayPointerCapture = [event.zrX, event.zrY];

        this.trigger('mousedown', event);
    },

    mousemove: function (event) {
         debugger;
        event = normalizeEvent(this.dom, event);

        var downPoint = this._mayPointerCapture;
        if (downPoint && (event.zrX !== downPoint[0] || event.zrY !== downPoint[1])) {
            togglePointerCapture(this, true);
        }

        this.trigger('mousemove', event);
    },

    mouseup: function (event) {
        event = normalizeEvent(this.dom, event);

        togglePointerCapture(this, false);

        this.trigger('mouseup', event);
    },

    mouseout: function (event) {
        event = normalizeEvent(this.dom, event);

        if (this._pointerCapturing) {
            event.zrEventControl = 'no_globalout';
        }
        var element = event.toElement || event.relatedTarget;
        event.zrIsToLocalDOM = isLocalEl(this, element);

        this.trigger('mouseout', event);
    },

    touchstart: function (event) {
        event = normalizeEvent(this.dom, event);
        markTouch(event);
        this._lastTouchMoment = new Date();
        this.handler.processGesture(event, 'start');
        localDOMHandlers.mousemove.call(this, event);
        localDOMHandlers.mousedown.call(this, event);
    },

    touchmove: function (event) {
        event = normalizeEvent(this.dom, event);
        markTouch(event);
        this.handler.processGesture(event, 'change');
        localDOMHandlers.mousemove.call(this, event);
    },

    touchend: function (event) {
        event = normalizeEvent(this.dom, event);
        markTouch(event);
        this.handler.processGesture(event, 'end');
        localDOMHandlers.mouseup.call(this, event);
        if (+new Date() - this._lastTouchMoment < TOUCH_CLICK_DELAY) {
            localDOMHandlers.click.call(this, event);
        }
    },

    pointerdown: function (event) {
        localDOMHandlers.mousedown.call(this, event);
    },

    pointermove: function (event) {
        if (!isPointerFromTouch(event)) {
            localDOMHandlers.mousemove.call(this, event);
        }
    },

    pointerup: function (event) {
        localDOMHandlers.mouseup.call(this, event);
    },

    pointerout: function (event) {
        if (!isPointerFromTouch(event)) {
            localDOMHandlers.mouseout.call(this, event);
        }
    }

}

# DOMHandlerScope

什么作用呢? 感觉就是类似于闭包

function DOMHandlerScope(domTarget, domHandlers) {
    this.domTarget = domTarget;
    this.domHandlers = domHandlers;

    // Key: eventName, value: mounted handler funcitons.
    // Used for unmount.
    this.mounted = {};
    this.listenerOpts = {};

    this.touchTimer = null;
    this.touching = false;
}