午夜视频在线观看区二区-午夜视频在线观看视频-午夜视频在线观看视频在线观看-午夜视频在线观看完整高清在线-午夜视频在线观看网站-午夜视频在线观看亚洲天堂

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

JS拖動(dòng)的原理

freeflydom
2025年4月3日 15:34 本文熱度 574

在 JavaScript 中實(shí)現(xiàn)元素的拖動(dòng)效果,核心原理是通過監(jiān)聽鼠標(biāo)事件(或觸摸事件)來計(jì)算元素的位置變化。以下是詳細(xì)的實(shí)現(xiàn)原理和步驟:


1. 核心事件

拖動(dòng)需要處理三個(gè)關(guān)鍵事件:

  • mousedown(按下鼠標(biāo)):標(biāo)記拖動(dòng)開始,記錄初始位置。
  • mousemove(移動(dòng)鼠標(biāo)):實(shí)時(shí)計(jì)算元素新位置并更新。
  • mouseup(松開鼠標(biāo)):結(jié)束拖動(dòng),移除事件監(jiān)聽。

如果是移動(dòng)端,對應(yīng)的事件為 touchstart、touchmove 和 touchend。


2. 實(shí)現(xiàn)步驟

2.1 綁定 mousedown 事件

當(dāng)用戶在目標(biāo)元素上按下鼠標(biāo)時(shí),記錄:

  • 鼠標(biāo)的初始位置clientXclientY)。
  • 元素的初始位置offsetLeftoffsetTop)。
  • 鼠標(biāo)相對于元素左上角的偏移量(用于保持拖動(dòng)時(shí)的相對位置)。
element.addEventListener('mousedown', function(e) {
  // 1. 記錄初始數(shù)據(jù)
  const startX = e.clientX;
  const startY = e.clientY;
  const elemLeft = element.offsetLeft;
  const elemTop = element.offsetTop;
  // 2. 計(jì)算鼠標(biāo)在元素內(nèi)的偏移量
  const offsetX = startX - elemLeft;
  const offsetY = startY - elemTop;
  // 3. 綁定 mousemove 和 mouseup 事件
  document.addEventListener('mousemove', onMouseMove);
  document.addEventListener('mouseup', onMouseUp);
  function onMouseMove(e) {
    // 計(jì)算新位置
    const newX = e.clientX - offsetX;
    const newY = e.clientY - offsetY;
    
    // 更新元素位置
    element.style.left = newX + 'px';
    element.style.top = newY + 'px';
  }
  function onMouseUp() {
    // 移除事件監(jiān)聽
    document.removeEventListener('mousemove', onMouseMove);
    document.removeEventListener('mouseup', onMouseUp);
  }
});

2.2 關(guān)鍵細(xì)節(jié)

  • 事件委托到 document
    將 mousemove 和 mouseup 綁定到 document,而非元素本身。這樣即使鼠標(biāo)快速移動(dòng)超出元素區(qū)域,仍能正常觸發(fā)事件。

  • 性能優(yōu)化
    避免在 mousemove 中頻繁觸發(fā)重排(如讀取 offsetLeft),提前緩存初始值。

  • 邊界限制(可選)
    可添加邏輯限制元素在容器內(nèi)移動(dòng):

    const maxX = container.offsetWidth - element.offsetWidth;
    const maxY = container.offsetHeight - element.offsetHeight;
    newX = Math.max(0, Math.min(newX, maxX));
    newY = Math.max(0, Math.min(newY, maxY));
    

2.3 處理 CSS 定位

  • 元素必須設(shè)置為 position: absolute 或 position: fixed,才能通過 left 和 top 修改位置。
  • 使用 transform: translate() 實(shí)現(xiàn)位置變化(性能更優(yōu)):
    element.style.transform = `translate(${newX}px, ${newY}px)`;
    

3. 完整代碼示例

<div id="draggable" style="position: absolute; left: 0; top: 0;">拖動(dòng)我</div>
<script>
  const element = document.getElementById('draggable');
  element.addEventListener('mousedown', startDrag);
  function startDrag(e) {
    e.preventDefault();
    
    const startX = e.clientX;
    const startY = e.clientY;
    const elemX = element.offsetLeft;
    const elemY = element.offsetTop;
    const offsetX = startX - elemX;
    const offsetY = startY - elemY;
    document.addEventListener('mousemove', onDrag);
    document.addEventListener('mouseup', stopDrag);
    function onDrag(e) {
      const newX = e.clientX - offsetX;
      const newY = e.clientY - offsetY;
      element.style.left = newX + 'px';
      element.style.top = newY + 'px';
    }
    function stopDrag() {
      document.removeEventListener('mousemove', onDrag);
      document.removeEventListener('mouseup', stopDrag);
    }
  }
</script>

4. 高級優(yōu)化

  • 防抖(Debounce):減少 mousemove 事件的觸發(fā)頻率。
  • 請求動(dòng)畫幀(RAF):使用 requestAnimationFrame 優(yōu)化動(dòng)畫流暢度。
  • 觸摸事件支持:通過 touchstart/touchmove 兼容移動(dòng)端。
  • 拖拽反饋:添加半透明效果或占位符提升用戶體驗(yàn)。

5. 原生拖拽 API 對比

HTML5 提供了原生拖放 API(draggable 屬性 + dragstart/dragover 事件),但:

  • 優(yōu)點(diǎn):支持跨元素拖放、文件拖拽上傳。
  • 缺點(diǎn):定制性較差,默認(rèn)會(huì)顯示半透明圖像。

總結(jié)

通過監(jiān)聽鼠標(biāo)事件、計(jì)算偏移量并更新元素位置,可以靈活實(shí)現(xiàn)自定義拖拽效果。相比原生 API,手動(dòng)控制更適用于需要高度定制的場景(如游戲、復(fù)雜 UI 組件)。

轉(zhuǎn)自https://juejin.cn/post/7488524321788444723


該文章在 2025/4/3 15:35:05 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 成人中文字幕一区二区三区 | 丰满人妻熟妇乱又伦精品软件 | 国产成人免费视频在线网站 | 国产精品人人做人人爽人人添 | 精品午夜福利视频 | 91久久久久精品无码一区二区 | 丰满少妇精品无码专区 | 国产精品一区二区国模私拍 | 国产成人无码的免费视频播放 | 成人精品综合免费视频 | 国产午夜福利电影免费在线观看 | 成人午夜福利a片在线观看 成人午夜福利电影 | 国产午夜精品美女免费大片 | 国产无码白丝自慰 | 国产成人午夜无码电影在线观看 | 国产护士在病房a | 国产精品无码av一区二区三区 | 精品国产经典三级在线看 | 高清成人爽a毛片免费直播 高清成人爽a毛片在线播放 | 国产毛片18片毛一级特黄 | 国产激情福利久久精品麻豆 | 成人黄色一级高清视频 | 国产精品一级特黄a毛片 | 国产另类的人妖ts视频 | 精品国产免费午夜剧场 | 国产精品大屁股白浆视频手 | 丰满年轻岳欲乱中文字幕电影 | 国产午夜无码片在线观看影视 | 国产精品中文久久久久久久 | www三级免费 | 10000部无码免费视频拍拍拍 | 国产福利无码一区色费 | 国产麻无矿码直接观看 | 国产精品无码专区免费不卡 | 国产综合精品一区二区 | 91精品人妻一区二区蜜桃 | 国产日韩一区二区三区视频免费 | 国产成人综合亚洲av第一页 | 99久久精品免费精品国产电影 | 国产精品一区二区三区高清在线 | 国产97视频在线观看免费 |