在上面代码中,点击事件发生时draw方法会执行一次重绘,并在重绘过程中检查每一个图形是否覆盖了事件坐标,如果判断为真,则视为点击了该图形,并将该图形的index值放入数组,最后将数组作为draw方法的返回值。在这种处理机制下,如果Canvas里有N个图形,它们有一部分是重叠的,而点击事件恰巧发生在这个重叠区域上,那么draw方法的返回数组里会有N个成员。这时就有点类似事件冒泡的情况,数组的最后一个成员处于Canvas最上层,而第一个成员则在最下层,我们可以视为最上层的成员是e.target,而其他成员则是冒泡过程中传递到的节点。当然这只是最简单的一种处理方法,如果真要模拟DOM处理,还要给图形设置父子级关系。
以上就是Canvas事件处理的基本方法。在实际运用时,如何缓存图形参数,如何进行循环重绘,以及如何处理事件冒泡,都还需要根据实际情况花一些心思去处理。另外,click是一个比较好处理的事件,相对麻烦的是mouseover、mouseout和mousemove这些事件,由于鼠标一旦进入Canvas元素,始终发生的都是mousemove事件,所以如果要给某个图形单独设置mouseover或mouseout,还需要记录鼠标移动的路线,给图形设置进出状态。由于处理的步骤变得复杂起来,必须对性能问题提高关注。