佛山網(wǎng)頁制作設(shè)計廣州seo軟件
文章目錄
- 基本概念
- 事件類型
- 事件對象的屬性
- touch事件封裝
- 單擊,雙擊
- 滑動方向(上下左右)
- 距離
- 角度
- 縮放
- 旋轉(zhuǎn)
- 常用功能封裝
- 滑動圖片瀏覽
- 實現(xiàn)拖拽操作
- 游戲角色移動、跳躍
- 封裝手寫板功能
在現(xiàn)代Web開發(fā)中,移動設(shè)備的普及使得觸摸屏交互成為了一個重要的方面。
JavaScript中的Touch
事件為開發(fā)者提供了處理觸摸屏輸入的能力,從而實現(xiàn)更豐富的用戶體驗。
本文將深入探討JavaScript中的Touch事件,涵蓋基本概念、事件類型、事件屬性以及實際應(yīng)用。
基本概念
首先,要注意touch事件是在移動設(shè)備上使用的,如智能手機(jī)和平板電腦,以及支持觸摸的筆記本電腦。
Touch
事件是指移動設(shè)備上用戶通過觸摸屏幕進(jìn)行交互所觸發(fā)的事件。這些事件包括觸摸開始、移動、結(jié)束以及取消等。
通過監(jiān)聽這些事件,開發(fā)者可以捕捉并處理觸摸交互的細(xì)節(jié)。它允許捕捉用戶在觸摸設(shè)備上的操作,例如點擊、滑動、縮放等。
事件類型
-
touchstart:當(dāng)用戶開始觸摸屏幕時觸發(fā),標(biāo)識觸摸操作的開始。
-
touchmove:在用戶觸摸屏幕后,隨著手指的移動持續(xù)觸發(fā),表示手指在屏幕上的滑動操作。
-
touchend:當(dāng)用戶從屏幕上移開手指時觸發(fā),表示觸摸操作的結(jié)束。
-
touchcancel:在某些情況下(如系統(tǒng)級的中斷),觸摸操作可能被取消,此時會觸發(fā)這個事件。
事件對象的屬性
每個touch事件都有一個事件對象,其中包含關(guān)于觸摸的各種信息。以下是一些常見的事件對象屬性:
-
touches:一個包含所有當(dāng)前處于活動狀態(tài)的觸摸點的列表,是一個Touch對象數(shù)組。
-
targetTouches:一個包含當(dāng)前事件目標(biāo)上的所有觸摸點的列表,是一個Touch對象數(shù)組。
-
changedTouches:一個包含最近發(fā)生變化的觸摸的列表(比如在touchstart中,它只會包含一個新的觸摸,而在touchmove和touchend中,它會包含有變化的觸摸),無論它們是否位于當(dāng)前事件目標(biāo)元素上。也是一個Touch對象數(shù)組。
每個Touch
對象都有一些屬性,如:
- identifier:觸摸點的唯一標(biāo)識符。一次觸摸動作(我們指的是手指的觸摸)在平 面上移動的整個過程中,該標(biāo)識符不變。
- target:與觸摸點關(guān)聯(lián)的DOM元素。
- clientX 和 clientY:觸摸點相對于瀏覽器窗口的坐標(biāo)。
- pageX 和 pageY:觸摸點相對于整個頁面的坐標(biāo)。
- screenX 和 screenY:觸摸點相對于屏幕的坐標(biāo)。
下面是一個簡單的代碼示例,演示如何使用touch事件來處理觸摸操作
// 獲取元素
const touchElement = document.getElementById('touch-element');// 添加事件監(jiān)聽器
touchElement.addEventListener('touchstart', handleTouchStart);
touchElement.addEventListener('touchmove', handleTouchMove);
touchElement.addEventListener('touchend', handleTouchEnd);// 處理touchstart事件
function handleTouchStart(event) {event.preventDefault(); // 阻止默認(rèn)的觸摸行為const touch = event.touches[0]; // 獲取第一個觸摸點console.log('Touch started at:', touch.clientX, touch.clientY);
}// 處理touchmove事件
function handleTouchMove(event) {const touch = event.touches[0];console.log('Touch moved to:', touch.clientX, touch.clientY);
}// 處理touchend事件
function handleTouchEnd(event) {console.log('Touch ended');
}
在這個示例中,我們首先獲取一個DOM元素(在這里假設(shè)有一個id為touch-element的元素),然后為touchstart、touchmove和touchend事件添加了相應(yīng)的事件監(jiān)聽器。每個事件處理函數(shù)都會提取事件對象中的觸摸信息,并進(jìn)行適當(dāng)?shù)牟僮鳌?/p>
請注意,實際應(yīng)用中可能需要更復(fù)雜的邏輯來處理觸摸操作,例如跟蹤多個觸摸點、處理滑動手勢等。
總之,使用JavaScript中的touch事件,可以輕松地在移動設(shè)備上實現(xiàn)各種觸摸操作的響應(yīng)和處理。
touch事件封裝
單擊,雙擊
click事件在移動端300ms延遲問題:當(dāng)你click一次之后,會經(jīng)過300ms之后檢測是否再有一次click,如果有的話,就會縮放頁面,否則的話就是一個click事件。由此我們可以封裝h5端的單擊,雙擊事件。
// 獲取觸摸目標(biāo)元素
const touchElement = document.getElementById('your-element-id');let lastClickTime = 0;
let touchTimeout;// 觸摸事件處理函數(shù)
function handleTouch(event) {const currentTime = new Date().getTime();if (currentTime - lastClickTime < 300) { // 判斷兩次點擊的時間間隔clearTimeout(touchTimeout);// 處理雙擊事件console.log('Double click');} else {// 處理單擊事件touchTimeout = setTimeout(() => {console.log('Single click');}, 300);}lastClickTime = currentTime;
}// 為目標(biāo)元素綁定觸摸事件處理函數(shù)
touchElement.addEventListener('touchend', handleTouch);
在這個例子中,我們創(chuàng)建了一個handleTouch函數(shù)來處理觸摸事件。通過記錄上一次點擊的時間戳,我們可以計算兩次點擊之間的時間間隔,從而判斷是單擊還是雙擊事件。如果兩次點擊的時間間隔小于300毫秒,則認(rèn)為是雙擊,否則認(rèn)為是單擊。
滑動方向(上下左右)
距離
可以根據(jù)觸摸點的坐標(biāo)變化來判斷滑動的方向。
// 獲取觸摸目標(biāo)元素
const touchElement = document.getElementById('your-element-id');let startX = 0;
let startY = 0;// 觸摸事件處理函數(shù)
function handleTouchStart(event) {const touch = event.touches[0];startX = touch.clientX;startY = touch.clientY;
}function handleTouchEnd(event) {const touch = event.changedTouches[0];const deltaX = touch.clientX - startX;const deltaY = touch.clientY - startY;if (Math.abs(deltaX) > Math.abs(deltaY)) {if (deltaX > 0) {console.log('向右滑動');} else {console.log('向左滑動');}} else {if (deltaY > 0) {console.log('向下滑動');} else {console.log('向上滑動');}}
}// 為目標(biāo)元素綁定觸摸事件處理函數(shù)
touchElement.addEventListener('touchstart', handleTouchStart);
touchElement.addEventListener('touchend', handleTouchEnd);
在這個例子中,我們使用了touchstart事件來記錄滑動開始時的觸摸點坐標(biāo),然后在touchend事件中計算觸摸點的坐標(biāo)變化(即滑動的距離),并根據(jù)坐標(biāo)變化的方向來判斷滑動的方向(左右或上下)。
角度
-
坐標(biāo)系:
原點通常位于屏幕左上角(0, 0)。水平方向向右增加,垂直方向向下增加。與常規(guī)的數(shù)學(xué)坐標(biāo)系的垂直方向有差異。
-
Math.atan2(y,x)
函數(shù),計算角度的弧度值-
angel=Math.atan2(y,x)
-
x 指定點的 x 坐標(biāo),y 指定點的 y 坐標(biāo)
-
angel是一個弧度值(可以比喻為直角三角形對角的角,其中 x 是鄰邊邊長,而 y 是對邊邊長)
-
-
Math.atan2(y,x)*180/Math.PI
轉(zhuǎn)換為角度
// 獲取觸摸目標(biāo)元素
const touchElement = document.getElementById('your-element-id');let startX = 0;
let startY = 0;// 觸摸事件處理函數(shù)
function handleTouchStart(event) {const touch = event.touches[0];startX = touch.clientX;startY = touch.clientY;
}function handleTouchEnd(event) {const touch = event.changedTouches[0];const endX = touch.clientX;const endY = touch.clientY;const deltaX = endX - startX;const deltaY = endY - startY;// 計算滑動角度const angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);// 判斷滑動方向if (angle >= -45 && angle < 45) {console.log('向右滑動');} else if (angle >= 45 && angle < 135) {console.log('向下滑動');} else if (angle >= -135 && angle < -45) {console.log('向上滑動');} else {console.log('向左滑動');}
}// 為目標(biāo)元素綁定觸摸事件處理函數(shù)
touchElement.addEventListener('touchstart', handleTouchStart);
touchElement.addEventListener('touchend', handleTouchEnd);
使用Math.atan2
函數(shù)來計算滑動的角度,然后根據(jù)角度范圍來判斷滑動的方向。具體來說:
- 角度在 -45 到 45 度之間,判斷為向右滑動。
- 角度在 45 到 135 度之間,判斷為向下滑動。
- 角度在 -135 到 -45 度之間,判斷為向上滑動。
- 其他情況判斷為向左滑動。
縮放
// 獲取需要縮放的元素
const targetElement = document.getElementById('yourElementId');// 初始觸摸點間的距離和初始縮放比例
let initialDistance = 0;
let initialScale = 1;// 開始觸摸時的處理函數(shù)
function handleTouchStart(event) {const touches = event.touches;if (touches.length >= 2) {const dx = touches[0].clientX - touches[1].clientX;const dy = touches[0].clientY - touches[1].clientY;initialDistance = Math.sqrt(dx * dx + dy * dy);}
}// 觸摸移動時的處理函數(shù)
function handleTouchMove(event) {const touches = event.touches;if (touches.length >= 2) {const dx = touches[0].clientX - touches[1].clientX;const dy = touches[0].clientY - touches[1].clientY;const currentDistance = Math.sqrt(dx * dx + dy * dy);// 計算縮放比例const scale = currentDistance / initialDistance;// 應(yīng)用縮放targetElement.style.transform = `scale(${scale})`;}
}// 觸摸結(jié)束時的處理函數(shù)
function handleTouchEnd() {// 重置縮放targetElement.style.transform = 'scale(1)';
}// 添加觸摸事件監(jiān)聽器
targetElement.addEventListener('touchstart', handleTouchStart);
targetElement.addEventListener('touchmove', handleTouchMove);
targetElement.addEventListener('touchend', handleTouchEnd);
在這個示例中,我們定義了三個處理函數(shù)來處理不同的觸摸事件。
- handleTouchStart 函數(shù)在觸摸開始時獲取初始觸摸點間的距離和初始縮放比例。
- handleTouchMove 函數(shù)在觸摸移動時計算當(dāng)前觸摸點間的距離并應(yīng)用縮放。
- handleTouchEnd 函數(shù)在觸摸結(jié)束時重置縮放。然后,我們通過添加監(jiān)聽器將這些處理函數(shù)綁定到相應(yīng)的觸摸事件上。
旋轉(zhuǎn)
旋轉(zhuǎn)手勢通常涉及到兩個觸摸點的移動變化,類似于之前提到的縮放功能。
// 獲取需要旋轉(zhuǎn)的元素
const targetElement = document.getElementById('yourElementId');// 初始觸摸點的角度
let initialAngle = 0;// 開始觸摸時的處理函數(shù)
function handleTouchStart(event) {const touches = event.touches;if (touches.length >= 2) {const dx = touches[0].clientX - touches[1].clientX;const dy = touches[0].clientY - touches[1].clientY;initialAngle = Math.atan2(dy, dx);}
}// 觸摸移動時的處理函數(shù)
function handleTouchMove(event) {const touches = event.touches;if (touches.length >= 2) {const dx = touches[0].clientX - touches[1].clientX;const dy = touches[0].clientY - touches[1].clientY;const currentAngle = Math.atan2(dy, dx);// 計算旋轉(zhuǎn)角度const angleDelta = currentAngle - initialAngle;// 應(yīng)用旋轉(zhuǎn)targetElement.style.transform = `rotate(${angleDelta}rad)`;}
}// 觸摸結(jié)束時的處理函數(shù)
function handleTouchEnd() {// 重置旋轉(zhuǎn)targetElement.style.transform = 'rotate(0)';
}// 添加觸摸事件監(jiān)聽器
targetElement.addEventListener('touchstart', handleTouchStart);
targetElement.addEventListener('touchmove', handleTouchMove);
targetElement.addEventListener('touchend', handleTouchEnd);
在這個示例中,我們使用 Math.atan2 函數(shù)來計算觸摸點與 x 軸的夾角,從而得到旋轉(zhuǎn)角度。
- handleTouchStart 函數(shù)獲取初始觸摸點的角度,
- 而 handleTouchMove 函數(shù)計算當(dāng)前觸摸點的角度變化,并將其應(yīng)用于元素的旋轉(zhuǎn)變換。
- 最后,handleTouchEnd 函數(shù)用于重置旋轉(zhuǎn)效果。
常用功能封裝
滑動圖片瀏覽
假設(shè)有一個包含多張圖片的畫廊,希望用戶可以在移動設(shè)備上滑動瀏覽這些圖片。
HTML 結(jié)構(gòu):
<div id="gallery"><img src="image1.jpg" alt="Image 1"><img src="image2.jpg" alt="Image 2"><img src="image3.jpg" alt="Image 3">
</div>
CSS 樣式(簡化):
#gallery {display: flex;overflow: hidden;white-space: nowrap;
}#gallery img {width: 100%;height: auto;display: inline-block;
}
JavaScript 代碼:
const gallery = document.getElementById('gallery');
let startX = 0;
let scrolling = false;gallery.addEventListener('touchstart', handleTouchStart);
gallery.addEventListener('touchmove', handleTouchMove);
gallery.addEventListener('touchend', handleTouchEnd);function handleTouchStart(event) {if (event.touches.length === 1) {startX = event.touches[0].pageX;scrolling = true;}
}function handleTouchMove(event) {if (!scrolling) return;const touch = event.touches[0];const distanceX = touch.pageX - startX;gallery.scrollLeft -= distanceX;startX = touch.pageX;
}function handleTouchEnd() {scrolling = false;
}
在這個案例中,我們使用touch
事件來實現(xiàn)了一個簡單的圖片瀏覽器。用戶可以在畫廊中水平滑動以瀏覽不同的圖片。
- 在
touchstart
事件中,我們記錄了觸摸開始時的橫坐標(biāo),并設(shè)置了一個標(biāo)志來表示正在滑動。 - 在
touchmove
事件中,我們計算當(dāng)前觸摸點與上一個觸摸點之間的距離,并根據(jù)這個距離來調(diào)整畫廊的滾動位置,實現(xiàn)圖片的平滑滑動。 - 在
touchend
事件中,我們將滑動標(biāo)志設(shè)置為false
,表示滑動已經(jīng)結(jié)束。
請注意,這只是一個簡化的案例,實際中可能需要處理更多的細(xì)節(jié),例如邊界檢查、慣性滾動等。
實現(xiàn)拖拽操作
實現(xiàn)拖拽操作是touch
事件中的一個常見應(yīng)用。下面是一個簡單的示例,演示如何使用touch
事件來實現(xiàn)基本的拖拽操作。
const draggableElement = document.getElementById('draggable-element');
let initialX = 0;
let initialY = 0;
let distanceX = 0;
let distanceY = 0;
let isDragging = false;draggableElement.addEventListener('touchstart', handleTouchStart);
draggableElement.addEventListener('touchmove', handleTouchMove);
draggableElement.addEventListener('touchend', handleTouchEnd);function handleTouchStart(event) {isDragging = true;const touch = event.touches[0];initialX = touch.clientX - distanceX;initialY = touch.clientY - distanceY;
}function handleTouchMove(event) {if (!isDragging) return;const touch = event.touches[0];distanceX = touch.clientX - initialX;distanceY = touch.clientY - initialY;updateElementPosition();
}function handleTouchEnd() {isDragging = false;
}function updateElementPosition() {draggableElement.style.transform = `translate(${distanceX}px, ${distanceY}px)`;
}
在這個示例中,我們使用
touchstart
事件來記錄初始觸摸點的位置,touchmove
事件來更新元素的位置,touchend
事件來標(biāo)記拖拽結(jié)束。
當(dāng)用戶觸摸元素并滑動手指時,元素將會跟隨手指的移動而移動。注意,這只是一個簡單的示例,實際中可能需要更多的功能,如邊界限制、慣性效果等。
在這個基礎(chǔ)上,可以根據(jù)需要添加更多的交互特性,例如限制拖拽范圍、添加釋放動畫等,以實現(xiàn)更好的用戶體驗。
游戲角色移動、跳躍
使用touch
事件來實現(xiàn)角色的移動、跳躍等動作可以為移動端游戲提供交互性。以下是一個示例,展示如何使用touch
事件來控制角色的移動和跳躍動作。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Touch Control Example</title><style>body {margin: 0;overflow: hidden;}#character {width: 50px;height: 50px;background-color: blue;position: absolute;}</style>
</head>
<body><div id="character"></div><script>const character = document.getElementById('character');let characterX = 0;let characterY = 0;let isJumping = false;document.addEventListener('touchstart', handleTouchStart);document.addEventListener('touchend', handleTouchEnd);function handleTouchStart(event) {const touchX = event.touches[0].clientX;const touchY = event.touches[0].clientY;if (touchX < window.innerWidth / 2) {moveLeft();} else {moveRight();}}function handleTouchEnd() {if (!isJumping) {jump();}}function moveLeft() {characterX -= 10;updateCharacterPosition();}function moveRight() {characterX += 10;updateCharacterPosition();}function jump() {isJumping = true;characterY -= 100;updateCharacterPosition();setTimeout(() => {characterY += 100;updateCharacterPosition();isJumping = false;}, 1000);}function updateCharacterPosition() {character.style.left = characterX + 'px';character.style.top = characterY + 'px';}</script>
</body>
</html>
在這個示例中,我們創(chuàng)建了一個簡單的角色元素,當(dāng)觸摸屏幕左半部分時,角色向左移動;觸摸屏幕右半部分時,角色向右移動;觸摸屏幕時角色跳躍。請注意,這只是一個基礎(chǔ)示例,實際中可能需要更多的邏輯和交互細(xì)節(jié)。
可以根據(jù)的需求擴(kuò)展此示例,例如添加更多的控制選項、調(diào)整角色移動速度、添加背景、碰撞檢測等。這個示例提供了一個基本的框架,可以根據(jù)游戲的需求進(jìn)行定制和擴(kuò)展。
封裝手寫板功能
當(dāng)希望實現(xiàn)一個能夠應(yīng)對復(fù)雜情況的手寫板時,可能需要添加更多的功能和交互細(xì)節(jié)。以下是一個更完整的手寫板案例,其中包括不同畫筆樣式、顏色選擇、清除畫布、保存圖像等功能。
HTML 結(jié)構(gòu):
<canvas id="canvas" width="600" height="400"></canvas>
<div id="controls"><button id="clear-button">Clear</button><input type="color" id="color-picker" value="#000000"><select id="brush-size"><option value="2">Thin</option><option value="5" selected>Medium</option><option value="10">Thick</option></select>
</div>
CSS 樣式(可選):
#canvas {border: 1px solid black;
}#controls {margin-top: 10px;
}
JavaScript 代碼:
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let isDrawing = false;function updateCanvasSize() {canvas.width = window.innerWidth;canvas.height = window.innerHeight;
}window.addEventListener('resize', updateCanvasSize);
updateCanvasSize();canvas.addEventListener('touchstart', startDrawing);
canvas.addEventListener('touchmove', draw);
canvas.addEventListener('touchend', stopDrawing);function startDrawing(event) {isDrawing = true;const touch = event.touches[0];const x = touch.pageX - canvas.offsetLeft;const y = touch.pageY - canvas.offsetTop;ctx.beginPath();ctx.moveTo(x, y);
}function draw(event) {if (!isDrawing) return;const touch = event.touches[0];const x = touch.pageX - canvas.offsetLeft;const y = touch.pageY - canvas.offsetTop;const brushSize = parseInt(document.getElementById('brush-size').value);const color = document.getElementById('color-picker').value;ctx.lineWidth = brushSize;ctx.strokeStyle = color;ctx.lineTo(x, y);ctx.stroke();
}function stopDrawing() {isDrawing = false;ctx.closePath();
}// 清除畫布按鈕
const clearButton = document.getElementById('clear-button');
clearButton.addEventListener('click', clearCanvas);function clearCanvas() {ctx.clearRect(0, 0, canvas.width, canvas.height);
}// 保存圖像按鈕
const saveButton = document.getElementById('save-button');
saveButton.addEventListener('click', saveCanvas);function saveCanvas() {const image = canvas.toDataURL('image/png');const link = document.createElement('a');link.href = image;link.download = 'drawing.png';link.click();
}
在這個手寫板案例中,我們添加了如下:
- 畫筆顏色和粗細(xì)的選擇
- 清除畫布功能
- 保存繪制圖像功能
- 窗口大小調(diào)整的事件監(jiān)聽器
通過在顏色選擇器、畫筆粗細(xì)選擇器和按鈕上添加事件監(jiān)聽器,我們可以實現(xiàn)更靈活的繪圖操作。用戶可以根據(jù)需求選擇畫筆顏色、粗細(xì),清除畫布,以及將繪制結(jié)果保存為圖像文件。通過在窗口大小發(fā)生變化時重新設(shè)置畫布的寬度和高度,我們可以避免屏幕旋轉(zhuǎn)帶來的繪制問題。