效果展示和需求分析
效果展示
需求分析
- 点击登录后登录表单和遮罩层显示,点击关闭按钮隐藏。
- 输入密码时可以明文查看或者隐藏。
- 在表单的头部按下鼠标后可以拖拽表单。
- 鼠标弹起拖拽结束。
代码分析
HTML 代码
<body>
<a href="javascript:;" class="login">登录我的账号</a>
<form action="">
<h4>账号登录</h4>
<div class="login-items">
<label for="uname">用户名:</label >
<input type="text" placeholder="请输入用户名" id="uname">
</div>
<div class="login-items">
<label for="psw">登录密码:</label>
<input type="password" name="" id="psw" placeholder="请输入您的密码">
<span class="close" id="eye-state"></span>
</div>
<a href="javascript:;" class="login-btn">登录账号</a >
<a href="javascript:;" class="close-btn">关闭</a >
</form>
<div id="bg" class="login-bg"></div>
</body>
<script src="js/模态框.js"></script>
js 代码
var eyeState = document.querySelector('#eye-state');
var pswInput = document.querySelector('#psw');
var login = document.querySelector('.login');
var loginBg = document.querySelector('#bg');
var loginForm = document.querySelector('form');
var closeBtn = document.querySelector('.close-btn');
var eyeFlag = 0;
eyeState.onclick = setEye;
login.onclick = goLogin;
closeBtn.onclick = leaveLogin;
loginForm.children[0].addEventListener('mousedown', dragForm);
// 表单内容不可选,不然看着不舒服
loginForm.onselectstart = function(e) {
e.preventDefault();
}
// 1、实现小眼睛改变密码输入状态
function setEye() {
if (!eyeFlag) {
eyeState.className = 'open';
pswInput.type = 'text';
eyeFlag = 1;
} else {
eyeState.className = 'close';
pswInput.type = 'password';
eyeFlag = 0;
}
}
// 2、外面登录按钮实现表单、遮罩层的显示和它自己隐藏
function goLogin() {
loginBg.style.visibility = 'visible';
loginForm.style.display = 'block';
this.style.display = 'none';
}
// 3、关闭按钮实现表单、遮罩层的隐藏和外面登录按钮的显示
function leaveLogin() {
loginBg.style.visibility = 'hidden';
loginForm.style.display = 'none';
login.style.display = 'block';
}
// 4、实现表单拖拽效果
function dragForm(e) {
// 当鼠标在表单的标题按下时获取它在表单元素内的坐标并绑定移动事件
var x = e.pageX - this.parentNode.offsetLeft;
var y = e.pageY - this.parentNode.offsetTop;
document.addEventListener('mousemove', move);
// 鼠标弹起移除移动事件
this.addEventListener('mouseup', function() {
document.removeEventListener('mousemove', move)
});
function move(event) {
loginForm.style.left = event.pageX - x + 'px';
loginForm.style.top = event.pageY - y + 'px';
}
}
分析
- 密码输入框,在点击后面的眼睛即 span 元素时通过 eyeFlag 变量来判断设置表单的 type 属性和 span 的类名(该用哪个小眼睛图)。
- 鼠标是在表单标题区域按下后才有拖拽效果所以给标题绑定 mousedown 事件。
- mousemove 和 mouseup 事件在鼠标按下后分别绑定给 document 和 this(标题)。
在实现拖拽时将 mousemove 事件绑定给标题的话会出现 bug 。快速拖拽时鼠标会离开标题导致表单没有跟上。所以要将这个事件绑定给 document 。
表单跟随鼠标的原理:在鼠标按下时根据鼠标和表单在页面的坐标得到它在表单的坐标(拖拽过程这个位置是不变的)。在鼠标移动过程根据鼠标在页面的动态坐标和它在表单的坐标即可获得表单在页面的动态坐标。