微信小程序的滑动事件是通过bindtouchmove实现的,通过比较滑动事件前后的坐标判断滑动方向,微信小程序通过三个事件共同作用实现了触摸滑动事件,即 bingtouchstart、bindtouchmove 和 bindtouchend 事件。
WXML:
<view class='btn' bindtouchstart='touchStart' bindtouchmove='touchMove' bindtouchend='touchEnd'>
OK
</view>
JS:
data: {
touchS : [0,0],
touchE : [0,0]
},
touchStart: function(e){
// consolelog(etouches[0]pageX)
let sx = etouches[0]pageX
let sy = etouches[0]pageY
thisdatatouchS = [sx,sy]
},
touchMove: function(e){
let sx = etouches[0]pageX;
let sy = etouches[0]pageY;
thisdatatouchE = [sx, sy]
},
touchEnd: function(e){
let start = thisdatatouchS
let end = thisdatatouchE
consolelog(start)
consolelog(end)
if(start[0] < end[0] - 50){
consolelog('右滑')
}else if(start[0] > end[0] + 50){
consolelog('左滑')
}else{
consolelog('静止')
}
},
在 touchstart 时,监听到触摸开始时的 (x, y)位置;在 touchMove 方法中持续监听触摸点的位置(x, y),并保存在 data 中;在 touchEnd 方法中对开始的触摸位置和结束的触摸位置进行判断,如果移动距离大于 50 则判定为发生触摸滑动事件。
在上面示例中,当 X 轴方向的移动超过 50 时即判定为左滑或右滑,相应的也可以通过判断 Y 轴方向的滑动长度,来判断上滑或是下滑,由此实现触摸滑动的功能。
更多信息联系我的微
左右滑动是由触摸事件定义的,触摸事件(touch)会在用户手指放在屏幕上面的时候、在屏幕上滑动的时候或者是从屏幕上移开的时候触发。下面具体说明:touchstart事件:当手指触摸屏幕时候触发,即使已经有一个手指放在屏幕上也会触发。touchmove事件:当手指在屏幕上滑动的时候连续地触发。在这个事件发生期间,调用preventDefault()事件可以阻止滚动。touchend事件:当手指从屏幕上离开的时候触发。touchcancel事件:当系统停止跟踪触摸的时候触发。关于这个事件的确切出发时间,文档中并没有具体说明,咱们只能去猜测了。上面的这些事件都会冒泡,也都可以取消。虽然这些触摸事件没有在DOM规范中定义,但是它们却是以兼容DOM的方式实现的。所以,每个触摸事件的event对象都提供了在鼠标实践中常见的属性:bubbles(起泡事件的类型)、cancelable(是否用 preventDefault() 方法可以取消与事件关联的默认动作)、clientX(返回当事件被触发时,鼠标指针的水平坐标)、clientY(返回当事件触发时,鼠标指针的垂直坐标)、screenX(当某个事件被触发时,鼠标指针的水平坐标)和screenY(返回当某个事件被触发时,鼠标指针的垂直坐标)。除了常见的DOM属性,触摸事件还包含下面三个用于跟踪触摸的属性。touches:表示当前跟踪的触摸 *** 作的touch对象的数组。targetTouches:特定于事件目标的Touch对象的数组。changeTouches:表示自上次触摸以来发生了什么改变的Touch对象的数组。每个Touch对象包含的属性如下。clientX:触摸目标在视口中的x坐标。clientY:触摸目标在视口中的y坐标。identifier:标识触摸的唯一ID。pageX:触摸目标在页面中的x坐标。pageY:触摸目标在页面中的y坐标。screenX:触摸目标在屏幕中的x坐标。screenY:触摸目标在屏幕中的y坐标。target:触目的DOM节点目标。
举个例子-JavaScript代码:
function load (){
documentaddEventListener('touchstart',touch, false);
documentaddEventListener('touchmove',touch, false);
documentaddEventListener('touchend',touch, false);
function touch (event){
var event = event || windowevent;
var oInp = documentgetElementById("inp");
switch(eventtype){
case "touchstart":
oInpinnerHTML = "Touch started (" + eventtouches[0]clientX + "," + eventtouches[0]clientY + ")";
break;
case "touchend":
oInpinnerHTML = "Touch end (" + eventchangedTouches[0]clientX + "," + eventchangedTouches[0]clientY + ")";
break;
case "touchmove":
eventpreventDefault();
oInpinnerHTML = "Touch moved (" + eventtouches[0]clientX + "," + eventtouches[0]clientY + ")";
break;
}
}
}
windowaddEventListener('load',load, false);
HTML代码:
<div id="inp"></div>上面的小例子当touchstart事件触发的时候,会将触摸的位置更新到div标签中。当touchmove事件触发的时候,会默认行为的滚动(触摸移动的默认行为是滚动页面),然后触摸 *** 作的变化信息更新到div标签中。而touchend事件会输出有关触摸 *** 作的最终信息。注意,在touchend事件触发的时候,touches集合中就没有任何Touch对象了,因为不存在活动的触摸 *** 作。
这些事件会在文档的所有元素上面触发,因而可以分别 *** 作页面的不同部分。在触摸屏幕上的元素,这些事件(包括鼠标事件)发生的顺序如下:
(1)touchstart
(2)mouseover
(3)mousemove(一次)
(4)mousedown
(5)mouseup
(6)click
(7)touchend
参考
移动端touch事件和click事件的区别
在手持设备上使用 touchstart 事件代替 click 事件是不是个好主意?
touchstart: //手指放到屏幕上时触发
touchmove: //手指在屏幕上滑动式触发
touchend: //手指离开屏幕时触发
touchcancel: //系统取消touch事件的时候触发,这个好像比较少用
每个触摸事件被触发后,会生成一个event对象
在移动端,手指点击一个元素,会经过:touchstart --> touchmove -> touchend --》click。
在手持设备的浏览器上(本处主要指代iOS和Android系统上的webkit内核的浏览器和嵌入在应用程序里面的webview),由于两次连续“轻触”是“放大”的 *** 作(即使你两次轻触的是一个链接或一个有click事件监听器的元素),所以在第一次被“轻触”后,浏览器需要先等一段时间,看看有没有所谓的“连续的第二次轻触”。如果有,则进行“放大” *** 作。没有,才敢放心地认为用户不是要放大,而是需要“click”至此才敢触发click事件,导致“短按(手指接触屏幕到离开屏幕的时间比较短)”的click事件通常约会延迟300ms左右。
采用touchstart代替click是比较初级的解决方案,首先,touchstart和click的触发条件就有区别,对于手持设备的浏览器:1touchstart:在这个dom(或冒泡到这个dom,这当然是废话)上手指触摸开始即能触发2click:在这个dom(或冒泡到这个dom,这当然是废话)上手指触摸开始,且手指未曾在屏幕上移动(某些浏览器允许移动一个非常小的位移值),且在这个在这个dom上手指离开屏幕,且触摸和离开屏幕之间的间隔时间较短(某些浏览器不检测间隔时间,也会触发click)才能触发于是我们可以看到,完全用touchstart代替是不太可取的。根据上面的区别,又要规避click在移动手持设备上带来的延迟,很容易有了模拟的办法,大致思路是:在touchstart、touchend时记录时间、手指位置,在touchend时进行比较,如果手指位置为同一位置(或允许移动一个非常小的位移值)且时间间隔较短(一般认为是200ms),且过程中未曾触发过touchmove,即可认为触发了手持设备上的“click”,一般称它为“tap”
webview点击滚动条导致touchend!答案是touchstart事件触发的时候设置全局变量(名字随便取)flag = 1; 2,touchmove事件触发
所以以上是webview点击滚动条导致touchend的原因。
网页可见区域宽: documentbodyclientWidth
网页可见区域高: documentbodyclientHeight
网页可见区域宽: documentbodyoffsetWidth (包括边线的宽)
网页可见区域高: documentbodyoffsetHeight (包括边线的高)
网页正文全文宽: documentbodyscrollWidth
网页正文全文高: documentbodyscrollHeight
网页被卷去的高: documentbodyscrollTop
网页被卷去的左: documentbodyscrollLeft
网页正文部分上: windowscreenTop
网页正文部分左: windowscreenLeft
屏幕分辨率的高: windowscreenheight
屏幕分辨率的宽: windowscreenwidth
屏幕可用工作区高度: windowscreenavailHeight
屏幕可用工作区宽度: windowscreenavailWidth
` font-family: PingFang SC,STHeitiSC-Light,Helvetica-Light,arial,sans-serif,Droid Sans Fallback;
<meta name="viewport" content="width=device-width, initial-scale=10, maximum-scale=10, user-scalable=0">
<body onselectstart="return false">
white-space: pre-wrap;
-webkit-tap-highlight-color: transparent;
注意到“pre-wrap”属性值:保留空白符序列,但是正常地进行换行。
white-space:pre-wrap;
filter: brightness(100); 变白
第二行变第一行不变
body{}
小程序上fixed成功过
一般这种都让ios或者安卓端禁止掉,然后在有d性需求的页面添加样式
overflow-y: scroll;
-webkit-overflow-scrolling : touch;
即可
-webkit-overflow-scrolling: touch;
//小程序 h5 交互
touches: 当前屏幕上所有触摸点的列表;
targetTouches: 当前对象上所有触摸点的列表;
changedTouches: 涉及当前(引发)事件的触摸点的列表
通过一个例子来区分一下触摸事件中的这三个属性:
1 用一个手指接触屏幕,触发事件,此时这三个属性有相同的值。
2 用第二个手指接触屏幕,此时,touches有两个元素,每个手指触摸点为一个值。当两个手指触摸相同元素时,targetTouches和touches的值相同,否则targetTouches 只有一个值。changedTouches此时只有一个值,
为第二个手指的触摸点,因为第二个手指是引发事件的原因
3 用两个手指同时接触屏幕,此时changedTouches有两个值,每一个手指的触摸点都有一个值
4 手指滑动时,三个值都会发生变化
5 一个手指离开屏幕,touches和targetTouches中对应的元素会同时移除,而changedTouches仍然会存在元素。
6 手指都离开屏幕之后,touches和targetTouches中将不会再有值,changedTouches还会有一个值,
此值为最后一个离开屏幕的手指的接触点。
3touchmove事件对象的获取
想要在touchmove:function(e,参数一)加一个参数,结果直接使用epreventDefault()就会 e 报错,处理方法为使用arguments[0]获取event参数
touchmove:function(e,参数一){
var e=arguments[0]
epreventDefault()
}
webpack-config dev-server 添加 disableHostCheck: true,
html的font-size还没设置的时候展示的样式是错误的
关于获取各种浏览器可见窗口大小的一点点研究
经本地测试和研究再次对 documentdocumentElementclientWidth 进行解释:
每一个html文件在浏览器中都会被解析为一个页面,documentdocumentElementclientWidth则是获取本页面的宽度。
下面进行举例子说明:
1) 如果在浏览器全屏,并且打开的一个标签页中只包含一个页面,则documentdocumentElementclientWidth即本页面的宽度=浏览器的宽度=屏幕可用工作区宽度:即windowscreenavailWidth;
2)当调整浏览器为非全屏状态时并且打开的一个标签页中只包含一个页面:则documentdocumentElementclientWidth即本页面的宽度=浏览器的宽度!=屏幕可用工作区宽度:即windowscreenavailWidth;
3)当打开的一个标签页中不只包含一个页面:比如在一个页面的frame中包含一个ifrme,该iframe指向另一个页面,如下所示
则iframe指向页面的documentdocumentElementclientWidth不再等于浏览器宽度,而是等于ifame的宽度
最近项目开发过程中,在ios环境下。双击(doubletap)上层元素(固定定位fix),偶尔会触发下层(瀑布流中)路由跳转。
经过部门老大指导,才了解到这个现象叫做“事件穿透”。再此俺决定研究下为什么?
电脑上一般是鼠标 *** 作,即响应的是鼠标事件,包括mousedown、mouseup、mousemove和click事件。
在一次点击行为中,事件的触发过程为:mousedown -> mouseup -> click 三步。
由于手机上没有鼠标,所以就用触摸事件去实现类似的功能。touch事件包含touchstart、touchmove、touchend
注意手机上并没有tap事件。 一些库例如hamerjs、zeptojs 等等都是通过处理这些原生事件,来定义不同的手势以及tap事件。
在一次点击行为中,事件的触发过程为:touchstart -> touchmove -> touchend。
有人在PC和手机上对事件做了对比实验,以说明手机对touch事件相应速度快于mouse事件。touchstart --> mouseover(有的浏览器没有实现) --> mousemove(一次) -->mousedown --> mouseup --> click -->touchend。
浏览器在 touchend 之后会等待约 300ms ,如果没有 tap 行为,则触发 click 事件。 而浏览器等待约 300ms 的原因是,判断用户是否是双击(double tap)行为,双击过程中就不适合触发 click 事件了。 由此可以看出 click 事件触发代表一轮触摸事件的结束。
ps:此处偷一张图
跟局官网描述我们可以看出:触发路由跳转的事件默认为 click
移动端chromiun 和 iOS 93+ 可以用 CSS 属性来阻止元素的双击缩放进而取消点击穿透的延迟:
首先引入库:
调用:
将层的固定定位“降”下来,和下面的router-link都在瀑布流内。
注:此方法只适合部分项目。
由于 click 事件的滞后性,在这段时间内原来点击的元素消失了,于是便“穿透”了。因此我们顺着这个思路就想到,可以给元素的消失做一个fade效果,类似jQuery里的fadeOut,并设置动画duration大于300ms,这样当延迟的 click 触发时,就不会“穿透”到下方的元素了。
同样的道理,不用延时动画,我们还可以动态地在触摸位置生成一个透明的元素,这样当上层元素消失而延迟的click来到时,它点击到的是那个透明的元素,也不会“穿透”到底下。在一定的timeout后再将生成的透明元素移除。
1、系统响应阶段:触摸屏幕→IOKit(IOHIDEvent)→通过mach port(IPC进程间通信)转发给SpringBoard(IOHIDEvent)→SpringBoard通过当前桌面状态判断前台运行的app,并通过mach port转发给当前app
2、应用内部:当前app主线程RunLoop的Source1(监听mach port消息,接收SpringBoard事件)触发,并在Source0回调内部把IOHIDEvent封装为 UIEvent, 调用UIApplication的sendEvent把UIEvent传给UIWindow,开始通过hitTest:view寻找最佳响应者( UIResponder ),找到最佳响应者后,事件开始在响应链中传递,最终被某个响应者/手势识别器/Target-Action模式捕捉并消耗掉,或没有找到任何响应对象后释放。
注:Mach Port进程端口,各进程利用它进行通信。
注:SpringBoard是一个系统进程,即桌面系统,统一管理和分发触摸事件。
事件的传递和分发,其实是寻找最佳响应者的过程(Hit-Testing 命中检测)。事件的传递起源于触摸状态的变化,一个点击会触发两次事件的传递(begin到end,touch的状态发生变化)
核心方法
1、- (UIView )hitTest:(CGPoint)point withEvent:(UIEvent )event {} // 视图是否能够响应事件
2、- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent )event {} // 触摸点是否在hitTest方法返回的视图内
传递过程 :UIApplication
→调用UIWindow的hitTest(多个window询问后显示的window(所以新添加的window记得makeKeyAndVisible))
→递归询问子视图是否能响应事件(实现:判断3种无法响应的情况→判断触摸点(return nil),从后往前遍历子视图(i = count - 1),convertPoint坐标转换到子视图上,并递归调用hitTest询问子视图中的子视图,如果有合适的则return,没有则return self)
→Window的hitTest方法返回最佳响应者,告知UIApplication。
注:无法响应的3种情况userInteractionEnabled = NO;hidden = YES;alpha < 001
事件拦截 :定制视图,自定义事件流向。如遇到超出TabBar坐标范围的TabButton时,重写TabBar的pointInside方法,将坐标convert到Button上,再调pointInside判断是否在Button上即可实现越界点击。
事件首先传递给最佳响应者(hit-tested view)响应,并在响应链中的传递。
响应过程
UIApplication通过Event中的Touch对象找到触摸所属的Window,将事件通过sendEvent传递给Window,Window也通过sendEvent将事件优先传递给最佳响应者(直接传递,因为此时Window已找到最佳响应者并保存了起来),然后通过 nextResponder 方法获取下一个响应者,形成响应链。
注:UIView的nextResponder是VC(如果此View是根视图)或其父视图;
VC的nextResponder是Window(如果此VC是根视图),如果VC是被present出来的,则是它的presenting view controller;
UIWindow的nextResponder是UIApplication;
UIApplication的nextResponder是AppDelegate。
事件的响应
UIResponder对象通过4个touch方法响应触摸事件,但默认不做事情,只单纯的继续传递,重写方法可以截获事件,进行 *** 作。(如创建自定义视图,重写touchMoved方法,通过touches和event属性实现简单的视图拖动)
注:在寻找最佳响应者时,所属的window和view会绑定到touch对象上,以供事件的传递过程中找到视图,给响应者发送事件。
事件的拦截
拦截和响应都是通过touchBegan方法控制的,默认实现为将事件沿着响应链继续向下传递。
1、不拦截,默认继续传递。
2、拦截,不再传递:重写touchesBegan处理事件,且不调用父类的方法。
3、拦截,继续传递:重写处理并调用父类的touchesBegan。
注:UIScrollViewDelayedTouchesBeganGestureRecognizer属性和手势延迟015秒的属性类似,所以,当视图中有手势和TableView共存时1、轻点手势只会执行手势而事件不会到达最佳响应者;2、短按会超过015到达最佳响应者但会因为手势拦截事件而被cancel;3、长按会因为手势识别失败,事件传递给最佳响应者执行cell的selected。
1、UIWindow是分发事件和响应事件的重要角色,是事件的起点:寻找最佳响应者时从Window开始寻找子视图,找到后也是由Window通过sendEvent:将事件传递给最佳响应者(hit-tested view)。
2、响应链中,Control上没有Gesture优先响应Control,Responder优先级最低,甚至会被视图层级低于自己的Gesture打断并Cancel掉Touch状态。
事件本身,type标识事件类型(触摸,加速计等),allTouchs属性包含了如多个手指产生的所有触摸对象(UITouch)的集合。
UITouch
源起触摸,封装在UIEvent内部,在事件传递时用于判断hitTest-view和确定GestureRecognizers。1手指1触摸生成1个UITouch;N手指1触摸生成N个UITouch对象;N手指N触摸,通过触摸位置判断是更新上次的还是再生成一个UITouch。手指离开屏幕一段时间后,确定UITouch不再更新才会释放。
UIResponder
响应者对象,具备响应事件的能力,因为其提供了4个处理触摸事件的Touch方法:Began、Moved、Ended、Cancelled,在接收到事件时调用,可以做出响应。如UIView/UIViewController/UIApplication/AppDelegate。
UIControl
以Target-Action模式处理触摸事件,如UIButton、UISwitch。UIControl跟踪到触摸事件时会向Target发送事件以执行Action(只接收单点触控)。跟踪的4个方法:beginTrackingWithTouch:(UITouch )touch、continueTracking、endTracking、cancelTracking。UIControl继承UIView,也具备普通UIResponder的身份,也有touch的4个方法,但默认实现与本类不同,如touchesBegan方法内部会调用beginTracking。
响应过程:先通过addTarget:action:forControlEvents:(UIControlEvents有许多关于交互事件的枚举)添加处理事件的target和action;当UIControl监听到事件时,sendAction把target、action和event都发给Application,再通过sendAction:from:to:forEvent向target发action(如果target为空,Application会在响应链中自己找能响应aciton的对象)
同样具有响应事件的能力,分为离散型(tap、swipe)和持续型。4个处理事件的方法跟UIResponder一样但无关(在UIGestureRecognizerSubclass中声明)。
手势识别成功后的处理: 事件响应在Source0回调的_UIApplicationHandleEventQueue()方法中,如果识别成了UIGesture手势时,首先调用Cancel打断当前的touch系列回调,然后将UIGestureRecognizer标记为待处理。当监听到BeforeWait事件时,回调函数_UIGestureRecognizerUpdateObserver()内部会获取所有标记待处理的手势,并执行手势回调。每当UIGestureRecognizer变化(创建销毁状态改变)时,RecognizerUpdate回调都会进行相应的处理。
离散型手势对响应链的影响
UIApplication在把事件传递给最佳响应者之前,会将事件先传递给相关的手势识别器开始识别,如果成功识别则会取消hit-tested view对事件的响应。但最佳响应者的touchBegan会先于手势的action执行,因为手势的识别成功(status = recognized)的时机是稍晚的。但重写手势的touchBegan方法即可证明UIWindow先把事件传递给了手势。-[TapGestureRecognizer touchesBegan:withEvent:]-[View touchesBegan:withEvent:]-[TapGestureRecognizer touchesEnded:withEvent:]Gesture Taped Action-[View touchesCancelled:withEvent:]注:如何优先传递给手势识别器?在hit-test过程中收集了UIGestureRecognizer的数组,保存在了event绑定的touch上。
持续型手势对响应链的影响
一个滑动的交互:pan手势识别过程中,连续事件会先传递给最佳响应者持续调用touchesMoved;pan手势识别成功后执行action,并通知Application去cancel掉响应者对事件的响应,之后都由手势接收事件并响应。若没有识别成功,则会一直传递给最佳响应者。
UIGestureRecognizer的三个属性轻点、短按、长按
cancelsTouchesInView:决定手势识别成功后,是否cancel响应链中响应者的响应(拦截并阻断),默认是YES
delaysTouchesBegan:是否在手势识别期间,就阻断事件传递给最佳响应者,默认是NO
delaysTouchesEnded:手势识别失败且触摸结束时,是否延迟015秒通知最佳响应者调用touchesEnded以结束事件响应,默认是YES
描述一下触摸事件的生命周期
分为系统响应阶段,和应用内部的传递、响应:IOKit到SpringBoard到APP(通过MachPort),应用内主线程RunLoop的Source回调中处理成UIEvent调UIApplication的sendEvent开始分发,通过hitTest找最佳响应者(传递链);响应者/手势识别器/Target-Action响应事件消耗或释放(响应链)。
系统是如何寻找最佳响应者的(传递链),如何在传递链中拦截事件
UIWindow中递归调用hitTest,判断三个交互条件+pointInside,满足则继续遍历子视图,否则返回自身。
重写pointInside可以扩大热区,拦截事件,自定义流向,最好不要调hitTest,因为实现不明,注意调super)
描述事件的响应过程(响应链),如何在响应链中拦截事件
事件由UIWindow先发送给最佳响应者,通过重写4个touch方法,截获处理后就终止(是否不再继续传递的标志是-是否调用supertouch方法),否则就nextResponder,期间手势识别器识别成功后会break掉touch的响应链。
UIGestureRecognizer对响应链的影响(离散型和持续型)
手势有识别过程,三个属性分别决定:识别成功后是否阻断响应链,是否开始识别时就阻断响应链,识别失败时候延迟通知最佳响应者调touchEnd。
<!DOCTYPE HTML>
<html>
<head>
<title>Page Title</title>
<meta >
以上就是关于手机小程序滑动返回是什么事件全部的内容,包括:手机小程序滑动返回是什么事件、html5页面左右滑动是怎么实现的、移动端touch事件和click事件的区别等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)