JavaScript实现鼠标拖动窗口效果详解
本文详细解析如何使用JavaScript实现鼠标拖动窗口效果。通过处理mousedown、mousemove和mouseup事件,结合绝对定位与坐标计算,实现窗口跟随鼠标移动。代码包含对IE与非IE浏览器的兼容处理,如事件绑定方式及鼠标按键值的差异,并提供了完整的HTML结构与CSS样式示例。
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浏览器中拖动存在异常,仅第一次拖动正常,后续会出现混乱。
JS在setTimeout或Ajax回调中打开新标签页失败怎么处理
2026-11-05 15:50:12
JS直播协议选型:HLS、FLV与WebRTC的延迟与兼容性对比
2026-11-05 12:16:14
JS实现回到顶部:scrollTop赋值与浏览器兼容性处理
2026-11-04 23:43:35
JS使用classList动态添加、移除和切换CSS类名
2026-11-04 23:40:58
在 D3.js 中实现平滑过渡动画的技巧
2026-11-03 23:46:09
