You need to enable JavaScript to run this app. 如何检测用户是否尝试调整使用CSS resize: both的可拖拽元素大小
优惠活动
大模型
产品
解决方案
定价
更多

如何检测用户是否尝试调整使用CSS resize: both的可拖拽元素大小

最优实现方案

核心思路是复用浏览器原生的resize状态判断,不需要自己硬编码坐标阈值,完全规避浏览器/系统的样式差异问题:

  • 浏览器触发resize规则时会自动修改光标类型为se-resize(右下角双向箭头),只需要在拖拽触发前判断当前光标类型,只要是调整尺寸相关的光标,直接终止拖拽逻辑即可。

具体修改点

你只需要替换原有mousedown事件中20px坐标判断的逻辑即可:

// 原有硬编码坐标逻辑可完全删除
/* if cursor within 20px from bottom right corner don't move */
// const r = e.target.getBoundingClientRect();
// if (r.right < e.x + 20 && r.bottom < e.y + 20)
//   return;

// 替换为光标类型判断逻辑
const cursorStyle = getComputedStyle(e.target).cursor;
// 匹配所有调整尺寸的光标类型,兼容不同浏览器表现
if(['se-resize', 'nwse-resize', 'resize'].includes(cursorStyle)) return;

优化后的完整可运行代码

JS

!function(){
"use strict";
let x, y, drag;
document.addEventListener("mousedown", function(e) {
  if (e.target.parentNode.lastChild !== e.target && e.target.parentNode.classList.contains("main")) {
    //bring element to the front and dispatch mousedown event again otherwise resize doesn't work
    e.target.parentNode.appendChild(e.target);
    return e.target.dispatchEvent(new MouseEvent(e.type, e));
  }

  if (!e.target.classList.contains("draggable"))
    return;

  // 替换原有坐标判断为光标类型判断
  const cursorStyle = getComputedStyle(e.target).cursor;
  if(['se-resize', 'nwse-resize', 'resize'].includes(cursorStyle)) return;

  drag = e.target;
  x = e.x - drag.offsetLeft;
  y = e.y - drag.offsetTop;
  document.body.classList.add("drag");
  drag.classList.add("drag");
});

document.addEventListener("mouseup", function(e) {
  document.body.classList.remove("drag");
  drag = drag && drag.classList.remove("drag");
});

document.addEventListener("mousemove", function(e) {
  if (!drag || e.x - drag.offsetLeft == x || e.y - drag.offsetTop == y)
    return;

  drag.style.left = (e.x - x) + "px";
  drag.style.top = (e.y - y) + "px";
});

/*init*/
for (let i = 0, c, d = document.getElementsByClassName("main")[0].children; i < d.length; i++) {
  c = (0x1000000 + Math.random() * 0xffffff).toString(16).substr(1, 6);
  d[i].style.backgroundColor = '#' + c;
  d[i].classList.toggle("dark", ((parseInt(c.substr(0, 2), 16) * 299) + (parseInt(c.substr(2, 2), 16) * 587) + (parseInt(c.substr(4, 2), 16) * 114)) / 1000 < 128);
  d[i].style.left = document.documentElement.scrollWidth / 8 + Math.random() * (document.documentElement.scrollWidth / 1.33 - d[i].offsetWidth) + "px";
  d[i].style.top = document.documentElement.scrollHeight / 8 + Math.random() * (document.documentElement.scrollHeight / 1.33 - d[i].offsetHeight) + "px";
}
}()

CSS(原有逻辑无需修改)

div.main>div {
  width: 5em;
  height: 5em;
  border: 1px solid black;
  position: absolute;
  resize: both;
  overflow: hidden;
  mix-blend-mode: hard-light;
  display: flex;
  border-radius: 0.3em;
}

div.main>div:hover {
  box-shadow: 0 0 5px black;
}

div.main>div:last-child {
  box-shadow: 0 0 10px black;
}

div.draggable {
  cursor: grab;
}

div.main>div:not(.draggable):before {
  content: "can't move me";
}

div.main>div.draggable:before {
  content: "move me";
}

div.main>div:before {
  color: black;
  text-shadow: 0 0 1em black;
  margin: auto;
  text-align: center;
}

div.main>div.dark:before {
  color: white;
  text-shadow: 0 0 1em white;
}

body.drag {
  user-select: none;
}

body.drag div.draggable {
  cursor: grabbing;
}

HTML(原有逻辑无需修改)

<div class="main">
  <div></div>
  <div class="draggable"></div>
  <div class="draggable"></div>
  <div class="draggable"></div>
</div>

方案优势

  1. 完全适配不同浏览器、操作系统的resize手柄尺寸差异,不会出现坐标判断失效的问题
  2. 逻辑更轻量,不需要额外计算元素坐标,性能更好
  3. 完全贴合用户预期,光标是移动状态时触发拖拽,是调整大小状态时触发原生resize,无逻辑冲突

内容的提问来源于stack exchange,提问作者vanowm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 05:36:08