JS 登录弹窗
我们需要做一个当用户点击登录按钮时,在页面中央弹出一个登录窗口,然后点击窗口的关闭按钮可以关闭,并且在登录窗口期间会有遮罩层防止用户点击到其他元素,而且此时浏览器是无法滚轮滑动的。
先看下效果图:
请输入图片描述
html代码:
<header id="header">
<div class="center">
<img src="https://www.mulingyuer.com/usr/themes/Yodu/images/logo.png" alt="" class="logo" />
<ul class="nav">
<li class="nav-li nav-login">登录</li>
<li class="nav-li nav-confin">
个人设置
<ul class="nav-menu">
<li class="menu-li">设置</li>
<li class="menu-li">换肤</li>
<li class="menu-li">帮助</li>
<li class="menu-li">退出</li>
</ul>
</li>
</ul>
</div>
</header>
<div id="login">
<i class="login_off">X</i>
<h2 class="login_title">网站登录</h2>
<form action="" id="login_form">
<div class="user">账 号:<input type="text" name="user" class="text" /></div>
<div class="pass">密 码:<input type="password" name="pass" class="text" /></div>
<div class="buttom"><input type="button" name="submit" value="登录" class="submit" /></div>
<div class="other">注册新用户 | 忘记密码?</div>
</form>
</div>
css代码:
#login {
position: fixed;
color: #666;
width: 350px;
font-size: 14px;
border: 1px solid orange;
text-align: center;
background-color: #fff;
clip: rect(0 0 0 0);
opacity: 0;
transition: all .5s;
}
#login_form {
line-height: 0;
background-color: #fff;
}
#login > .login_off {
position: absolute;
top: 0;right: 0;
margin-top: 8px;
margin-right: 8px;
color: #fff;
font-style: normal;
width: 14px;
line-height: 14px;
background-color: orange;
cursor: pointer;
}
#login > .login_title {
font-weight: normal;
font-size: 16px;
line-height: 30px;
letter-spacing: 1px;
background-color: #eee;
}
.user,.pass,.buttom {
line-height: 40px;
}
.user,.buttom,.other {
padding: 10px 0;
}
#login input.text {
background-color: #fff;
border: 1px solid #eee;
height: 25px;
width: 200px;
}
.buttom > input.submit {
padding: 5px 14px 5px 22px;
color: #fff;
letter-spacing: 8px;
font-weight: bold;
border: 1px solid green;
background-color: #00d82e;
background-image: linear-gradient(rgba(255,255,255,.3) 30%,rgba(0,0,0,.2));
border-radius: 2px;
cursor: pointer;
}
.other {
text-align: right;
padding-right: 8px;
font-size: 12px;
}
JS代码:
接着上一章的代码,我们要做一个修改,首先就是我们之前只有一个选项:个人设置 所以class用的是通用的nav-li,然后js部分也是通过这个class去获取这个对象,但是现在我们有多个了,如果还是用之前的方法,就会导致获取的对象是所有的li元素,然后在class的if判断时候也会出错,因为我们之前用的是:this.arr[i].className == className;而我们现在是给li加上了多个class,为此要先改动一下.class()方法。
Base.prototype.getclass = function(className, idName) {
var node = null;
if (arguments.length == 2) {
node = document.getElementById(idName);
} else {
node = document;
}
var elements = node.getElementsByTagName('*');
for (var i = 0; i < elements.length; i++) {
if (elements[i].className.match(className)) {
this.arr.push(elements[i]);
}
}
return this;
}
我们通过match的方法去判断,如果搜到了就传入arr中。
css部分我们已经做好了,我们现在只需要为 登录 选项添加click事件,然后弹出ID为login的div元素。
ligin元素我们使用了clip: rect(0 0 0 0);opacity: 0;做隐藏,所以,显示的时候做对应修改就可以了。
首先我们先获取到对应的元素并添加cilck事件:
$().getclass('nav-login','header').click(function(){});
然后在事件函数里面获取到login元素,然后将它的css改为clip: auto;opacity: 1;
$().getclass('nav-login', 'header').click(function() {
$().getId('login').css('clip','auto').css('opacity','1');
});
点击是可以显示了,但是我们还要点击login里的关闭,将窗口隐藏,那也很简单,一样获取关闭按钮的元素对象,然后添加click事件,然后再css改回去。
$().getclass('login_off','login').click(function(){
$().getId('login').css('clip','').css('opacity','');
});
将css的值传入为空的字符,这样行内css就被自动删除了。
现在显示和隐藏都可以了,我们还要将login设置为居中,那么我们要用到获取可视宽度/高度和获取元素宽度/高度的js。
获取可视宽度:document.documentElement.clientWidth;
获取可视高度:document.documentElement.clientHeight;
这里火狐最新版63他的高度会有问题,他获取的是body元素的高度,所以火狐只能使用w3c提供的innerHeight来获取,这个innerHeight新版的浏览器都已经支持,但是旧版ie不支持,所以还要做个判断。
typeof innerHeight == 'undefined' ? document.documentElement.clientHeight : innerHeight;
获取元素宽度:offsetWidth;
获取元素高度:offsetHeight;
这里获取的是border+padding+content三个盒模型的值。
于是添加一个center()自动居中的公用方法:
Base.prototype.center = function(){
var left = document.documentElement.clientWidth;
var top = typeof innerHeight == 'undefined' ? document.documentElement.clientHeight : innerHeight;
for(var i = 0;i<this.arr.length;i++) {
this.arr[i].style.top = (top - this.arr[i].offsetHeight)/2 + 'px';
this.arr[i].style.left = (left - this.arr[i].offsetWidth)/2 + 'px';
}
return this;
}
调用:
$().getclass('nav-login','header').click(function(){
$().getId('login').css('clip','auto').css('opacity','1').center();
});
$().getclass('login_off','login').click(function(){
$().getId('login').css('clip','').css('opacity','');
});
自动居中后,我们发现,这个居中只有在每次刷新后才会居中,如果用户没有刷新,只是改变了浏览器窗口的大小,这时候login还是显示在第一次出现的位置,所以我们还要做个resize事件,让浏览器窗口发生变化时重新调整位置。
Base.prototype.resize = function(fn){
window.onresize = fn;
return this;
}
自动居中没必要再写一遍获取这个对象啊,直接传入一个函数,在函数里面重新运行一遍居中就可以了。
$().getclass('nav-login','header').click(function(){
$().getId('login').css('clip','auto').css('opacity','1').center().resize(function(){
$().getId('login').center()
});
});
$().getclass('login_off','login').click(function(){
$().getId('login').css('clip','').css('opacity','');
});
这样我们基本就做好了,细节还要做一下,有以下几个地方:
- 选项点击 登录 改变背景色增加交互体验
- 添加遮罩层,防止用户误触
- 有遮罩层时页面不能滚动,无遮罩层可以滚动
选项点击 登录 改变背景色增加交互体验
$().getclass('nav-login', 'header').hover(function() {
$(this).css('background-color', 'rgba(0,0,0,.3)');
}, function() {
$(this).css('background-color', 'rgba(0,0,0,0)');
});
添加遮罩层,防止用户误触
#login {
position: fixed;
color: #666;
width: 350px;
font-size: 14px;
border: 1px solid orange;
text-align: center;
background-color: #fff;
clip: rect(0 0 0 0);
opacity: 0;
z-index: 1;
transition: all .5s;
}
#login::before {
content: "";
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, .3);
z-index: -1;
}
通过伪元素扩大形成遮罩层,这是伪元素在其他元素之上,用户点击遮罩层无法点击到下面的元素,由于是伪元素,所以省了显示和隐藏的js步骤,直接和login是同步的,但是也有一个缺点:有时候我们会添加点击遮罩层可以关闭login和遮罩层的交互效果,但是因为伪元素无法添加事件的,所以有利也有弊吧!
有遮罩层时页面不能滚动,无遮罩层可以滚动
这里我们只要在用户点击login后将html元素overflow:hidden;即可,用户关闭login再还原css,于是:
$().getclass('nav-login','header').click(function(){
$().getId('login').css('clip','auto').css('opacity','1').center().resize(function(){$().getId('login').center()});
$().getTagName('html').css('overflow','hidden');
});
$().getclass('login_off','login').click(function(){
$().getId('login').css('clip','').css('opacity','');
$().getTagName('html').css('overflow','');
});
当html的滚动条隐藏后,整个页面会自动的往右偏移,体验非常不好,为此我们利用一个小小的hack的方法,直接为布局的元素自动模拟出一条滚动条的宽度占用着,这样不管页面滚动条有还是没有,位置都是固定的了。
.center {
max-width: 500px;
margin: 0 auto;
padding-left: calc(100vw - 100%); /*模拟滚动条宽度*/
}
然后将js调用代码集中一下如下:
$().getclass('nav-login', 'header').hover(function() {
$(this).css('background-color', 'rgba(0,0,0,.3)');
}, function() {
$(this).css('background-color', 'rgba(0,0,0,0)');
});
$().getclass('nav-login', 'header').click(function() {
$().getId('login').css('clip', 'auto').css('opacity', '1').center().resize(function() {
$().getId('login').center()
});
$().getTagName('html').css('overflow', 'hidden');
});
$().getclass('login_off', 'login').click(function() {
$().getId('login').css('clip', '').css('opacity', '');
$().getTagName('html').css('overflow', '');
});
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据