最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

前端JavaScript編寫鼠標事件的完整指南

 更新時間:2026年05月30日 09:14:03   作者:detayun  
鼠標事件是Web交互的基礎,點擊、拖拽、滾輪、懸停幾乎所有操作都離不開它,本文從基礎到實戰(zhàn),講清楚每個事件怎么用,什么時候用,有哪些坑

鼠標事件是Web交互的基礎。點擊、拖拽、滾輪、懸停……幾乎所有操作都離不開它。

但很多人只會寫 onclick,其實鼠標事件遠不止這些。本文從基礎到實戰(zhàn),講清楚每個事件怎么用、什么時候用、有哪些坑。

一、八個核心事件對比

事件觸發(fā)時機典型用途
click完整點擊(按下+松開)按鈕、鏈接、提交
dblclick雙擊打開文件、編輯文本
mousedown鼠標按下瞬間拖拽開始、按住觸發(fā)
mouseup鼠標松開瞬間拖拽結束
mousemove鼠標移動實時跟蹤位置、繪圖
mouseenter鼠標進入元素懸停顯示提示
mouseleave鼠標離開元素隱藏提示
wheel滾輪滾動切換圖片、縮放
contextmenu右鍵點擊自定義右鍵菜單

最常用的四個:click、mousedown、mousemove、wheel

二、基礎寫法

// 方式1:addEventListener(推薦)
document.getElementById('btn').addEventListener('click', function(e) {
    console.log('點擊了');
});
// 方式2:on事件屬性(簡單場景可用)
<button onclick="alert('點擊了')">點我</button>
// 方式3:內(nèi)聯(lián)事件(不推薦,維護性差)
<div onmouseover="this.style.background='red'">懸停變紅</div>

結論:優(yōu)先用 addEventListener,可以綁定多個事件,也方便解綁。

三、事件對象e里有什么

element.addEventListener('click', function(e) {
    console.log(e.clientX, e.clientY);  // 鼠標相對于視口的坐標
    console.log(e.pageX, e.pageY);      // 鼠標相對于文檔的坐標
    console.log(e.target);              // 觸發(fā)事件的元素
    console.log(e.button);              // 哪個鍵:0左鍵,1中鍵,2右鍵
});

clientX/Y vs pageX/Y 怎么選?

  • clientX/Y → 相對于瀏覽器窗口,不受滾動影響
  • pageX/Y → 相對于整個文檔,包含滾動距離

做拖拽、定位,用 clientX/Y 更方便。

四、實戰(zhàn):驗證碼識別頁面的鼠標交互

場景1:拖拽滑塊旋轉圖片

這是我們項目中的核心交互——按住滑塊左右拖動,圖片同步旋轉。

var box = document.getElementsByClassName("sliding_block")[0];
var isDrop = false;
var angle = 0;

// 按下:開始拖拽
box.onmousedown = function(e) {
    var e = e || window.event;
    var x = e.clientX - box.offsetLeft;
    var y = e.clientY - box.offsetTop;
    isDrop = true;
};

// 移動:實時更新位置和角度
document.onmousemove = function(e) {
    if (!isDrop) return;
    
    var e = e || window.event;
    var moveX = e.clientX - x;
    
    // 限制范圍 0~360
    var minX = 0, maxX = 360;
    if (moveX < minX) moveX = minX;
    if (moveX > maxX) moveX = maxX;
    
    box.style.left = moveX + "px";
    angle = moveX;
    
    $("#baidu_img").attr("style", "transform: rotate(" + angle + "deg);");
    $("#msg_angle_span").html(angle);
};

// 松開:結束拖拽
document.onmouseup = function() {
    isDrop = false;
};

關鍵點

  • mousedown 記錄初始位置
  • mousemove 實時計算偏移
  • mouseup 結束拖拽
  • 三個事件必須配合使用,缺一不可

場景2:滾輪切換圖片

document.addEventListener('wheel', function(e) {
    // 避免在輸入框中觸發(fā)
    if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
        return;
    }
    
    e.preventDefault();  // 必須加,否則頁面會跟著滾
    
    if (e.deltaY > 0) {
        next_img();      // 滾輪向下 → 下一張
    } else {
        last_img();      // 滾輪向上 → 上一張
    }
}, { passive: false });  // passive: false 是關鍵

e.deltaY 的含義:

  • deltaY > 0 → 滾輪向下
  • deltaY < 0 → 滾輪向上
  • deltaX → 水平滾動(橫向滾輪)

場景3:拖拽浮動框

項目中還有個浮動框可以自由拖動:

var floatingDiv = document.getElementById('floatingDiv');
var initialX = null, initialY = null;

