移动端的touch事件详解

移动端的touch事件

触摸事件的起源

随着智能手机和平板电脑的普及, 越来越多的人用移动设备浏览网页,我们平时在pc浏览器上用的鼠标事件,比如:click, mouseover等, 已经无法满足移动设备触摸屏的特点,触摸时代的到来,离不开那些触摸事件。
触摸事件touchstart、touchmove和touchend的出现是因为iOS版Safari浏览器为了向开发人员传达一些信息而新添加的事件。因为ios设备既没有鼠标也没有键盘,所以在为移动Safari浏览器开发交互性网页的时候,PC端的鼠标和键盘事件是不够用的。
在iPhone 3Gs发布的时候,其自带的移动Safari浏览器就提供了一些与触摸(touch)操作相关的新事件。随后,Android上的浏览器也实现了相同的事件。触摸事件(touch)会在用户手指放在屏幕上面的时候、在屏幕上滑动的时候或者是从屏幕上移开的时候出发。

事件类型

1.touchstart事件(触摸开始事件):当手指触摸屏幕时候触发,即使已经有一个手指放在屏幕上也会触发(触发一次)。
2.touchmove事件(触摸移动事件):当手指在屏幕上滑动的时候连续地触发。在这个事件发生期间,调用preventDefault()事件可以阻止滚动(当手指在屏幕上滑动,就会一直触发)。
3.touchend事件(触摸结束事件):当手指从屏幕上离开的时候触发。(触发一次)
4.touchcancel事件(触摸中断事件):当触摸中断时候触发。

注意:上面的这些事件都会冒泡,也都可以取消。

属性

虽然这些触摸事件没有在DOM规范中定义,但是它们却是以兼容DOM的方式实现的。所以,每个触摸事件的event对象都提供了在鼠标实践中常见的属性:
1.bubbles – 起泡事件的类型
2.cancelable – 是否用 preventDefault() 方法可以取消与事件关联的默认动作
3.clientX – 返回当事件被触发时,鼠标指针的水平坐标
4.clientY – 返回当事件触发时,鼠标指针的垂直坐标
5.screenX – 当某个事件被触发时,鼠标指针的水平坐标
6.screenY – 返回当某个事件被触发时,鼠标指针的垂直坐标
7.altKey – 该属性返回一个布尔值,表示在指定的事件发生时,Alt 键是否处于按下状态, event.altKey=true\false或者1\0
8.type – 触摸时触发的事件类型,比如touchstart

并且每个触摸事件都包括了三个触摸属性列表:
1 .touches:当前位于屏幕上的所有手指触摸点的一个列表
2. targetTouches:当前元素对象上所有触摸点的列表
3. changedTouches:涉及当前事件的触摸点的列表
例:

<body>
<style>
#dom {
  width:500px;
  height:500px;
  background:black;
}
</style>
<div id="dom"></div>
<script>
function onTouchStart(e){
    console.log(e);
}
function start(){
    var dom = document.getElementById('dom');
    dom.addEventListener('touchstart', onTouchStart, false);
}
</script>
</body>

控制台输出如下:
在这里插入图片描述

触摸事件跟鼠标事件的触发先后顺序

touchstart > toucheend > mousemove > mousedown > mouseup > click

移动端触屏click点击事件延迟问题的解决方案

click事件在移动端和pc端均可以触发,但是在移动端有延迟现象。
1、背景
由于早期移动设备浏览网页时内容较小,为了增强用户体验,苹果公司专门为移动设备设计了双击放大的功能,以确保用户可以方便地放大网页内容,但是当用户单击按钮的时候,移动设备需要延迟约300ms执行,以判断用户是否是要双击。
2.解决方案
给移动端加视口,禁止缩放(慎用。因为在移动端没有视口的情况下,用户是可以进行缩放的,默认会存在双击放大的功能,禁用后,那么双击放大的功能也就没有了)
例:

<meta name="viewport" content="width=device-width, user-scalable=no">
<!-- 关键词 user-scalable = no -->

使用touch事件模拟一个点击事件

如下使用touchstart和touched封装了一个移动端的tap事件。
例:

