《四》移动端事件

如果移动端触摸方法中出现了一些莫名其妙的问题,可以添加下面的代码试试:

  1. Touch 触摸事件中,在 touchstart 中添加 event.preventDefault) ,阻止移动端浏览器默认行为。
  2. Pointer 指针事件中,加多绑定一个 touchstart 事件并添加 event.preventDefault)

Touch 触摸事件:

Touch 触摸事件是由苹果推出的。

特征检测:

判断浏览器是否支持 Touch 触摸事件。

if ('ontouchstart' in window) {
	console.log('支持')
}

事件类型:

  1. touchsatrt:当手指触摸开始时触发。
  2. touchmove:当手指滑动时连续触发。
  3. touchend:当手指触摸结束时触发。
  4. touchcancel:当手指触摸中断时触发(例如:有来电、有弹框弹出等)。

    触发了 touchend,就不会再触发 touchcancel;触发了 touchcancel,就不会再触发 touchend。所以,一般结束时要执行的方法,在 touchend 和 touchcancel 中都需要绑定。

const box = document.getElementById('box')
// 用手指在屏幕上点击一下,会触发一次 touchsatrt,一次 touchend
box.addEventListener('touchsatrt', () => {console.log('touchsatrt')})
box.addEventListener('touchend', () => {console.log('touchend')})

事件对象 Event:

const box = document.getElementById('box')
box.addEventListener('touchsatrt', (event) => {
	console.log(event)
})
事件对象 Event 的常用属性:
  1. type:事件类型。

  2. target:目标元素。

  3. touches:屏幕上所有的触摸点组成的类数组。
    targetTouches:类数组。目标元素上所有的触摸点组成的类数组。
    changeTouches:类数组。事件触发时,目标元素上状态发生了改变的触摸点组成的类数组。

    es 为复数,表明不单支持单指触摸,也支持多指触摸。

    例如:以下为一个手机屏幕,在红色背景的元素上绑定了触摸事件。
    《四》移动端事件_第1张图片
    用三根手指触摸屏幕,落在红色背景的元素中两根,其他区域一根。此时,touches 中有三个触摸点,targetTouches 中有两个触摸点,changeTouches 中有两个触摸点。
    《四》移动端事件_第2张图片
    其他手指不懂,中间那根手指向右滑动了一下。此时,touches 中有三个触摸点,targetTouches 中有两个触摸点,changeTouches 中有一个触摸点,就是滑动了的那根手机的触摸点。

触摸点的常用属性:

组成 touches、targetTouches、changeTouches 类数组的 touch 对象就是触摸点。

// 单个触摸点
console.log(event.changeTouches[0])
  1. identifier:触摸点的 id,唯一标识符。一般多指触摸时有用。
  2. target:目标元素。
  3. screenX、screenY:相对于屏幕左上角的坐标。
  4. clientX、clientY:相对于可视区域左上角的坐标。
  5. pageX、pageY:相对于页面左上角的坐标。

    client 的坐标是不包括滚动条的;page 的坐标是包括滚动条的。

实现单指拖拽:

