细说 JavaScript 事件编码维护

阅读 598
收藏 33
2017-05-06
原文链接:www.imooc.com

在学习完JavaScript事件之后,我们对事件都有一定的了解了,但是你的编码是否利于维护了呢?这里将讲述编写事件代码的两个规则。

规则1: 将应用逻辑将事件处理程序分离

我们先定义一些对象用于存储跨浏览器的事件处理程序与事件对象方法,这里将不讲解这个代码,详情可参考红宝书。

var EventUtil = {

    // 添加事件处理程序
    addHandler: function(element, type, handler) {

        if (element.addEventListener) {
                        // DOM2级事件处理程序
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
                        // IE事件处理程序
            element.attachEvent(type, handler);
        } else {
                        // DOM0级事件处理程序
            element["on" + type] = handler;
        }
    },

    // 删除事件处理程序
    removeHandler: function(element, type, handler) {
        if(element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent(type, handler);
        } else {
            element["on" + type] = null;
        }
    },

    // 获取事件对象
    getEvent: function(event) {
        return event ? event : window.event;
    },

    // 获取事件目标
    getTarget: function(event) {
        return event.target || event.srcElement;
    },

    // 阻止默认行为
    preventDefault: function(event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },

    // 取消事件冒泡
    stopPropagation: function(event) {
        if (event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubble = false;
        }
    }
}

或许你现在是这样写代码的

function getClient(event) {
    console.log(event.clientX + event.clientY);
}

// 使用上例代码的对象方法,并且element参数自定义
EventUtil.addHandler(element, "click", getClient);

在上面例子中就没有分离应用逻辑跟事件处理程序。

而应用逻辑与事件处理程序的定义如下:

应用逻辑:应用逻辑是和应用相关的功能性代码,而不是和用户行为相关的。在上例的中getClient函数中的函数体。
事件处理程序:事件处理程序是相应某个事件的函数。

所以我们需要这么做,来分离应用逻辑与事件处理程序。

var myApplication = {
    // 应用逻辑
    getClient: function(event) {
        console.log(event.clientX + event.clientY);
    },

    // 作用只用来调用getClient()函数
    // 此函数也就是事件处理程序
    runGetClient: function(event) {
        this.getClient(event);
    }
}

EventUtil.addHandler(element, "click", function(event) {
    myApplication.runGetClient(event);
}

以为做到上面这样就够了?

现在来说规则2:不要分发事件对象
在上面例子中应用逻辑的功能依赖event对象来完成,但应用逻辑不应该依赖于event对象,相反方法接口对于依赖应该是透明的,并且假如你想测试该方法,可你又得重新创建event对象来测试,如上例

所以使用下面例子来让事件对象不被分发

var myApplication = {
    // 应用逻辑
    getClient: function(x, y) {
        console.log(x + y);
    },

    // 作用只用来调用getClient()函数
    // 此函数也就是事件处理程序
    runGetClient: function(event) {
        this.getClient(event.clientX, event.clientY);
    }
}

EventUtil.addHandler(element, "click", function(event) {
    myApplication.runGetClient(event);
}
评论