var idcast = {
        //传入dom元素
        tap:function(dom,callback) {
            //判断是否传入了dom元素,或者dom元素是否是一个对象
            if(!dom||typeof dom != "object"){
                return;
            }
            var startX,startY,time,moveX,moveY,distanceX,distanceY;
            dom.addEventListener("touchstart",function(e) {
                if(e.targetTouches.length>1) {
                    return;
                }
                startX = e.targetTouches[0].clientX;
                startY = e.targetTouches[0].clientY;
                time = Date.now();
            });
            dom.addEventListener("touchend",function(e) {
                if(e.changedTouches.length>1) {//说明不止一个手指
                    return;
                }
                //判断时间差异
                if(Date.now()-time>150){//长按操作
                    return;
                }
                //获取松开手指的时候的坐标与触摸开始时的坐标差异
                moveX = e.changedTouches[0].clientX;
                moveY = e.changedTouches[0].clientY;
                distanceX = moveX - startX;
                distanceY = moveY - startY;
                //判断坐标差异
                if(Math.abs(distanceX) < 6 && Math.abs(distanceY) <6) {//说明是点击而非滑动
                    //执行tap事件相应之后的处理操作
                    //若函数不为空才调用
                    callback&&callback(e);
                    console.log("移动端点击单击事件--tap事件");
                }
            })
        }
    }

使用fastclick.js插件
fastclick.js是FT Labs专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库。简而言之,FastClick 在检测到 touchend 事件的时候,会通过 DOM 自定义事件立即触发一个模拟 click 事件,并把浏览器在 300 毫秒之后真正触发的click事件阻止掉。 FastClick 的使用方法非常简单,在DOMContentLoaded事件之后,在body上调用FastClick.attach()即可。
例:

 if ('addEventListener' in document) {
	    document.addEventListener('DOMContentLoaded', function() {
		FastClick.attach(document.body);
	        }, false);
        }

attach方法虽可在更具体的元素上调用,直接绑定到body上可以确保整个应用都能受益。当 FastClick 检测到当前页面使用meta设置了user-scalable=no或者 touch-action 属性的解决方案时,会静默退出。可以说,这是真正的跨平台方案出来之前一种很好的变通方案。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现移动端touch事件的横向滑动列表效果可以使用原生的JavaScript和CSS3来实现。 首先,我们需要在HTML中创建一个容器元素,用来包含列表项。容器元素需要设置overflow-x属性为scroll,使得内容超出容器范围时可以滚动。 ```html <div class="container"> <ul class="list"> <li>项1</li> <li>项2</li> <li>项3</li> <li>项4</li> <li>项5</li> </ul> </div> ``` 然后,在CSS中,我们需要设置容器元素和列表项的样式,以及使用CSS3的transition属性来实现平滑的过渡效果。 ```css .container { width: 100%; overflow-x: scroll; -webkit-overflow-scrolling: touch; /* 添加iOS滚动效果 */ } .list { display: flex; flex-wrap: nowrap; /* 设置列表项不换行 */ transition: transform 0.3s ease; /* 添加平滑的过渡效果 */ } .list li { width: 100px; height: 100px; margin-right: 10px; background-color: #ccc; } ``` 最后,在JavaScript中,我们需要监听容器元素的touchstart、touchmove和touchend事件,计算滑动距离并通过改变列表项的transform属性来实现横向滑动效果。 ```javascript const container = document.querySelector('.container'); const list = document.querySelector('.list'); let isDragging = false; let startPosition = 0; let currentTranslate = 0; let prevTranslate = 0; let animationId = 0; container.addEventListener('touchstart', touchStart); container.addEventListener('touchmove', touchMove); container.addEventListener('touchend', touchEnd); container.addEventListener('touchcancel', touchEnd); function touchStart(event) { if (event.target.classList.contains('list')) { isDragging = true; startPosition = event.touches[0].clientX; animationId = requestAnimationFrame(updateAnimation); container.classList.add('grabbing'); } } function touchMove(event) { if (isDragging) { const currentPosition = event.touches[0].clientX; currentTranslate = prevTranslate + currentPosition - startPosition; } } function touchEnd() { isDragging = false; cancelAnimationFrame(animationId); prevTranslate = currentTranslate; container.classList.remove('grabbing'); } function updateAnimation() { list.style.transform = `translateX(${currentTranslate}px)`; animationId = requestAnimationFrame(updateAnimation); } ``` 通过以上代码,我们就成功地实现了移动端touch事件的横向滑动列表效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值