JavaScript 中常見的鼠標事件及應用
在 JavaScript 中,鼠標事件是用戶與網頁進行交互的重要方式,通過監聽這些事件,開發者可以實現各種交互效果,如點擊、懸停、拖動等。
在 JavaScript 中,鼠標事件類型多樣,下面為你詳細介紹常見的鼠標事件類型及應用:
一. 基礎交互事件
1.?click
觸發時機:
當用戶在元素上按下并釋放鼠標主按鈕(通常是左鍵)時觸發。
應用場景:
常用于處理按鈕點擊、鏈接跳轉、表單提交等操作。
示例代碼:
<!DOCTYPE html>
<html lang="en">
<body><button id="myButton">點擊我</button><script>const button = document.getElementById('myButton');button.addEventListener('click', function () {alert('按鈕被點擊了!');});</script>
</body>
</html>
2.?dblclick
觸發時機:
當用戶在短時間內快速連續點擊兩次鼠標主按鈕時觸發。
應用場景:
可用于實現雙擊放大圖片、編輯文本等功能。
示例代碼:
<!DOCTYPE html>
<html lang="zh-CN">
<head><style>#myDiv {width: 200px;height: 200px;background-color: lightblue; /* 初始背景顏色 */display: flex; /* 使用flex布局 */justify-content: center; /* 水平居中 */align-items: center; /* 垂直居中 */font-size: 30px;font-weight: bold;}</style>
</head>
<body><h1>雙擊鼠標事件,改變顏色</h1><div id="myDiv">雙擊我,<br>改變顏色</div><script>const div = document.getElementById('myDiv');// 顏色數組const color = ['lightblue', 'pink', 'lightgreen', 'lightyellow', 'lightgray']; // 初始化計數器為-1,以便第一次雙擊時顏色數組從索引0開始變化let dblcount = -1; // 添加雙擊事件監聽器div.addEventListener('dblclick', function () {dblcount++;// 循環改變背景顏色this.style.backgroundColor = color[dblcount % color.length]; });</script>
</body>
</html>
二、按鈕狀態事件
3.?mousedown
觸發時機:
當用戶在元素上按下任意鼠標按鈕時觸發。
應用場景:
常用于實現拖動元素、繪制圖形等操作的起始點。
示例代碼:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Untitled-1</title>
</head>
<body><h1>鼠標事件-按下</h1><div id="draggable" style="width:100px;height:100px;background-color:red;">拖動我</div><script>const draggable = document.getElementById('draggable');draggable.addEventListener('mousedown', function () {console.log('鼠標按下');draggable.style.backgroundColor = 'blue';});</script>
</body>
</html>
4.?mouseup
觸發時機:
- 當用戶在元素上釋放之前按下的鼠標按鈕時觸發。
應用場景:
- 通常與?
mousedown
?事件配合使用,用于完成拖動、繪制等操作。
示例代碼:
<!DOCTYPE html>
<html lang="en">
<body><div id="drawArea" style="width: 200px; height: 200px; border: 1px solid black;"></div><script>const drawArea = document.getElementById('drawArea');drawArea.addEventListener('mousedown', function () {console.log('鼠標按下');drawArea.style.backgroundColor = 'blue';});drawArea.addEventListener('mouseup', function () {console.log('鼠標釋放');drawArea.style.backgroundColor = 'red';});</script>
</body>
</html>
此代碼的主要功能是通過監聽鼠標在指定div
上的按下和釋放事件,實現div
背景顏色的變化。具體來說:
- 當用戶點擊
div
時,div
的背景顏色會變為藍色,同時在控制臺輸出“鼠標按下”。 - 當用戶松開鼠標時,
div
的背景顏色會變為紅色,同時在控制臺輸出“鼠標釋放”。
這段代碼主要用于演示如何使用JavaScript的事件監聽機制來響應用戶的鼠標操作,并實時更新網頁元素的樣式。
三、鼠標移動事件
5.?mousemove
觸發時機:
- 當鼠標指針在元素上移動時,會持續觸發該事件。
應用場景:
- 常用于實現鼠標跟隨效果、繪制軌跡、實時更新鼠標位置信息等。
示例代碼:
<!DOCTYPE html>
<html lang="en">
<body><div id="moveArea" style="width: 200px; height: 200px; border: 1px solid black;"></div><p>請在黑色區域內移動鼠標,并查看下面的鼠標位置。</p><p>鼠標位置: (0, 0)</p><script>const moveArea = document.getElementById('moveArea');moveArea.addEventListener('mousemove', function (event) {console.log(`鼠標位置: (${event.offsetX}, ${event.offsetY})`);// 使用querySelector選擇頁面中最后一個<p>標簽,并將其文本內容更新為當前鼠標的位置。document.querySelector('p:last-of-type').textContent = `鼠標位置: (${event.offsetX}, ${event.offsetY})`;});</script>
</body>
</html>
這段代碼的主要功能是在網頁上創建一個200x200像素的黑色邊框區域,并實時顯示用戶在這個區域內的鼠標位置。每當鼠標在該區域內移動時,位置信息會被更新到頁面上的最后一個段落標簽中,并且在控制臺中輸出。
6.?mouseover
、mouseout
觸發時機:
mouseover
當鼠標指針從元素外部移動到元素內部時觸發,并且當鼠標進入該元素的子元素時也會觸發。mouseout
當鼠標指針從元素內部移動到元素外部時觸發,并且當鼠標離開該元素的子元素時也會觸發。
應用場景:
mouseover
常用于實現鼠標懸停效果,如顯示下拉菜單、改變元素樣式等。mouseout
通常與?mouseover
?事件配合,用于恢復元素的原始樣式。
示例代碼:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>鼠標懸停切換類</title><style>/* 設置div的基本樣式 */div {position: relative;display: inline-block;place-content: center;text-align: center;font-size: 20px;color: white;cursor: pointer;}/* 定義原始樣式 */.original {width: 180px;height: 180px;background-color: lightgray;}/* 定義懸停時的樣式 */.hovered {width: 180px;height: 180px;background-color: pink;border: 2px solid black;}</style>
</head>
<body><!-- 創建一個div元素,初始應用original樣式 --><div id="element" class="original">懸停切換樣式</div><script>// 獲取id為element的div元素const element = document.getElementById('element');// 添加鼠標懸停事件監聽器,切換到hovered樣式element.addEventListener('mouseover', function () {this.classList.remove('original');this.classList.add('hovered');});// 添加鼠標移出事件監聽器,切換回original樣式element.addEventListener('mouseout', function () {this.classList.remove('hovered');this.classList.add('original');});</script>
</body>
</html>
這段代碼的主要功能是在網頁上實現一個簡單的鼠標懸停效果。當用戶將鼠標懸停在特定的div
元素上時,該元素的背景顏色會從淺灰色變為粉色,并且增加一個黑色邊框。當鼠標移開時,div
元素的樣式會恢復到原來的淺灰色背景無邊框狀態。這是一種常見的交互設計,用于提高用戶體驗,通過視覺反饋來告知用戶他們與頁面元素的交互狀態。
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>懸停下拉菜單示例</title><style>.menu {list-style-type: none;margin: 0;padding: 0;}.menu-item {position: relative;display: inline-block;}.menu-item a {display: block;padding: 10px;color: #fff;background-color: #007BFF;text-decoration: none;}.submenu {display: none;position: absolute;top: 100%;left: 0;background-color: #007BFF;list-style-type: none;margin: 0;padding: 0;box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);}.submenu li {width: 200px;}.submenu li a {padding: 12px 16px;text-decoration: none;display: block;color: white;}.submenu li a:hover {background-color: #555;}</style>
</head>
<body><ul class="menu"><li class="menu-item"><a href="#">菜單項1</a><ul class="submenu"><li><a href="#">子菜單項1-1</a></li><li><a href="#">子菜單項1-2</a></li><li><a href="#">子菜單項1-3</a></li></ul></li><li class="menu-item"><a href="#">菜單項2</a><ul class="submenu"><li><a href="#">子菜單項2-1</a></li><li><a href="#">子菜單項2-2</a></li><li><a href="#">子菜單項2-3</a></li></ul></li></ul><script>document.addEventListener('DOMContentLoaded', function () {const menuItems = document.querySelectorAll('.menu-item');menuItems.forEach(function (item) {item.addEventListener('mouseover', function () {const submenu = this.querySelector('.submenu');if (submenu) {submenu.style.display = 'block';}});item.addEventListener('mouseout', function () {const submenu = this.querySelector('.submenu');if (submenu) {submenu.style.display = 'none';}});});});</script>
</body>
</html>
下面是對 javascript 代碼的逐步分解:
-
document.addEventListener('DOMContentLoaded', function () { ... });
- 這行代碼的作用是監聽整個文檔是否已經完全加載完畢。只有在文檔加載完成后,腳本中的內容才會被執行,確保在操作DOM元素時這些元素已經存在。
-
const menuItems = document.querySelectorAll('.menu-item');
- 使用
querySelectorAll
方法選擇所有帶有menu-item
類名的元素,并將它們存儲在一個NodeList對象menuItems
中。在這個例子中,menuItems
包含了兩個菜單項,即“菜單項1”和“菜單項2”。
- 使用
-
menuItems.forEach(function (item) { ... });
- 對于NodeList中的每一個元素(即每個菜單項),執行一次回調函數。回調函數中的參數
item
代表當前正在處理的菜單項。
- 對于NodeList中的每一個元素(即每個菜單項),執行一次回調函數。回調函數中的參數
-
item.addEventListener('mouseover', function () { ... });
- 為每個菜單項添加一個
mouseover
事件監聽器。當鼠標進入菜單項時,會觸發回調函數中的代碼。
- 為每個菜單項添加一個
-
const submenu = this.querySelector('.submenu');
- 在
mouseover
事件的回調函數中,this
指向觸發事件的菜單項。通過querySelector
方法,我們在這個菜單項內部查找第一個帶有submenu
類名的元素,即子菜單。
- 在
-
if (submenu) { submenu.style.display = 'block'; }
- 如果找到了子菜單(即
submenu
不為null),則將它的display
屬性設置為’block’,使子菜單顯示出來。
- 如果找到了子菜單(即
-
item.addEventListener('mouseout', function () { ... });
- 為每個菜單項添加一個
mouseout
事件監聽器。當鼠標離開菜單項時,會觸發回調函數中的代碼。
- 為每個菜單項添加一個
-
if (submenu) { submenu.style.display = 'none'; }
- 同樣地,在
mouseout
事件的回調函數中,如果找到了子菜單,則將其display
屬性設置為’none’,使子菜單隱藏起來。
- 同樣地,在
7.?mouseenter
、mouseleave
觸發時機:
mouseenter
當鼠標指針從元素外部移動到元素內部時觸發,但當鼠標進入該元素的子元素時不會再次觸發。mouseleave
當鼠標指針從元素內部移動到元素外部時觸發,但當鼠標離開該元素的子元素時不會觸發。
應用場景:
mouseenter
與?mouseover
?類似,但不會受子元素影響,適合需要精確控制懸停范圍的場景。mouseleave
與?mouseout
?類似,但不會受子元素影響,常與?mouseenter
?配合使用。
示例代碼:
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>mouseenter 事件示例</title><style>.tooltip {display: none;position: absolute;background-color: #007BFF;color: white;padding: 5px 10px;border-radius: 5px;font-size: 12px;}.button-container {position: relative;display: inline-block;}</style>
</head>
<body><div class="button-container"><button id="myButton">懸停我</button><div class="tooltip" id="myTooltip">這是一個提示信息</div></div><script>document.addEventListener('DOMContentLoaded', function () {const button = document.getElementById('myButton');const tooltip = document.getElementById('myTooltip');button.addEventListener('mouseenter', function () {// 顯示提示框tooltip.style.display = 'block';// 獲取按鈕的位置,并設置提示框的位置const buttonRect = button.getBoundingClientRect();tooltip.style.top = `${buttonRect.bottom + window.scrollY}px`;tooltip.style.left = `${buttonRect.left + window.scrollX}px`;});button.addEventListener('mouseleave', function () {// 隱藏提示框tooltip.style.display = 'none';});});</script>
</body>
</html>
mouseenter
?事件與?mouseover
?事件的主要區別在于,mouseenter
?不會冒泡到其子元素上,而?mouseover
?會。這意味著當鼠標進入一個元素時,mouseenter
?只會觸發一次,而?mouseover
?可能在鼠標進入子元素時再次觸發。
mouseenter
?事件最適合用于需要精確控制事件只在特定元素上觸發的場景,而不需要考慮子元素的情況。例如,當你想要在鼠標進入某個按鈕時顯示一個提示,但不希望在子元素上重復顯示這個提示時,可以使用?mouseenter
。
在上面的示例中,我們創建了一個按鈕和一個提示框。當鼠標進入按鈕區域時,使用?mouseenter
事件來顯示提示框,并根據按鈕的位置動態設置提示框的位置,確保提示框顯示在按鈕下方。當鼠標離開按鈕區域時,使用?mouseleave
?事件來隱藏提示框。
這里使用?mouseenter
?和?mouseleave
?事件而不是?mouseover
?和?mouseout
?事件,是為了避免當鼠標移動到按鈕的子元素(如果有)時,提示框被重復顯示或隱藏。在這個簡單的例子中,按鈕沒有子元素,但如果有更復雜的結構,mouseenter
?和?mouseleave
?的非冒泡特性會更顯優勢。
四、鼠標滾輪事件
8.?wheel
觸發時機:
- 當用戶滾動鼠標滾輪時觸發。
應用場景:
- 常用于實現頁面滾動、縮放元素、切換幻燈片等功能。
示例代碼:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>滾輪事件示例</title><style>body {height: 2000px; /* 為了能看到滾動效果 */}</style>
</head>
<body>
<script>// 獲取body元素var body = document.body;// 添加滾輪事件監聽器body.addEventListener('wheel', function(event) {// 阻止默認行為event.preventDefault();// 判斷滾輪滾動的方向if (event.deltaY > 0) {console.log(event.deltaY);console.log('向下滾動');} else {console.log('向上滾動');}});
</script>
</body>
</html>
這段代碼的主要功能是在網頁的<body>
元素上添加一個滾輪事件監聽器,用于檢測用戶鼠標滾輪的滾動方向,并在控制臺中輸出滾動方向的信息。需要注意的是,這段代碼還阻止了頁面的默認滾動行為,因此即使用戶嘗試滾動鼠標滾輪,頁面也不會發生自動的上下滾動。
五、鼠標右鍵事件
9.?contextmenu
觸發時機:
- 當用戶在元素上點擊鼠標右鍵時觸發。
應用場景:
- 可用于自定義上下文菜單,替代瀏覽器默認的右鍵菜單。
示例代碼:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>右擊事件示例</title><style>body {height: 2000px;/* 為了能看到滾動效果 */position: relative;}#customMenu {display: none;position: absolute;background-color: #f9f9f9;border: 1px solid #d3d3d3;box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);padding: 5px 0;width: 150px;z-index: 1000;}#customMenu div {padding: 8px 15px;cursor: pointer;}#customMenu div:hover {background-color: #ddd;}</style>
</head>
<body><div id="customMenu"><div onclick="showAlert('選項1')">選項1</div><div onclick="showAlert('選項2')">選項2</div><div onclick="showAlert('選項3')">選項3</div></div><script>// 獲取body元素,以便在頁面上添加事件監聽器var body = document.body;// 獲取自定義菜單元素,該元素在用戶右擊時顯示var customMenu = document.getElementById('customMenu');// 添加右擊事件監聽器body.addEventListener('contextmenu', function (event) {// 阻止默認行為(顯示瀏覽器的上下文菜單)event.preventDefault();// 設置自定義菜單的位置為鼠標點擊的位置customMenu.style.left = event.pageX + 'px';customMenu.style.top = event.pageY + 'px';// 顯示自定義菜單customMenu.style.display = 'block';});// 添加點擊頁面其他地方隱藏菜單的事件監聽器document.addEventListener('click', function (event) {if (event.target !== customMenu) {customMenu.style.display = 'none';}});// 顯示彈窗的函數,用于測試菜單選項function showAlert(option) {alert('你點擊了:' + option);}</script>
</body>
</html>
六、事件對象
在上述示例中,事件處理函數通常會接收一個事件對象作為參數(如 event
)。通過這個事件對象,可以獲取與鼠標事件相關的信息,如鼠標的坐標、按下的按鈕等。常見的屬性包括:
-
clientX
和clientY
:鼠標相對于瀏覽器窗口可視區域的坐標。 -
offsetX
和offsetY
:鼠標相對于觸發事件的元素的坐標。 -
button
:表示按下的鼠標按鈕,0 代表左鍵,1 代表中鍵,2 代表右鍵。
這些鼠標事件為開發者提供了豐富的交互手段,可以根據具體需求靈活運用,打造出更加生動和交互性強的網頁。