拖动模态框(弹出框)
案例分析:
- 点击弹出层,模块框和灰色半透明的遮挡层就会显示出来 display:block;
- 点击关闭按钮,模块框和灰色半透明的遮挡层就会隐藏出来 display:none;
- 鼠标放到模块框最上面一行,可以按住鼠标拖拽模块框在页面中移动,触发的事件源是最上面一行,即id为title
- 鼠标松开,可以停止拖动模态框移动
- 在页面中拖拽的原理:鼠标按下并且移动,之后松开鼠标
- 触发事件是鼠标按下mousedown、鼠标移动mousemove、鼠标松开mouseup
- 拖拽过程:鼠标在移动过程中获得最新的值赋值给模态框的left和top值,这样模态框就会跟着鼠标走了
- 鼠标的坐标 - 鼠标在盒子内的坐标 = 模态框真正的位置
<head>
<style>
* {
padding: 0;
margin: 0;
}
a {
text-decoration: none;
color: #000;
}
.login {
display: none;
width: 512px;
height: 280px;
position: fixed;
border: #ebebeb solid 1px;
left: 50%;
top: 50%;
background: #fff;
box-shadow: 0px 0px 20px #ddd;
z-index: 9999;
transform: translate(-50%, -50%);
}
.login-header {
width: 100%;
height: 30px;
line-height: 30px;
font-size: 24px;
text-align: center;
}
.login-title {
position: relative;
width: 100%;
margin: 10px 0px 0px 0px;
text-align: center;
line-height: 40px;
height: 40px;
font-size: 18px;
cursor: move;
}
.login-title span {
position: absolute;
right: -20px;
top: -30px;
border: #ebebeb solid 1px;
width: 40px;
height: 40px;
border-radius: 20px;
background-color: #fff;
}
.login-input-content {
margin-top: 20px;
}
.login-input {
overflow: hidden;
margin: 0px 0px 20px 0px;
}
.login-input input {
float: left;
line-height: 35px;
height: 35px;
width: 350px;
border: #ebebeb 1px solid;
text-indent: 5px;
background-color: #fff;
}
.login-input label {
float: left;
width: 90px;
padding-right: 10px;
text-align: right;
line-height: 35px;
height: 35px;
font-size: 14px;
}
.login-button {
width: 50%;
line-height: 40px;
font-size: 14px;
margin: 30px auto 0px auto;
border: #ebebeb 1px solid;
text-align: center;
}
.login-button a {
display: block;
}
.login-bg {
display: none;
width: 100%;
height: 100%;
position: fixed;
top: 0px;
left: 0px;
background: rgba(0, 0, 0, 0.3);
}
</style>
</head>
<body>
<div class="login-header">
<a href="javascript:;" id="link">点击,弹出登录框</a>
</div>
<div class="login">
<div id="title" class="login-title">
登录会员
<span
><a href="javascrip:;" id="closeBtn" class="close-login"
>关闭</a
></span
>
</div>
<div class="login-input-content">
<div class="login-input">
<label>用户名</label>
<input type="text" placeholder="请输入用户名" class="list-input" />
</div>
<div class="login-input">
<label>密码</label>
<input
type="passwords"
placeholder="请输入登录密码"
class="list-input"
/>
</div>
</div>
<div id="loginBtn" class="login-button">
<a href="javascript" id="login-button-submit">登录会员</a>
</div>
</div>
<!-- 遮罩层 -->
<div id="bg" class="login-bg"></div>
<script>
// 1. 获取元素
var link = document.querySelector("#link");
var login = document.querySelector(".login");
var closeBtn = document.querySelector("#closeBtn");
var mask = document.querySelector(".login-bg");
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. 开始拖拽
// (1) 当我们鼠标按下, 就获得鼠标在盒子内的坐标
title.addEventListener("mousedown", function (e) {
var x = e.pageX - login.offsetLeft;
var y = e.pageY - login.offsetTop;
// (2) 鼠标移动的时候,把鼠标在页面中的坐标,减去 鼠标在盒子内的坐标就是模态框的left和top值
document.addEventListener("mousemove", move);
function move(e) {
login.style.left = e.pageX - x + "px";
login.style.top = e.pageY - y + "px";
}
// (3) 鼠标弹起,就让鼠标移动事件移除
document.addEventListener("mouseup", function () {
document.removeEventListener("mousemove", move);
});
});
});
</script>
</body>
</html>
仿京东放大镜效果
案例分析:
整个案例分为3个功能模块
1、鼠标经过小图片盒子,黄色的遮挡层和大图片盒子显示,离开隐藏2个盒子功能
2、黄色的遮挡层跟随鼠标功能
- 把鼠标坐标给遮挡层不合适,因为遮挡层坐标以父盒子为准
- 首先是获得鼠标在盒子的坐标,之后把数值给给遮挡层做为left值和top值
- 此时用到鼠标移动事件,但是还是在小图片盒子内移动
- 发现遮挡层的位置不对(鼠标在遮挡层的顶点,要在遮挡层的中间),需要减去盒子自身的高度和宽度的一半
- 遮挡层不能超出小图片盒子范围 如果小于0,就把坐标设置为0,如果大于遮挡层最大的移动距离,就把坐标设置为最大的移动距离
- 遮挡层的最大移动距离:小图片盒子的宽度减去遮挡层盒子宽度
3、移动黄色遮挡层,大图片跟随移动功能
- 求大图片的移动距离公式:遮挡层距离/遮挡层最大移动距离=大图片距离/大图片最大移动距离
detail.html
<head>
<link rel="stylesheet" href="detail.css" />
<script src="detail.js"></script>
</head>
<body>
<div class="w">
<div class="preview_img">
<img src="../image/s3.png" alt="" />
<div class="mask"></div>
<div class="big">
<img src="../image/big.jpg" alt="" class="bigImg" />
</div>
</div>
</div>
</body>
</html>
detail.css
*{
padding: 0;
margin: 0;
}
.w {
width: 1200px;
margin: 0 auto;
}
.preview_img{
position: relative;
width: 398px;
height: 398px;
margin: 50px;
border: 1px solid #ccc;
}
.preview_img img{
vertical-align: middle;
}
.mask{
display: none;
position: absolute;
top: 0;
left: 0;
height: 298px;
width: 298px;
background-color: #FEDE4F;
border: 1px solid #ccc;
opacity: .5;
cursor: move;
}
.big{
display: none;
position: absolute;
top: 0;
left: 410px;
width: 498px;
height: 498px;
/* background-color: pink; */
border: 1px solid #ccc;
overflow: hidden;
}
.big img{
position: absolute;
left: 0;
top: 0;
}
detail.js
window.addEventListener('load', function() {
var preview_img = document.querySelector('.preview_img');
var mask = document.querySelector('.mask');
var big = document.querySelector('.big');
// 1. 当我们鼠标经过 preview_img 就显示和隐藏 mask 遮挡层 和 big 大盒子
preview_img.addEventListener('mouseover', function() {
mask.style.display = 'block';
big.style.display = 'block';
})
preview_img.addEventListener('mouseout', function() {
mask.style.display = 'none';
big.style.display = 'none';
})
// 2. 鼠标移动的时候,让黄色的盒子跟着鼠标来走
preview_img.addEventListener('mousemove', function(e) {
// (1). 先计算出鼠标在盒子内的坐标
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
// console.log(x, y);
// (2) 减去盒子高度 300的一半 是 150 就是我们mask 的最终 left 和top值了
// (3) 我们mask 移动的距离
var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;
// (4) 如果x 坐标小于了0 就让他停在0 的位置
// 遮挡层的最大移动距离
var maskMax = preview_img.offsetWidth - mask.offsetWidth;
if (maskX <= 0) {
maskX = 0;
} else if (maskX >= maskMax) {
maskX = maskMax;
}
if (maskY <= 0) {
maskY = 0;
} else if (maskY >= maskMax) {
maskY = maskMax;
}
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';
// 3. 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离
// 大图
var bigIMg = document.querySelector('.bigImg');
// 大图片最大移动距离
var bigMax = bigIMg.offsetWidth - big.offsetWidth;
// 大图片的移动距离 X Y
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
bigIMg.style.left = -bigX + 'px';
bigIMg.style.top = -bigY + 'px';
})
})