You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

拖拽文本后window的mouseup事件未触发,如何修复?

问题描述

我写了一个通过鼠标点击拖拽距离改变页面背景色的脚本,在空白区域拖拽时功能正常,但选中段落“This is a paragraph”中的文本并拖拽后,mouseup事件未被触发,脚本无法按预期工作。相关代码如下:

index.html

<!DOCTYPE html>
<html>

<head>
    <link rel="stylesheet" href="index.css">
</head>

<body id="main-body">
    <script src="index.js"></script>

    <p id="para">This is a paragraph</p>

</body>

</html>

index.ts

const body = document.getElementById('main-body')

let posX: number, posY: number;
let mouseDownX: number, mouseDownY: number;
let clicked: boolean = false;


window.addEventListener('mousedown', e =>{
  if(!clicked){
    mouseDownX = e.clientX;
    mouseDownY = e.clientY;
    clicked = true;
  }  
  console.log('Mouse clicked');
})


window.addEventListener('mousemove', e =>{
  if(!clicked) {
    mouseDownX = e.clientX;
    mouseDownY = e.clientY;
  }
  const deltaDX = mouseDownX - e.clientX,
        deltaDY = mouseDownY - e.clientY,
        maxDelta = window.innerWidth/2;
  const percentageX = Math.abs(deltaDX/maxDelta);
  const percentageY = Math.abs(deltaDY/maxDelta);

  body?.style.setProperty('background-color', `rgb(0, ${255*percentageX}, ${255*percentageY})`)
})

window.addEventListener('mouseup', () =>{
  clicked = false;
})
解决方案

这是因为文本拖拽属于浏览器默认行为,当选中文本拖拽时,浏览器会启动内置的文本拖拽操作,导致mouseup事件无法正常冒泡到window对象上。可以通过以下两种方式修复:

方式一:阻止文本的默认拖拽行为

给段落元素添加mousedown事件监听,阻止默认行为,避免浏览器触发文本拖拽:

const para = document.getElementById('para');
para?.addEventListener('mousedown', (e) => {
  e.preventDefault();
});

这种方式会直接禁止文本被选中和拖拽,确保你的mouseup事件能正常触发。

方式二:补充监听dragend事件

如果需要保留文本选中功能,可以额外监听dragend事件,在文本拖拽结束时重置clicked状态:

window.addEventListener('dragend', () => {
  clicked = false;
});

文本拖拽结束时会触发dragend事件,通过这个事件可以在特殊场景下重置状态,让脚本恢复正常工作。

额外优化建议

你的mousemove事件逻辑存在小问题:当clicked为false时,每次鼠标移动都会重置mouseDownX/Y,导致背景色会一直跟随鼠标移动,即使没有点击拖拽。可以调整逻辑,仅在点击状态下计算距离并修改背景色:

window.addEventListener('mousemove', e =>{
  if(clicked) {
    const deltaDX = mouseDownX - e.clientX,
          deltaDY = mouseDownY - e.clientY,
          maxDelta = window.innerWidth/2;
    const percentageX = Math.abs(deltaDX/maxDelta);
    const percentageY = Math.abs(deltaDY/maxDelta);

    // 限制颜色值不超过255的合法范围
    body?.style.setProperty('background-color', `rgb(0, ${Math.min(255, 255*percentageX)}, ${Math.min(255, 255*percentageY)})`)
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:48:30