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

HTML+JS怎么寫一個(gè)可以拖拽縮放的div?

admin
2023年11月1日 9:47 本文熱度 1536

說(shuō)在前面

元素拖拽和縮放現(xiàn)在也是一個(gè)很常見(jiàn)的功能,讓我們從實(shí)現(xiàn)div元素的拖拽縮放開(kāi)始來(lái)了解元素拖拽縮放的具體原理和實(shí)現(xiàn)方法吧。

效果展示

AI改圖-Document - Google Chrome 2023-09-26 22-50-31-720x382.gif
AI改圖-Document - Google Chrome 2023-09-26 22-55-50-720x382.gif

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

畫一個(gè)div

首先我們需要先畫一個(gè)div,并給它8個(gè)方位(上、下、左、右、左上、右上、右下、左下)加上縮放錨點(diǎn),我們可以通過(guò)這幾個(gè)錨點(diǎn)來(lái)對(duì)div進(jìn)行縮放,具體代碼如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./index.css" />
  </head>
  <body>
    <div class="box" id="drag">
      <div class="resize-handle top-left"></div>
      <div class="resize-handle top"></div>
      <div class="resize-handle top-right"></div>
      <div class="resize-handle right"></div>
      <div class="resize-handle bottom-right"></div>
      <div class="resize-handle bottom"></div>
      <div class="resize-handle bottom-left"></div>
      <div class="resize-handle left"></div>
    </div>
  </body>
  <script src="./index.js"></script>
</html>

加點(diǎn)css

將錨點(diǎn)定位到其特定的位置上,并設(shè)置不同的鼠標(biāo)指示效果,具體代碼如下:

.box {
  position: absolute;
  left50%;
  top50%;
  transformtranslate(-50%, -50%);
  width200px;
  height200px;
  background-color#f0f0f0;
  cursor: move;
}

.resize-handle {
  position: absolute;
  width10px;
  height10px;
  background-color#000;
}

.top-left {
  top: -5px;
  left: -5px;
  cursor: nw-resize;
}

.top {
  top: -5px;
  leftcalc(50% - 5px);
  cursor: ns-resize;
}

.top-right {
  top: -5px;
  right: -5px;
  cursor: ne-resize;
}

.right {
  topcalc(50% - 5px);
  right: -5px;
  cursor: ew-resize;
}

.bottom-right {
  bottom: -5px;
  right: -5px;
  cursor: se-resize;
}

.bottom {
  bottom: -5px;
  leftcalc(50% - 5px);
  cursor: ns-resize;
}

.bottom-left {
  bottom: -5px;
  left: -5px;
  cursor: sw-resize;
}

.left {
  topcalc(50% - 5px);
  left: -5px;
  cursor: ew-resize;
}

效果是這樣的:

image.png

完成拖拽和縮放功能

拖拽功能

我們需要鼠標(biāo)在div內(nèi)按下不松開(kāi)的時(shí)候,div可以跟著鼠標(biāo)的位置移動(dòng),這里我們可以從鼠標(biāo)的三種事件的觸發(fā)來(lái)入手:

  • 1、鼠標(biāo)按下(mousedown)

首先我們需要監(jiān)聽(tīng)鼠標(biāo)按下事件。

const dragElement = document.getElementById("drag");
dragElement.addEventListener("mousedown", startDrag);

判斷點(diǎn)擊事件是否為錨點(diǎn)觸發(fā),是的話則不執(zhí)行拖拽邏輯。這里我們可以通過(guò)樣式名來(lái)判斷,錨點(diǎn)我們都給它加上了resize-handle,我們只需要判斷樣式名是否包含resize-handle就可以。

function startDrag(event{
  event.preventDefault();
  const currentHandle = event.target;
  const isResizeHandle = currentHandle.className.includes("resize-handle");
  if (isResizeHandle) return;
}

記錄下鼠標(biāo)點(diǎn)擊的坐標(biāo)及拖拽元素所在位置,用于后面計(jì)算鼠標(biāo)移動(dòng)距離和對(duì)拖拽元素進(jìn)行移動(dòng),監(jiān)聽(tīng)鼠標(biāo)移動(dòng)和抬起事件

  const startX = event.clientX;
  const startY = event.clientY;
  const startLeft = dragElement.offsetLeft;
  const startTop = dragElement.offsetTop;
  document.addEventListener("mousemove", drag);
  document.addEventListener("mouseup", stopDrag);
  • 2、鼠標(biāo)移動(dòng)(mousemove)

鼠標(biāo)移動(dòng)的時(shí)候計(jì)算鼠標(biāo)當(dāng)前位置與鼠標(biāo)點(diǎn)擊位置的相對(duì)距離,將拖拽元素的位置也移動(dòng)相應(yīng)的相對(duì)距離

function drag(event{
  const dx = event.clientX - startX;
  const dy = event.clientY - startY;
  const newLeft = startLeft + dx;
  const newTop = startTop + dy;
  dragElement.style.left = newLeft + "px";
  dragElement.style.top = newTop + "px";
}
  • 3、鼠標(biāo)抬起(mouseup)

鼠標(biāo)抬起的時(shí)候?qū)⑹髽?biāo)移動(dòng)和鼠標(biāo)抬起的監(jiān)聽(tīng)事件移除。

