JavaScript实现鼠标拖动窗口效果详解

作者:小圆点

时间:2026-10-26

浏览:470

本文详细解析如何使用JavaScript实现鼠标拖动窗口效果。通过处理mousedown、mousemove和mouseup事件,结合绝对定位与坐标计算,实现窗口跟随鼠标移动。代码包含对IE与非IE浏览器的兼容处理,如事件绑定方式及鼠标按键值的差异,并提供了完整的HTML结构与CSS样式示例。

文章目录

JavaScript实现鼠标拖动窗口效果详解

首先展示需要实现拖动功能的模拟窗口效果。


JavaScript实现鼠标拖动窗口效果详解 目标效果:当鼠标左键在窗口标题栏按下并移动时,窗口随之移动。 窗口结构如下:

HTML代码如下:

 
<div id="win">
<div id="win_header"></div>
</div>

前期准备工作:


为使窗口可自由移动,需将其定位方式设置为绝对定位(absolute);


在窗口顶部添加标题栏,并将该区域的鼠标光标样式设置为拖动形状(在Chrome中拖动时光标会变为文字光标,松开鼠标后恢复)。


CSS代码如下:

 
#win {
position:absolute;
width:480px;
height:320px;
background-color:#d4d4d4;
border: 1px solid #4d4d4d;
} 
#win_header {
width:480px;
height:48px;
background-color:#4d4d4d;
cursor:move;
} 

定义一个辅助函数,用于通过ID获取元素:


代码如下:

 
function $id(id) {
return document.getElementById(id);
} 

定义浏览器核心标识isIE:


var isIE = (window.navigator.userAgent.indexOf("IE") == -1) ? false : true;


获取窗口元素及其标题栏:


代码如下:

 
var win = $id("win");
var header = $id("win_header");

为记录鼠标和窗口位置信息,创建一个位置对象:


代码如下:

 
var pos =function(x, y) {
this.x = x;
this.y = y;
}; 

为窗口设置初始位置(即CSS中的left和top值)。


此处原因不明,若不在JS中设置这两个属性,即使CSS中已指定也无法获取值。


代码如下:

 
var originalpos = new pos(20, 20);

拖动过程中需记录以下数值:


鼠标按下时光标的位置


代码如下:

 
var oldmouse =new pos(0, 0);

鼠标按下时窗口的位置


var oldpos = new pos(0, 0);


鼠标移动时窗口的新位置


var newpos = new pos(0, 0);


设置窗口的初始位置


代码如下:

 
win.style.left = originalpos.x + "px";
win.style.top = originalpos.y + "px";

由于浏览器差异(IE与非IE),元素绑定事件处理函数的方法不同(IE使用attachEvent,非IE使用addEventListener)。为简化操作,定义一个事件绑定函数:


代码如下:

 
function bind(ev, func) {
if(isIE) {
header.attachEvent("on" + ev, func);
} else {
header.addEventListener(ev, func, false);
} 
} 

完成上述准备工作后,即可开始处理鼠标事件。


程序中仅允许鼠标左键拖动,其他按键无效。此判断需在多个函数中使用,故提取为独立函数,通过传入参数(鼠标键值)进行判断。需注意浏览器差异:IE中鼠标左键值为1,非IE中值为0。


代码如下:

 
function isLeftButton(btn) {
if(isIE) {
if(btn == 1)
return true;
else
return false;
} else {
if(btn == 0)
return true;
else
return false;
} 
} 

拖动动作由按下鼠标左键后移动完成。该动作涉及两个事件:先触发按下(mousedown),再触发移动(mousemove)。为区分真实拖动与鼠标经过,设置变量记录鼠标按下状态:


var mousedown = false;


由于CSS存在兼容性问题,此处使用JS控制鼠标悬停在标题栏时的颜色变化。


悬停效果


代码如下:

 
function over(e){
header.style.backgroundColor = "#5d5d5d";
} 

离开效果


代码如下:

 
function out(e) {
header.style.backgroundColor = "#4d4d4d";
// 有时鼠标在未松开时离开窗口,
// 此时通过触发鼠标松开事件使窗口脱离控制
up(e);
} 

按下事件


在按下事件中,需先判断是否为鼠标左键;


若是,则记录此时鼠标和窗口的位置;否则不记录。


代码如下:

 
function down(e) {
e = e || event;
if(!isLeftButton(e.button))
return;
mousedown = true;
oldmouse.x = e.clientX;
oldmouse.y = e.clientY;
oldpos.x = parseInt(win.style.left.replace("px", ""));
oldpos.y = parseInt(win.style.top.replace("px", ""));
} 

松开事件


代码如下:

 
function up(e) {
if(!isLeftButton(e.button))
return;
mousedown = false;
} 

移动事件


此处涉及两个鼠标事件:


按下和移动。仅当鼠标左键按下时,移动动作才有效。


窗口新位置由拖动状态下的移动距离(X和Y轴距离)决定。即:


用新的鼠标位置减去按下左键时记录的位置,得到移动距离,再将窗口原位置加上该移动距离,即为窗口新位置。


代码如下:

 
function move(e) {
if(!isLeftButton(e.button))
return;
if(mousedown) {
e =e || event;
newpos.x = e.clientX - oldmouse.x;
newpos.y = e.clientY - oldmouse.y
win.style.left = (oldpos.x + newpos.x) + "px";
win.style.top = (oldpos.y + newpos.y) + "px";
} 
} 

所有事件处理函数编写完毕后,最后将事件绑定到元素上。


代码如下:

 
bind("mouseover", over);
bind("mouseenter", over);
bind("mouseout", out);
bind("mouseleave", out);
bind("blur", out);
bind("mousedown", down);
bind("mouseup", up);
bind("mousemove", move);

但在FF浏览器中拖动存在异常,仅第一次拖动正常,后续会出现混乱。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章