.box {
	width: 200px;
	height: 200px;
	background-color: red;
}
const drag = $el => { const startPoint = {} const movePoint = {} const currPos = { x: 0, y: 0, } const touchStartHanlder = e => { e.preventDefault() const touch = e.changedTouches[0] startPoint.x = touch.pageX startPoint.y = touch.pageY } const touchMoveHanlder = e => { const touch = e.changedTouches[0] movePoint.x = currPos.x + touch.pageX - startPoint.x movePoint.y = currPos.y + touch.pageY - startPoint.y $el.style.transform = `translate3d(${movePoint.x}px, ${movePoint.y}px, 0)` } const touchEndHanlder = () => { currPos.x = movePoint.x currPos.y = movePoint.y } // touch 事件是有内定顺序的,只有触发了 touchstart 之后,才会有 touchmove,,然后才会有 touchend 或者 touchcancel,所以可以并排写 $el.addEventListener('touchstart', touchStartHanlder, false) $el.addEventListener('touchmove', touchMoveHanlder, false) $el.addEventListener('touchend', touchEndHanlder, false) $el.addEventListener('touchcancel', touchEndHanlder, false) } drag(document.getElementById('box'))

Pointer 指针事件:

Pointer 指针事件是由微软推出的,统一了鼠标、手指触摸和笔的事件。

特征检测:

判断浏览器是否支持 Pointer 指针事件。

if ('onpointerdown' in window) {
	console.log('支持')
}

事件类型:

Pointer 指针事件直接继承了鼠标事件,在鼠标事件的基础上又添加了一些其他内容,处理 Pointer 指针事件和处理鼠标事件几乎一致。

  1. pointerdown:指针按下时触发。
  2. pointermove:指针移动时触发。
  3. pointerup:指针松开时触发。
  4. pointercancel:指针中断时触发。
  5. pointerenter:指针进入目标元素及其后代元素区域时触发。
  6. pointerleave:指针离开目标元素及其后代元素区域时触发。
  7. pointerover:指针进入目标元素区域时触发。
  8. pointerout:指针离开目标元素区域时触发。

    由于pointerover、pointerout 支持事件冒泡,pointerenter、pointerleave 不支持事件冒泡,因此在子元素上进入或离开的时候会触发其父元素的 pointerover、pointerout事件,但是却不会触发 pointerenter、pointerleave 事件。

事件对象 Event:

const box = document.getElementById('box')
box.addEventListener('pointerdown', (event) => {
	console.log(event)
})
  1. type:事件类型。
  2. pointerType:指针类型(手指触摸/鼠标/笔等)。
  3. target:目标元素。
  4. pointerId:指针 id,唯一标识符。
  5. screenX、screenY:相对于屏幕左上角的坐标。
  6. clientX、clientY:相对于可视区域左上角的坐标。
  7. pageX、pageY:相对于页面左上角的坐标。

实现单指拖拽:

.box {
	width: 200px;
	height: 200px;
	background-color: red;
}
const drag = $el => { const startPoint = {} const movePoint = {} const currPos = { x: 0, y: 0, } const pointerMoveHanlder = e => { movePoint.x = currPos.x + e.pageX - startPoint.x movePoint.y = currPos.y + e.pageY - startPoint.y $el.style.transform = `translate3d(${movePoint.x}px, ${movePoint.y}px, 0)` } const pointerUpHanlder = () => { currPos.x = movePoint.x currPos.y = movePoint.y document.removeEventListener('pointermove', pointerMoveHanlder, false) document.removeEventListener('pointerup', pointerUpHanlder, false) document.removeEventListener('pointercancel', pointerUpHanlder, false) } // PC 端鼠标不按下去也会触发 pointermove,所以必须在 pointerdown 的事件处理函数中进行绑定,也就是必须先按下鼠标,才执行拖动、释放等方法 const pointerDownHanlder = e => { startPoint.x = e.pageX startPoint.y = e.pageY // 拖拽之后,元素移动到新的位置,这之间是有时间差的,就会导致触摸点移出目标元素,触摸点移出目标元素后,pointermove 不会再触发,因此,需要将事件处理函数绑定在 document 上 document.addEventListener('pointermove', pointerMoveHanlder, false) document.addEventListener('pointerup', pointerUpHanlder, false) document.addEventListener('pointercancel', pointerUpHanlder, false) } $el.addEventListener('pointerdown', pointerDownHanlder, false) // 不加这行代码来阻止移动端的默认事件,移动端将无法拖拽 $el.addEventListener('touchstart', e => {e.preventDefault()}, false) } drag(document.getElementById('box'))

Touch 触摸事件、Pointer 指针事件、mouse 鼠标事件的区别:

如果同时绑定了 touch、pointer、mouse、click 的事件,前三种哪个先触发是不确定的,不同浏览器不同,但是 click 总是最后触发的。

触发设备不同:

Touch 触摸事件只会在移动端触发,不会在 PC 端触发。

Pointer 指针事件、鼠标事件(mouseover、click 等)在移动端和 PC 端都会触发。

touchmove、pointermove 和 mousemove 有区别:

  1. 触摸点移出目标元素,touchmove 依然会持续触发,pointermove 和 mousemove 不会再触发。
  2. touchmove 在移动端没有按下之前不会触发。
    pointermove 在移动端没有按下之前不会触发;在 PC 端没有按下之前也会触发。
    mousemove 在 PC 端没有按下之前也会触发。

阻止浏览器的默认行为不同。

  1. Touch 触摸事件中,在 touchstart 和 touchend 中添加 event.preventDefault) 将会阻止鼠标事件(mouseover、click 等)的触发;在 touchmove 中不会阻止。
  2. Pointer 指针事件中:
    在移动端和 PC 端,在 pointerdown 中添加 event.preventDefault) 将会阻止 mouse 类事件的触发,不会阻止 click 的触发;在 pointerup 和 pointermove 中全都不会阻止。
    在 PC 端,在 pointerdown 中添加 event.preventDefault) 将会阻止图片默认的拖动行为;在 pointerup 和 pointermove 中全都不会阻止。

touch-action

touch-action:写在 CSS 中,用于设置移动端触摸操作时浏览器的行为。这个属性用来取消浏览器默认的手势行为。

浏览器默认行为:许多事件会自动触发浏览器执行某些行为。例如:

  1. 点击一个链接,将会触发导航到该 URL。
  2. 点击表单的提交按钮,将会触发提交表单到服务器。
  3. 滚动鼠标滚轮,将会触发滚动条滚动。
  4. 在文本上按下鼠标按钮并移动,将会触发选中文本。
  5. 点击鼠标右键,将会触发弹出右键菜单。
  6. 在图片上按下鼠标按钮并拖动,将会触发图片的拖动。

属性值:

支持某方向上的拖拽,是指按下去后在那个可拖动方向的执行的拖拽。

  1. auto:默认值。完全由浏览器自己决定。

  2. none:禁止默认的拖拽行为。

  3. manipulation:只允许进行滚动和持续缩放,禁止双击缩放。

    这个设置可以完美解决移动端 click 事件 300ms 延时的问题。

  4. pan-x:仅支持横向的默认拖拽行为(禁止纵向的默认拖拽行为)。

  5. pan-y:仅支持纵向的默认拖拽行为(禁止横向的默认拖拽行为)。

  6. pan-up:仅支持从上往下的默认拖拽行为(禁止从下往上、横向的默认拖拽行为)。
    《四》移动端事件_第3张图片

  7. pan-down:仅支持从下往上的默认拖拽行为(禁止从上往下、横向的默认拖拽行为)。

  8. pan-left:仅支持从左往右的默认拖拽行为(禁止从右往左、纵向的默认拖拽行为)。

  9. pan-right:仅支持从右往左的默认拖拽行为(禁止从左往右、纵向的默认拖拽行为)。

.box {
	touch-action: manipulation;
}

你可能感兴趣的:(移动端,移动端)