可拖拽的登陆弹窗

练习制作的一个可拖拽的登陆弹窗

  • 点击页面头部登陆按钮,弹出登陆弹窗和遮罩,并禁用滚动条;
  • 点击弹窗里的关闭按钮,关闭登陆弹窗和遮罩,并还原滚动条;
  • 弹窗可以在视口区域任意位置拖动,但是不可移出浏览器边缘;
  • 不管关闭前弹窗移动到任何位置,每次点击登录打开弹窗都在视口上下左右居中显示;
  • 当弹窗居于浏览器视口右边缘或者下边缘时,调整浏览器大小时弹窗也不会超出浏览器边缘,会始终贴着右边缘或者下边缘;
    <i> 效果图如下:</i>
初始效果-带滚动条
点击登录-弹窗&遮罩
可拖动-不会拖到浏览器视口外
html部分


<header class="header">
<div class="logo"><img src="imgs/logo.png" alt="logo.png"></div>
<button class="login">登陆</button>
</header>


<div id="mask"></div>

<div id="login-pop">
<form class="form">
<h2>登陆弹窗<span class="close">X</span></h2>
<div class="field">
<label for="userName">用户名:</label>
<input type="text" name="userName" id="userName" placeholder="请输入用户名">
</div>
<div class="field">
<label for="password">密码:</label>
<input type="password" name="password" id="password" placeholder="请输入密码">
</div>
<button id="loginbtn">登录</button>
</form>
</div>

<p>1</p><p>1</p><p>1</p><p>1</p> <p>1</p> <p>1</p> <p>1</p>
<p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p>
<p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p>
<p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p>
<p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p>
<p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p>
<p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p>
<p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p> <p>1</p>
<p>1</p> <p>1</p> <p>1</p> <p>1</p>

css部分