function stopDrag({
  document.removeEventListener("mousemove", drag);
  document.removeEventListener("mouseup", stopDrag);
}

到這里我們就完成了一個(gè)最基本的可拖拽元素了,接下來(lái)就該來(lái)實(shí)現(xiàn)縮放功能了。

縮放功能

我們希望在點(diǎn)擊縮放錨點(diǎn)進(jìn)行移動(dòng)的時(shí)候,元素會(huì)隨著鼠標(biāo)繼續(xù)縮小或放大,這里我們?nèi)匀皇且獜氖髽?biāo)觸發(fā)的三種事件來(lái)入手:

  • 1、鼠標(biāo)按下(mousedown)

我們需要監(jiān)聽(tīng)所有錨點(diǎn)的鼠標(biāo)按下事件,首先我們需要先獲取所有的錨點(diǎn)元素:

const resizeHandles = document.getElementsByClassName("resize-handle");

再監(jiān)聽(tīng)所有錨點(diǎn)元素的鼠標(biāo)按下事件:

Array.from(resizeHandles).forEach((handle) => {
  handle.addEventListener("mousedown", startResize);
});

記錄鼠標(biāo)按下的初始位置及縮放元素的初始位置和寬高,便于后面對(duì)縮放元素進(jìn)行縮放操作,并為縮放元素加上鼠標(biāo)移動(dòng)和鼠標(biāo)抬起的監(jiān)聽(tīng)事件。

