事件穿透和拦截机制同样并不是deviceone平台独有的,这个机制几乎是所有和UI相关的技术都共有,了解一下非常有必要。我们会以一个简单的例子来描述事件处理机制运行的过程。
我们先假定是手机屏幕显示一个UI,里面包括了4个View,这些View都是树状结构,父View下包含一个或多个子View,其中最上层的View和屏幕大小是一致的,参考下图:
我们可以看到view1有一个子节点view2,view2包含2个子节点view3和view4.
假如我们点击屏幕一个位置,会产生一个事件event对象,整个流程都是这个对象在流转,如下图:
接下来的流程是:
整个屏幕接受到点击事件后,view1先处理,注意是view1哦。我们命名这个事件叫event1,这个事件包含了坐标值,这个时候假设这个点击的位置的坐标是(x0,y0),这里我们的坐标都是相对整个屏幕。view1接受到event1后先判断自己有没有子节点,发现有一个子节点view2,先问view2:“点击事件是你的区域内吗?”view2是一个矩形,它会先判断(x0,y0)是否在自己的区域里,如果是,继续判断自己有没有子节点,发现有2个子节点,先问view3,再问view4同样的问题:“点击事件是在你的区域内吗?”view4告诉它的父节点view2,“点击是在我的区域里了”,view2会继续问view4,“那你处理这个event1吗?”view4如果处理,那么event1的生命周期就到此结束了。(这是通常情况,有特殊情况,它可以处理完event1,又手动把事件传递给别的view)view4如果不处理,那么event1又返回到父亲节点view2,同样的逻辑,view2处理或者不处理返回给它的父节点view1。
总之,事件处理的机制是从根节点逐步到最末端的子节点,然后又返回回来一级级向父节点传递。
有了上面的机制基础,我们就可以理解一下touch事件的处理方式了。比如下面的四种点击处理,在不同的事件订阅情况下有不同的结果。如下:
view1.on("touch",function(){
deviceone.print("view1 touch")
})
view2.on("touch",function(){
deviceone.print("view2 touch")
})
view3.on("touch",function(){
deviceone.print("view3 touch")
})
view4.on("touch",function(){
deviceone.print("view4 touch")
})
结果就是:
点击1 会打印 "view1 touch"
点击2 会打印 "view2 touch"
点击3 会打印 "view3 touch"
点击4 会打印 "view4 touch"
view1.on("touch",function(){
deviceone.print("view1 touch")
})
view2.on("touch",function(){
deviceone.print("view2 touch")
})
view3.on("touch",function(){
deviceone.print("view3 touch")
})
view4.on("touch",function(){
//do nothing
})
结果就是:
点击1 会打印 "view1 touch"
点击2 会打印 "view2 touch"
点击3 会打印 "view3 touch"
点击4 什么都不会打印,事件被view4拦截了
view1.on("touch",function(){
deviceone.print("view1 touch")
})
view2.on("touch",function(){
deviceone.print("view2 touch")
})
view3.on("touch",function(){
deviceone.print("view3 touch")
})
结果就是:
点击1 会打印 "view1 touch"
点击2 会打印 "view2 touch"
点击3 会打印 "view3 touch"
点击4 会打印 "view2 touch",view4上的点击穿透view4到达view2
view1.on("touch",function(){
deviceone.print("view1 touch")
})
结果就是:
点击1 会打印 "view1 touch"
点击2 会打印 "view1 touch"
点击3 会打印 "view1 touch"
点击4 会打印 "view1 touch"