/*头部*/
* {margin:0; padding:0; }
body {font-size:14px; color:#333; position: relative; }
.header {width: 980px; height:50px; margin: 0 auto; background-color: #efefef; border-radius: 0 0 5px 5px; }
.header .logo {float:left; }
.header .logo img {height: 50px; }
.login{float: right; margin: 15px; cursor: pointer; }
/*遮罩*/
#mask{z-index: 9; background-color: #000; opacity:0.3; width: 100%; height: 100%; position: fixed; top: 0; left: 0; display: none; }
/*登陆弹窗*/
#login-pop{z-index: 10; width: 300px; height: 230px; background-color: #fff; position: absolute; text-align: center; display: none; }
#login-pop h2 {height:50px; line-height:50px; text-align:center; font-size:16px; letter-spacing:5px; color:#666; border-bottom:1px solid #ccc; margin:0 0 30px 0; position: relative; cursor: move; }
#login-pop .close{position: absolute; right: 10px; cursor: pointer; }
#login-pop .field{margin-bottom: 20px; }
#login-pop .field label{width: 60px; text-align: right; display: inline-block; }
#login-pop #loginbtn{width: 100px; height: 40px; line-height: 40px; background-color: green; border: none; color: #fff; font-size: 16px; border-radius: 5px; cursor: pointer; }
</code>

  • 弹窗的绝对定位的位置坐标是通过js实现的;
js部分
var 
//获取登陆弹窗div——loginPop
//获取弹窗的头部h2——move
loginPop = document.getElementById("login-pop"),
move = document.getElementsByTagName("h2")[0];
//给move添加鼠标按下事件
move.addEventListener("mousedown",function (e) {
    //获取事件触发时按下点距浏览器当前窗口的水平坐标(e.clientX)和垂直坐标(e.clientX)
    //以及此时登陆弹窗左边缘和上边缘距浏览器左边缘和上边缘的距离offsetLeft和offsetTop
    //计算得到鼠标按下点距登陆弹窗左边缘和上边缘的距离diffX、diffY
    var diffX = e.clientX - loginPop.offsetLeft,
        diffY = e.clientY - loginPop.offsetTop;
    //利用IE独有的方法setCapture,鼠标按下时捕获鼠标移出浏览器的事件
    //配合下面releaseCapture,鼠标弹起时释放
    //解决IE在限制弹窗移出浏览器失效的bug
    if (typeof loginPop.setCapture != 'undefined') {
        loginPop.setCapture();
    }
    //鼠标在弹窗头部按下时,给document添加鼠标移动事件
    //从而让弹窗可以在document范围内移动
    document.addEventListener("mousemove",mousemove); 
    function mousemove(e) {
        //实时获取鼠标移动事件触发时按住点距浏览器当前窗口的水平坐标(e.clientX)和垂直坐标(e.clientX)
        //根据上面计算得到的diffX、diffY
        //计算移动后登陆弹窗位置参数left、top
        var left = e.clientX - diffX;
        var top = e.clientY - diffY;
        //当登陆弹窗移出浏览器左边缘时left<0,
        //当弹窗移出浏览器右边缘时left > getInner().width - loginPop.offsetWidth
        //限制弹窗移出浏览器左右边缘
        // 上下边缘同理
        if (left < 0) {
            left = 0;
        } else if (left > getInner().width - loginPop.offsetWidth) {
            left = getInner().width - loginPop.offsetWidth;
        }               
        if (top < 0) {
            top = 0;
        } else if (top > getInner().height - loginPop.offsetHeight) {
            top = getInner().height - loginPop.offsetHeight;
        }
        loginPop.style.left = left + 'px';
        loginPop.style.top = top + 'px';
    }
    // 给document添加鼠标弹起事件
    // 鼠标弹起时移出鼠标的移动事件和弹起事件自身
    // 鼠标弹起时弹窗停止在当前位置
    document.addEventListener("mouseup",mouseup);
    function mouseup() {
        document.removeEventListener("mousemove",mousemove);
        document.removeEventListener("mouseup",mouseup);
        //配合上面的setCapture
        if (typeof loginPop.releaseCapture != 'undefined') {
            loginPop.releaseCapture();
        }
    }
});
// 浏览器的window添加窗口大小的监听事件
// 当浏览器大小变化时,判断弹窗当前位置是否超出浏览器的右边缘或者下边缘
// 当超出时强制赋值使其定位在浏览器边缘
window.addEventListener("resize",fn);
function fn() {
    if (loginPop.offsetLeft > getInner().width - loginPop.offsetWidth) {
        loginPop.style.left = getInner().width - loginPop.offsetWidth + 'px';
    }
    if (loginPop.offsetTop > getInner().height - loginPop.offsetHeight) {
        loginPop.style.top = getInner().height - loginPop.offsetHeight + 'px';
    }
};  
// 遮罩
// 获取头部的登陆按钮login,弹窗的关闭按钮close、遮罩div mask
var login = document.getElementsByClassName("login")[0],
    close = document.getElementsByClassName("close")[0],
    mask = document.getElementById("mask");
// 头部的登陆按钮添加点击事件
login.addEventListener("click",function(){ 
    // 设置弹窗居中
    center(300,230);
    // 显示遮罩
    mask.style.display = "block";
    // 显示弹窗 
    loginPop.style.display = "block";
    // 禁用滚动条
    document.documentElement.style.overflow = 'hidden';
});
// 弹窗的关闭按钮点击事件
close.addEventListener("click",function(){ 
    // 隐藏遮罩和登陆弹窗
    mask.style.display = "none"; 
    loginPop.style.display = "none"; 
    // 还原滚动条默认状态
    document.documentElement.style.overflow = 'auto';
}); 
// 登陆弹窗居中,两个参数分别是弹窗的宽高
function center(width, height) {
    //通过浏览器的视口大小减去弹窗大小后除以2确定弹窗的绝对定位位置参数top、left
    var top = (getInner().height - height) / 2,
        left = (getInner().width - width) / 2;
    loginPop.style.top = top + 'px';
    loginPop.style.left = left + 'px';
}
//跨浏览器获取视口大小
function getInner() {
    //非IE浏览器,支持innerWidth、innerHeight
    if (typeof window.innerWidth != 'undefined') { 
        return {
            width : window.innerWidth,
            height : window.innerHeight
        }
    } else {
        //IE浏览器,不支持innerWidth、innerHeight
        //支持documentElement.clientWidth、documentElement.clientHeight
        return {
            width : document.documentElement.clientWidth,
            height : document.documentElement.clientHeight
        }
    }
}
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容