floatingDiv.addEventListener('mousedown', function(e) {
    initialX = e.clientX - floatingDiv.getBoundingClientRect().left;
    initialY = e.clientY - floatingDiv.getBoundingClientRect().top;
    e.preventDefault();  // 防止選中文本
});

document.addEventListener('mousemove', function(e) {
    if (initialX === null) return;
    
    var deltaX = e.clientX - initialX;
    var deltaY = e.clientY - initialY;
    
    floatingDiv.style.left = deltaX + 'px';
    floatingDiv.style.top = deltaY + 'px';
});

document.addEventListener('mouseup', function() {
    initialX = null;
    initialY = null;
});

五、mouseenter vs mouseover 的區(qū)別

事件冒泡觸發(fā)時機推薦場景
mouseover? 冒泡進入子元素也會觸發(fā)需要事件冒泡時
mouseenter? 不冒泡只在進入自身時觸發(fā)懸停效果優(yōu)先用這個

同理:mouseleave vs mouseout,也是 mouseleave 更常用。

// ? 不推薦:進入子元素會反復觸發(fā)
div.addEventListener('mouseover', function() {
    this.style.background = 'yellow';
});

// ? 推薦:只在進入/離開 div 時觸發(fā)一次
div.addEventListener('mouseenter', function() {
    this.style.background = 'yellow';
});
div.addEventListener('mouseleave', function() {
    this.style.background = '';
});

六、五個常見坑

坑1:忘了e.preventDefault()

右鍵會彈出瀏覽器菜單,滾輪會滾動頁面,拖拽會選中文本。

解決:在 mousedownwheel 里加 e.preventDefault()

坑2:mousemove性能問題

mousemove 觸發(fā)頻率極高(每秒幾十次),里面寫重邏輯會卡頓。

解決:用 requestAnimationFrame 節(jié)流。

var ticking = false;
document.addEventListener('mousemove', function(e) {
    if (!ticking) {
        requestAnimationFrame(function() {
            // 在這里寫業(yè)務邏輯
            ticking = false;
        });
        ticking = true;
    }
});

坑3:拖拽時元素被選中

拖拽過程中文字被藍框選中,體驗很差。

解決:CSS 全局禁用選中。

.sliding_block {
    user-select: none;
    -webkit-user-select: none;
}

(你的代碼里已經(jīng)加了,做得很好)

坑4:事件綁定在錯誤的元素上

mousemove 綁在滑塊上,結果拖出滑塊就失效了。

解決:mousemovemouseup 綁在 document 上,不是綁在滑塊上。

// ? 正確
box.onmousedown = function() { ... };
document.onmousemove = function() { ... };  // 綁在 document 上
document.onmouseup = function() { ... };    // 綁在 document 上

// ? 錯誤
box.onmousemove = function() { ... };  // 鼠標移出滑塊就失效

坑5:用onclick綁定多個事件

// ? 后面的會覆蓋前面的
btn.onclick = function() { alert(1); };
btn.onclick = function() { alert(2); };  // 只會彈出 2

// ? 用 addEventListener 可以綁定多個
btn.addEventListener('click', function() { alert(1); });
btn.addEventListener('click', function() { alert(2); });  // 兩個都會執(zhí)行

七、鼠標事件設計原則

原則說明
拖拽用 mousedown + mousemove + mouseup三件套,缺一不可
mousemove 綁在 document防止拖出元素失效
滾輪用 wheel + preventDefault{ passive: false } 必須加
懸停用 mouseenter/mouseleave不冒泡,不會反復觸發(fā)
第一行判斷是否在輸入框避免打字時誤觸發(fā)

總結

鼠標事件的核心就四句話:

  1. 點擊用 click,拖拽用 mousedown + mousemove + mouseup
  2. 滾輪用 wheel,記得 preventDefault() + { passive: false }
  3. mousemove 綁在 document 上,不是綁在元素上
  4. 第一行判斷是否在輸入框中

掌握這四點,你就能搞定90%的鼠標交互需求。

到此這篇關于前端JavaScript編寫鼠標事件的完整指南的文章就介紹到這了,更多相關JavaScript鼠標事件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

达尔| 土默特右旗| 百色市| 普陀区| 景洪市| 库尔勒市| 平和县| 长春市| 五寨县| 永宁县| 拉萨市| 龙川县| 郓城县| 南和县| 扎鲁特旗| 永靖县| 丹寨县| 郯城县| 信阳市| 霸州市| 唐海县| 禹州市| 来宾市| 精河县| 临沭县| 繁昌县| 新和县| 大石桥市| 西峡县| 耒阳市| 伊通| 丰都县| 德钦县| 湟源县| 津市市| 会东县| 册亨县| 玛沁县| 高唐县| 聂拉木县| 德令哈市|