function startResize(event{
  event.preventDefault();
  const currentHandle = event.target;
  const direction = currentHandle.className.split(" ")[1];
  startX = event.clientX;
  startY = event.clientY;
  startWidth = dragElement.offsetWidth;
  startHeight = dragElement.offsetHeight;
  startLeft = dragElement.offsetLeft;
  startTop = dragElement.offsetTop;
  document.addEventListener("mousemove", resize);
  document.addEventListener("mouseup", stopResize);
  }
  • 2、鼠標(biāo)移動(dòng)(mousemove)

鼠標(biāo)移動(dòng)的時(shí)候我們需要判斷當(dāng)前是從哪個(gè)錨點(diǎn)觸發(fā)的縮放事件,我們可以從錨點(diǎn)的樣式名className來(lái)做區(qū)分。

const currentHandle = event.target;
const direction = currentHandle.className.split(" ")[1];

不同錨點(diǎn)我們需要對(duì)元素進(jìn)行不同的操作,我們可以分為四個(gè)方位來(lái)進(jìn)行判斷并區(qū)分操作:

(1)左邊

判斷樣式名是否包含left,左邊錨點(diǎn)會(huì)觸發(fā)元素的寬度變化及左右位置的變化,這時(shí)候鼠標(biāo)左移相對(duì)于元素來(lái)說(shuō)是放大,右移相對(duì)于元素來(lái)說(shuō)是縮小,所以元素的寬度應(yīng)該減去鼠標(biāo)的位移距離。

if (direction.includes("left")) {
  width = startWidth - dx + "px";
  left = startLeft + dx / 2 + "px";
}

(2)右邊

判斷樣式名是否包含right,右邊錨點(diǎn)會(huì)觸發(fā)元素的寬度變化及左右位置的變化,這時(shí)候鼠標(biāo)左移相對(duì)于元素來(lái)說(shuō)是縮小,右移相對(duì)于元素來(lái)說(shuō)是放大,所以元素的寬度應(yīng)該加上鼠標(biāo)的位移距離。

if (direction.includes("right")) {
  width = startWidth + dx + "px";
  left = startLeft + dx / 2 + "px";
}

(3)上邊

判斷樣式名是否包含top,上邊錨點(diǎn)會(huì)觸發(fā)元素的高度變化及上下位置的變化,這時(shí)候鼠標(biāo)上移相對(duì)于元素來(lái)說(shuō)是放大,下移相對(duì)于元素來(lái)說(shuō)是縮小,所以元素的高度應(yīng)該減去鼠標(biāo)的位移距離。

if (direction.includes("top")) {
  height = startHeight - dy + "px";
  top = startTop + dy / 2 + "px";
}

(4)下邊

判斷樣式名是否包含bottom,下邊錨點(diǎn)會(huì)觸發(fā)元素的高度變化及上下位置的變化,這時(shí)候鼠標(biāo)上移相對(duì)于元素來(lái)說(shuō)是縮小,下移相對(duì)于元素來(lái)說(shuō)是放大,所以元素的高度應(yīng)該加上鼠標(biāo)的位移距離。

if (direction.includes("bottom")) {
  height = startHeight + dy + "px";
  top = startTop + dy / 2 + "px";
}

我們還需要判斷當(dāng)前元素的寬度和高度是否小于等于0,等于0的時(shí)候我們不再對(duì)其進(jìn)行縮放操作,大于0則對(duì)元素進(jìn)行賦值操作。

if (parseInt(width) <= 0 || parseInt(height) <= 0return;
dragElement.style.width = width;
dragElement.style.height = height;
dragElement.style.left = left;
dragElement.style.top = top;

完整代碼如下:

function resize(event{
    const dx = event.clientX - startX;
    const dy = event.clientY - startY;
    let width = startWidth,
      height = startHeight,
      left = startLeft,
      top = startTop;
    if (direction.includes("left")) {
      width = startWidth - dx + "px";
      left = startLeft + dx / 2 + "px";
    }
    if (direction.includes("right")) {
      width = startWidth + dx + "px";
      left = startLeft + dx / 2 + "px";
    }
    if (direction.includes("top")) {
      height = startHeight - dy + "px";
      top = startTop + dy / 2 + "px";
    }
    if (direction.includes("bottom")) {
      height = startHeight + dy + "px";
      top = startTop + dy / 2 + "px";
    }
    if (parseInt(width) <= 0 || parseInt(height) <= 0return;
    dragElement.style.width = width;
    dragElement.style.height = height;
    dragElement.style.left = left;
    dragElement.style.top = top;
}
  • 3、鼠標(biāo)抬起(mouseup)

鼠標(biāo)抬起的時(shí)候?qū)⑹髽?biāo)移動(dòng)和鼠標(biāo)抬起的監(jiān)聽(tīng)事件移除。

function stopResize({
    document.removeEventListener("mousemove", resize);
    document.removeEventListener("mouseup", stopResize);
}

到這里我們就完成了一個(gè)最基本的可拖拽縮放的元素了。

完整代碼

完整的JavaScrip代碼如下:

const dragElement = document.getElementById("drag");
// 拖拽功能
dragElement.addEventListener("mousedown", startDrag);
function startDrag(event{
  event.preventDefault();
  const currentHandle = event.target;
  const isResizeHandle = currentHandle.className.includes("resize-handle");
  if (isResizeHandle) return;
  const startX = event.clientX;
  const startY = event.clientY;
  const startLeft = dragElement.offsetLeft;
  const startTop = dragElement.offsetTop;
  document.addEventListener("mousemove", drag);
  document.addEventListener("mouseup", stopDrag);
  function drag(event{
    const dx = event.clientX - startX;
    const dy = event.clientY - startY;
    const newLeft = startLeft + dx;
    const newTop = startTop + dy;
    dragElement.style.left = newLeft + "px";
    dragElement.style.top = newTop + "px";
  }
  function stopDrag({
    document.removeEventListener("mousemove", drag);
    document.removeEventListener("mouseup", stopDrag);
  }
}
// 縮放功能
const resizeHandles = document.getElementsByClassName("resize-handle");
Array.from(resizeHandles).forEach((handle) => {
  handle.addEventListener("mousedown", startResize);
});

function startResize(event{
  event.preventDefault();
  const currentHandle = event.target;
  const direction = currentHandle.className.split(" ")[1];
  const startX = event.clientX;
  const startY = event.clientY;
  const startWidth = dragElement.offsetWidth;
  const startHeight = dragElement.offsetHeight;
  const startLeft = dragElement.offsetLeft;
  const startTop = dragElement.offsetTop;
  document.addEventListener("mousemove", resize);
  document.addEventListener("mouseup", stopResize);
  function resize(event{
    const dx = event.clientX - startX;
    const dy = event.clientY - startY;
    let width = startWidth,
      height = startHeight,
      left = startLeft,
      top = startTop;
    if (direction.includes("left")) {
      width = startWidth - dx + "px";
      left = startLeft + dx / 2 + "px";
    }
    if (direction.includes("right")) {
      width = startWidth + dx + "px";
      left = startLeft + dx / 2 + "px";
    }
    if (direction.includes("top")) {
      height = startHeight - dy + "px";
      top = startTop + dy / 2 + "px";
    }
    if (direction.includes("bottom")) {
      height = startHeight + dy + "px";
      top = startTop + dy / 2 + "px";
    }
    if (parseInt(width) <= 0 || parseInt(height) <= 0return;
    dragElement.style.width = width;
    dragElement.style.height = height;
    dragElement.style.left = left;
    dragElement.style.top = top;
  }
  function stopResize({
    document.removeEventListener("mousemove", resize);
    document.removeEventListener("mouseup", stopResize);
  }
}

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

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
久久午夜视频一二三区 | 在线看片免费人成视频福利 | 亚洲国内自拍欧美一区二区三区 | 亚洲AⅤ鲁丝一区二区三区 日韩欧美综合一区二区 | 日韩国产欧美一级天堂 | 夜夜爱夜夜操国产精品 |