本文详细解析如何使用JavaScript实现模态框的拖拽功能。通过对比offset与style属性的区别,掌握鼠标按下、移动及松开事件的逻辑处理,结合完整的HTML结构、CSS样式及JS代码,帮助开发者快速实现带有半透明遮挡层的可拖拽登录框效果。
本文分享了利用JavaScript实现模态框拖拽效果的具体代码,供读者参考学习。
关键属性与offset和style的区别
在开始编写案例之前,需要明确几个关键属性:offsetLeft.offsetTop,e.pageX,e.pageY;。掌握这些基础概念后,即可进行后续操作。
以下是对上述属性的具体解释:
1. offsetLeft:返回带有定位父元素的左侧偏移量。若父元素未定位,则返回距离浏览器窗口最左侧的距离。2. offsetTop:返回带有定位父元素的顶部偏移量。若父元素未定位,则返回距离浏览器窗口最顶部的距离。3. e.pageX:表示鼠标指针距离浏览器窗口最左侧的坐标值。4. e.pageY:表示鼠标指针距离浏览器窗口最顶部的坐标值。
注意:offsetLeft获取的是number类型数值,不包含像素单位px;而通过style.left获取的值则包含px单位,建议对比记忆。口诀:获取元素偏移量或大小时使用offset;设置元素值时使用style,且赋值时需手动添加+‘px’。
接下来详细阐述offset与style的具体区别:
关于offset:
- offset可以获取任意样式表(包括内部和外部)中的样式值,但仅返回数值,不含px单位。
- offset系列属性获取的数值均不带单位。
- offsetWidth包含padding、border以及width的总和。
- offsetWidth等属性为只读属性,仅支持获取,不支持赋值【重点】。
- 因此,当需要获取元素的大小或位置信息时,使用offset更为合适。
关于style:
- style仅能获取行内样式表中的样式值,且返回值带有px单位。
- style.width获取的是带有单位的字符串。
- style.width获取的值不包含padding和border。
- style.width是可读写属性,既支持获取也支持赋值【重点】。
- 因此,当需要修改元素的样式值时,应使用style进行设置。
掌握上述知识点后,即可开始动手实现具体需求。
模态框拖拽需求与逻辑分析
案例需求如下:
1. 点击弹出层链接,显示模态框及灰色半透明遮挡层。
2. 点击关闭按钮,隐藏模态框及灰色半透明遮挡层。
3. 鼠标置于模态框顶部标题栏,按住鼠标可拖拽模态框在页面中移动。
4. 鼠标松开后,模态框停止移动。
案例分析:
1. 点击弹出层链接,模态框和遮挡层的display属性设置为block以显示。2. 点击关闭按钮,模态框和遮挡层的display属性设置为none以隐藏。3. 页面内拖拽原理:按下鼠标并移动,随后松开鼠标。4. 触发事件包括:鼠标按下(mousedown)、鼠标移动(mousemove)和鼠标松开(mouseup)。5. 拖拽过程:鼠标移动时,获取最新坐标值并赋值给模态框的left和top属性,使模态框跟随鼠标移动。6. 事件源为顶部标题栏,即id为title的元素。7. 鼠标坐标减去鼠标在盒子内的相对坐标,即为模态框真正的绝对位置。8. 鼠标按下时,需计算鼠标在盒子内的相对坐标。9. 鼠标移动时,将模态框坐标设置为:鼠标坐标减去盒子内相对坐标。注意:移动事件需写在按下事件内部。10. 鼠标松开时,解除鼠标移动事件监听,停止拖拽。
完整代码实现
具体代码实现如下:
HTML结构代码:
<body>
<div class="login-header"><a id="link" href="javascript:;">点击,弹出登录框</a></div>
<div id="login" class="login">
<div id="title" class="login-title">登录会员
<span><a id="closeBtn" href="javascript:void(0);" class="close-login">关闭</a></span>
</div>
<div class="login-input-content">
<div class="login-input">
<label>用户名:</label>
<input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
</div>
<div class="login-input">
<label>登录密码:</label>
<input type="password" placeholder="请输入登录密码" name="info[password]" id="password" class="list-input">
</div>
</div>
<div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div>
</div>
<!-- 遮盖层 -->
<div id="bg" class="login-bg"></div>
<script>
</script>
</body>CSS样式代码:
<style>
.login-header {
width: 100%;
text-align: center;
height: 30px;
font-size: 24px;
line-height: 30px;
}
ul,
li,
ol,
dl,
dt,
dd,
div,
p,
span,
h1,
h2,
h3,
h4,
h5,
h6,
a {
padding: 0px;
margin: 0px;
}
.login {
display: none;
width: 512px;
height: 280px;
position: fixed;
border: #ebebeb solid 1px;
left: 50%;
top: 50%;
background: #ffffff;
box-shadow: 0px 0px 20px #ddd;
z-index: 9999;
transform: translate(-50%, -50%);
}
.login-title {
width: 100%;
margin: 10px 0px 0px 0px;
text-align: center;
line-height: 40px;
height: 40px;
font-size: 18px;
position: relative;
cursor: move;
}
.login-input-content {
margin-top: 20px;
}
.login-button {
width: 50%;
margin: 30px auto 0px auto;
line-height: 40px;
font-size: 14px;
border: #ebebeb 1px solid;
text-align: center;
}
.login-bg {
display: none;
width: 100%;
height: 100%;
position: fixed;
top: 0px;
left: 0px;
background: rgba(0, 0, 0, .3);
}
a {
text-decoration: none;
color: #000000;
}
.login-button a {
display: block;
}
.login-input input.list-input {
float: left;
line-height: 35px;
height: 35px;
width: 350px;
border: #ebebeb 1px solid;
text-indent: 5px;
}
.login-input {
overflow: hidden;
margin: 0px 0px 20px 0px;
}
.login-input label {
float: left;
width: 90px;
padding-right: 10px;
text-align: right;
line-height: 35px;
height: 35px;
font-size: 14px;
}
.login-title span {
position: absolute;
font-size: 12px;
right: -20px;
top: -30px;
background: #ffffff;
border: #ebebeb solid 1px;
width: 40px;
height: 40px;
border-radius: 20px;
}
</style>JavaScript代码:
window.onload = function() {
// 1. 获取元素
var login = document.querySelector('.login');
var mask = document.querySelector('.login-bg');
var link = document.querySelector('#link');
var closeBtn = document.querySelector('#closeBtn');
var title = document.querySelector('#title');
// 2. 点击弹出层这个链接 link 让mask 和login 显示出来
link.addEventListener('click', function() {
login.style.display = 'block';
mask.style.display = 'block';
})
// 3. 点击 closeBtn 就隐藏 mask 和 login
closeBtn.addEventListener('click', function() {
login.style.display = 'none';
mask.style.display = 'none';
});
// 4.给标题添加一个鼠标按下的事件
title.addEventListener('mousedown', function(e) {
// 获取鼠标在框内的距离
var x = e.pageX - login.offsetLeft;
var y = e.pageY - login.offsetTop;
// 5创建移动函数
function move(e) {
login.style.left = e.pageX - x + 'px';
login.style.top = e.pageY - y + 'px';
}
// 鼠标移动则触发事件
document.addEventListener('mousemove', move);
// 鼠标松移除事件
document.addEventListener('mouseup', function() {
document.removeEventListener('mousemove', move);
});
});
}提示:JS代码通常单独存放为一个文件,引入时记得确保路径正确。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。