编写可维护的JavaScript-随笔(五)

事件处理

       当事件触发时,事件对象(event对象)会作为回调参数传入事件处理程序中,event对象包含所有和事件相关的信息

function handleClick(event){
    var popup = document.getElementById('popup')
    popup.style.left = event.clientX + 'px'
    popup.style.top = event.clientY + 'px'
    popup.className = "reveal"
}

addEventListener(element,"click",handleClick)

尽管上边的代码看起来非常简单且没有什么问题,但实际上是不好的写法,因为这种做法有其局限性

一、    规则

  a)     隔离应用逻辑

    1、上段实例代码第一个问题是事件处理程序中包含了应用逻辑,应用逻辑是和应用相关的功能性代码,而不是和用户行为相关的。如果别的事件也用到这段逻辑,但是存在元素判断的时候这段代码就会重复出现多次。2、测试的时候必须通过制造事件的触发才能测试,而调用功能性代码最好的做法就是单个函数的调用。需要将应用逻辑和事件处理的代码拆分开来。

    事件处理程序应当总是在一个相同的全局对象中

var MyApplication = {
    handleClick: function (event) {
        this.showPopup(event)
    },
    showPopup: function (event) {
        var popup = document.getElementById('popup')
        popup.style.left = event.clientX + 'px'
        popup.style.top = event.clientY + 'px'
        popup.className = "reveal"
    }
}

addEventListener(element,"click",function(event){
    MyApplication.handleClick(event)
})

MyApplication.handleClick()方法只做了一件事情,调用this.showPopup(event),若应用逻辑被剥离出去,对同一段功能代码的调用可以在多点发生,不需要一定依赖与某个特定事件的触发

  b)不要分发事件对象

  上段改造完后的代码存在一个问题,event对象被无节制地分发,从匿名的事件处理函数传入了MyApplication.handleClick(),然后又传入了MyApplication.showPopup()。但是event对象中的信息这里只用到两个,拿出所有需要的event对象中的数据传给应用逻辑

var MyApplication = {
    handleClick: function (event) {
        this.showPopup(event.clientX,event.clientY)
    },
    showPopup: function (x,y) {
        var popup = document.getElementById('popup')
        popup.style.left = x + 'px'
        popup.style.top = y + 'px'
        popup.className = "reveal"
    }
}

addEventListener(element,"click",function(event){
    MyApplication.handleClick(event)
})
//可以通过调用MyApplication.showPopup(10,10)进行测试,不用依赖事件触发

这样就清晰地看到showPopup()所期望传入的参数。并且在测试或代码的任意位置都可以轻易地直接调用这段逻辑

在处理事件时,最好让事件处理程序成为接触到event对象的唯一函数,在进入应用逻辑之前完成针对event对象的任何必要的操作,比如完成阻止默认事件或阻止事件冒泡

var MyApplication = {
    handleClick: function (event) {
        event.preventDefault()
        evrnt.stopPropagation()
        this.showPopup(event.clientX,event.clientY)
    },
    showPopup: function (event) {
        var popup = document.getElementById('popup')
        popup.style.left = x + 'px'
        popup.style.top = y + 'px'
        popup.className = "reveal"
    }
}

addEventListener(element,"click",function(event){
    MyApplication.handleClick(event)
})

这样就清楚地展示了事件处理程序和应用逻辑之间的分工。应用逻辑不需要对event产生依赖

 

posted @ 2019-08-05 15:25  下一页2013  阅读(219)  评论(0编辑  收藏  举报