屏幕事件穿透和拦截分析

事件穿透和拦截机制同样并不是deviceone平台独有的,这个机制几乎是所有和UI相关的技术都共有,了解一下非常有必要。我们会以一个简单的例子来描述事件处理机制运行的过程。

屏幕事件处理机制

我们先假定是手机屏幕显示一个UI,里面包括了4个View,这些View都是树状结构,父View下包含一个或多个子View,其中最上层的View和屏幕大小是一致的,参考下图:


我们可以看到view1有一个子节点view2,view2包含2个子节点view3和view4.

假如我们点击屏幕一个位置,会产生一个事件event对象,整个流程都是这个对象在流转,如下图:

接下来的流程是:

  1. 整个屏幕接受到点击事件后,view1先处理,注意是view1哦。我们命名这个事件叫event1,这个事件包含了坐标值,这个时候假设这个点击的位置的坐标是(x0,y0),这里我们的坐标都是相对整个屏幕。
  2. view1接受到event1后先判断自己有没有子节点,发现有一个子节点view2,先问view2:“点击事件是你的区域内吗?”
  3. view2是一个矩形,它会先判断(x0,y0)是否在自己的区域里,如果是,继续判断自己有没有子节点,发现有2个子节点,先问view3,再问view4同样的问题:“点击事件是在你的区域内吗?”
  4. view4告诉它的父节点view2,“点击是在我的区域里了”,view2会继续问view4,“那你处理这个event1吗?”
  5. view4如果处理,那么event1的生命周期就到此结束了。(这是通常情况,有特殊情况,它可以处理完event1,又手动把事件传递给别的view)
  6. view4如果不处理,那么event1又返回到父亲节点view2,同样的逻辑,view2处理或者不处理返回给它的父节点view1。

总之,事件处理的机制是从根节点逐步到最末端的子节点,然后又返回回来一级级向父节点传递。

事件穿透和拦截

有了上面的机制基础,我们就可以理解一下touch事件的处理方式了。比如下面的四种点击处理,在不同的事件订阅情况下有不同的结果。如下:

1. 四个view都订阅了事件
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. 点击1 会打印 "view1 touch"
  2. 点击2 会打印 "view2 touch"
  3. 点击3 会打印 "view3 touch"
  4. 点击4 会打印 "view4 touch"
2. 四个view都订阅了事件,但是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")
})
view4.on("touch",function(){
//do nothing
})

  

结果就是:

  1. 点击1 会打印 "view1 touch"
  2. 点击2 会打印 "view2 touch"
  3. 点击3 会打印 "view3 touch"
  4. 点击4 什么都不会打印,事件被view4拦截了
3. 只有三个view订阅了事件,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. 点击1 会打印 "view1 touch"
  2. 点击2 会打印 "view2 touch"
  3. 点击3 会打印 "view3 touch"
  4. 点击4 会打印 "view2 touch",view4上的点击穿透view4到达view2
4. 只有view1订阅了事件,其它都没有订阅。会导致事件一直穿透到最根节点。
view1.on("touch",function(){
deviceone.print("view1 touch")
})

  

结果就是:
    1. 点击1 会打印 "view1 touch"
    2. 点击2 会打印 "view1 touch"
    3. 点击3 会打印 "view1 touch"
    4. 点击4 会打印 "view1 touch"
时间: 2024-10-03 13:23:25

屏幕事件穿透和拦截分析的相关文章

Android Touch事件原理加实例分析

Android中有各种各样的事件,以响应用户的操作.这些事件可以分为按键事件和触屏事件.而Touch事件是触屏事件的基础事件,在进行Android开发时经常会用到,所以非常有必要深入理解它的原理机制. Android Touch事件原理描述 一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP. 当屏幕中包含一个ViewGr

IE8,input事件穿透

连续加班一个半月,项目昨天晚上12:08终于上线了:然后处理了一些新发现的bug:一直熬到凌晨五点半才吃点宵夜回家睡觉.然后下午这会过来上班:回想昨晚的场景,真的跟打仗一样..然后发现了一个比较有意思的bug:称之为"事件穿透"!,问题只在纯IE8浏览器下重现(IE9,10,11的的IE8模式切换不重新). 场景大概是这样的:首页有一个浮动的登录框:然后页头有一个导航(有链接),下面还有一个轮播图,而且有链接:如下图所示: 然后,IE8下,当你准备在输入框输入时,忽然发现点了一下,页面

事件分发、拦截、消费(一)

main.xml <?xml version="1.0" encoding="utf-8"?> <cn.sunzn.tevent.TouchEventFather xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fi

android事件分发,拦截,处理

事件分发 android事件处理的时候 会根据事件发生的坐标,从父容器一直慢慢的发送到相关的所有的view 因此当都不处理的时候 事件传递的流程图 dispatchTouchEvent返回true 但是如果我们在A的dispatchTouchEvent 中返回true,那么也就是事件不进行分发 发现只是调用了ViewGroupA事件的拦截方法,也就是没有将事件进行分发,连自己的onTouchEvent事件都没有进行处理 如果让ViewGroupB的dispatchEvent返回true呢? 当我

如何让触摸事件穿透一个View

偶然间发现,如何屏蔽或者让触摸事件穿透一个view是一个很简单的事情. 现象: 源码: // // ViewController.m // UserInteraction // // Created by YouXianMing on 14/10/23. // Copyright (c) 2014年 YouXianMing. All rights reserved. // #import "ViewController.h" @interface ViewController () @

支持事件穿透?使用pointer-events样式

使用绝对定位元素,让元素A完全盖住元素B时,如何通过元素A来响应元素B的事件呢? 上图可以用下面的SVG代码来实现: <svg width="200" height="180"> <rect x="50" y="50" width="50" height="50" fill="#f34b5b" onclick="alert('Clicked

JQuery 支持 hide 和 show 事件的方法与分析

问题提出  JQuery不支持hide和show作为事件形式出现, 实际上这两个仅仅是JQuery对象的一个方法(fn): 有一类UI交互需求,根据一个DOM对象的或者显示对附属的DOM对象做相同操作, 一般情况下, 利用jquery hide和show方法的扩展参数中的回调函数,是可以实现的,例如: $( "#book" ).hide( "slow", function() { $( "#booklet" ).hide() }); 如果附属DO

屏幕事件控制器

SAP程序的执行时通过事件来驱动的 1.INITIALIZATION事件,这个事件是在屏幕未显示之前执行,对程序设置值及屏幕元素进行初始化赋值 2.START-OF-SELECTION事件 该事件是单击执行按钮时触发的 3.END-OF-SELCTION事件 该事件应用于所有事件数据处理完成,即START-OF-SELECTION事件执行完成,但是输出屏幕还未显示之前.在实际开发中,主要应用于一直执行结果的检验等,其输出数据叠加于同一输出屏幕. 下面说说AT SELECTION-SCREEN事件

转载:事件穿透

前言 小伙伴们在开发中是否遇到过这样的需求呢,一个控件的某个部分被另外一个控件遮挡住,当点击这个重叠部分时,需要响应被遮盖控件的点击事件,就如下图所示 当我们点击区域3时,响应蓝色按钮的点击事件,点击区域1和2时,响应红色按钮的点击事件,对于区域1和3没什么好说的,那如何让红色按钮响应区域2的点击呢?这就是笔者今天要讲的内容. 事件传递 大家应该都知道,事件从应用程序开始,按照从上到下的顺序(UIApplication -> UIWindow -> rootViewController -&g