点击登录出现登陆框,鼠标在标题位置处按下并移动,登录框就会移动,实现拖动效果,鼠标弹起之后拖动效果消失。
图示效果:
难点:我想到了计算当前登陆框位置的方法,即用鼠标在页面中的坐标减去鼠标在盒子内的坐标,鼠标按下,鼠标移动,鼠标弹起三个事件的组合使用也想到了,但是卡在了怎么计算登陆框位置,首先我想到可以:
e.pageY - (e.pageY - sign.offsetTop); //Y方向位置
e.pageY - (e.pageY - sign.offsetTop); //X方向位置
但是明显这样不可以,因为最后就剩下offset值了,相当于一个确定值,这时候其实可以把鼠标在盒子内的坐标计算放在鼠标移动事件的外面,这样想:鼠标移动只会更新e.pageX和e.pageY,鼠标在盒子内的坐标是一个定值,两者相减之后得到的就是一个变化的值
h.addEventListener('mousedown', function (e) {
var x = e.pageX - sign.offsetLeft;
var y = e.pageY - sign.offsetTop; //不能把这个放在移动事件里面,因为:两个变量相减最后只剩下offsetTop和offsetLeft了,也就是放在移动事件里面,为什么不可以直接等于offset,因为直接等于offset,这样就永远不会改变。只有放在这里是可以在鼠标按下的时候就算出此刻鼠标在盒子里面的坐标,后面在鼠标移动事件中减去这个固定值即可,这样得到的才是一个变量。·
//这时候获得的鼠标在盒子内部的坐标就是一个固定值
//当鼠标移动的时候盒子的left和top值应该是鼠标在页面中的坐标减去鼠标在盒子内的坐标,又因为按下之后鼠标在盒子内的坐标保持不变,所以盒子的位置就会跟随鼠标的移动发生变化
//(2)鼠标在页面中的坐标减去鼠标在盒子内的坐标(上面算出的固定值)就是盒子应该移动到的位置
document.addEventListener('mousemove', fn);
function fn(e) { //这里不要忘记加e
sign.style.top = e.pageY - y + 'px';//注意这里要加单位
sign.style.left = e.pageX - x + 'px';
}
//(3)给h添加鼠标弹起的时候删除鼠标移动事件这个事件
h.addEventListener('mouseup', function () {
document.removeEventListener('mousemove', fn); //注意要给document删除事件,注意删除事件的格式
})
})
下面附上完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
height: 2000px;
}
.w {
position: relative;
width: 1200px;
margin: 0 auto;
text-align: center;
}
.eject {
position: absolute;
top: 200px;
left: 50%;
transform: translateX(-50%);
width: 160px;
height: 30px;
line-height: 30px;
background-color: skyblue;
border: 0;
outline: none;
font-size: 16px;
border-radius: 12px;
/* display: none; */
}
.sign {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 500px;
height: 267px;
background-color: rgb(151, 208, 208);
/* margin: 200px auto 0; */
display: none;
/* font-size: 16px; */
}
.sign h3 {
padding-left: 208px;
padding-top: 20px;
font-weight: 400;
}
.sign h3:hover {
cursor: move;
}
.uname {
margin-top: 20px;
}
.password {
margin-top: 20px;
}
.sign span {
display: inline-block;
width: 100px;
margin-left: 20px;
text-align: right;
/* vertical-align: top; */
}
input {
/* margin-left: 50px; */
width: 350px;
height: 40px;
border: 1px solid #ccc;
outline: none;
font-size: 16px;
color: rgb(144, 143, 143);
}
.ejectbtn {
width: 200px;
height: 40px;
margin-top: 30px;
margin-left: 150px;
font-size: 16px;
background-color: #fff;
border: 1px solid #ccc;
}
.sign .close {
position: absolute;
top: -20px;
right: -20px;
width: 40px;
height: 40px;
background-color: #fff;
border: 0;
border-radius: 20px;
}
button:hover {
cursor: pointer;
}
.mask {
width: 100%;
height: 100%;
background-color: #ccc;
display: none;
}
</style>
</head>
<body>
<!-- 效果:点击登录之后弹出登陆框,提示用户输入用户名和密码,登录会员
同时,整个登录框可以拖动,页面背景变为灰色 -->
<div class="w">
<button class="eject">点击弹出登录框</button>
</div>
<div class="sign">
<h3>登录会员</h3>
<div class="uname"><span>用户名:</span><input type="text" value="请输入用户名"></div>
<div class="password"><span>登录密码:</span><input type="text" value="请输入登录密码"></div>
<button class="ejectbtn">登录会员</button>
<button class="close">关闭</button>
</div>
<!-- 遮罩层 -->
<div class="mask"></div>
</body>
<script>
//设置input的行为,获得焦点后value清空,然后用户输入内容,失去焦点保留内容,再次获得焦点不清空内容
//设置eject的行为,点击之后弹出用户输入界面
//设置button close的行为,点击之后关闭这个框,display:none;
var ipts = document.querySelectorAll('input');
console.log(ipts);
ipts[0].addEventListener('focus', function () {
if (this.value === '请输入用户名') {
this.value = '';
}
})
ipts[0].addEventListener('blur', function () {
if (this.value === '') {
this.value = '请输入用户名';
}
})
ipts[1].addEventListener('focus', function () {
if (this.value === '请输入登录密码') {
this.value = '';
this.type = 'password';
}
})
ipts[1].addEventListener('blur', function () {
if (this.value === '') {
this.value = '请输入登录密码';
this.type = 'text';
}
})
var eject = document.querySelector('.eject');
var close = document.querySelector('.close');
var sign = document.querySelector('.sign');
var body = document.querySelector('body');
var mask = document.querySelector('.mask');
eject.addEventListener('click', function () {
mask.style.display = 'block';
sign.style.display = 'block';
})
close.addEventListener('click', function () {
sign.style.display = 'none';
mask.style.display = 'none';
})
//设置拖动登陆框的效果
//思路:鼠标按下触发,获得鼠标的位置,e.pageX
var h = document.querySelector('h3');
//(1)鼠标按下之后获得鼠标在盒子里面的坐标,注意这里规定了只有在h3里面按下才有效果
h.addEventListener('mousedown', function (e) {
var x = e.pageX - sign.offsetLeft;
var y = e.pageY - sign.offsetTop; //不能把这个放在移动事件里面,因为:两个变量相减最后只剩下offsetTop和offsetLeft了,也就是放在移动事件里面,为什么不可以直接等于offset,因为直接等于offset,这样就永远不会改变。只有放在这里是可以在鼠标按下的时候就算出此刻鼠标在盒子里面的坐标,后面在鼠标移动事件中减去这个固定值即可,这样得到的才是一个变量。·
//这时候获得的鼠标在盒子内部的坐标就是一个固定值
//当鼠标移动的时候盒子的left和top值应该是鼠标在页面中的坐标减去鼠标在盒子内的坐标,又因为按下之后鼠标在盒子内的坐标保持不变,所以盒子的位置就会跟随鼠标的移动发生变化
//(2)鼠标在页面中的坐标减去鼠标在盒子内的坐标(上面算出的固定值)就是盒子应该移动到的位置
document.addEventListener('mousemove', fn);
function fn(e) { //这里不要忘记加e
sign.style.top = e.pageY - y + 'px';//注意这里要加单位
sign.style.left = e.pageX - x + 'px';
}
//(3)给h添加鼠标弹起的时候删除鼠标移动事件这个事件
h.addEventListener('mouseup', function () {
document.removeEventListener('mousemove', fn); //注意要给document删除事件,注意删除事件的格式
})
})
</script>
</html>