可拖动弹窗的JS和jQuery两种写法

      最近在慕课网上学习了一个网页可拖动对话框js实现的演示视频,这个demo中的例子是百度首页登录按钮的弹窗,如下图:

1611211456_1_thumb1

       当点击左上角的登录按钮时,弹窗出现并自动居中,同时窗口可拖动的范围被限制在了可视区域内,即浏览器视窗的上下左右边界,弹窗无法移出移动出四个边界,也不会出现滚动条。

1611211459_2_thumb31611211504_3_thumb21611211505_4_thumb2

      另一个效果就是,当改变窗口大小时,对话框自动居中

      这个视频中用了原生js,jQuery两种写法实现案例,但本质上,对话框居中,限制拖动范围的的计算思路是一致的。

      为了简化页面,总结核心思路,我重新写了一个小demo,界面如下:

1611211515_5_thumb2

1611211516_6_thumb2               1611211524_7_thumb3

      依旧保持着点击弹出按钮,对话框自动居中,拖动范围限制,改变窗口大小弹窗居中等效果,下面是本demo的HTMl结构和CSS布局代码:

HTML结构代码

<div id="callout" class="button callout_button"><a href="#">弹出对话框</a></div>
<div id="mask" class="mask"></div>
<div class="dialog" id="dialog">
    <div class="dialog_head" id="move_part">可拖拽部分</div>
    <div class="dialog_content"></div>
    <div class="button close_button" id="close"><a href="#">点我关闭对话框</a>
    </div>
</div>

CSS样式代码

<style type="text/css">
    a{text-decoration: none; color: #eee; display: block;}
    .button{width: 200px; height: 50px; border-radius: 20px; text-align:center;line-height: 50px;}
    .callout_button{background:#FF5B5B;margin:0 auto; }
    .callout_button:hover{background: red;}
    .close_button{background:#363636;margin:0 auto;}
    .close_button:hover{background: black;}
    .mask{width: 100%;height: 100%;background:#000;position: absolute;top: 0px;left:0px;opacity: 0.4;z-index: 8000; display: none;-moz-user-select: none; -webkit-user-select: none;}
    .dialog{width: 380px;background:#fff; position: absolute;z-index: 9000;padding-bottom: 10px; display: none;-moz-user-select: none; -webkit-user-select: none;}
    .dialog_head{width: 100%;height:50px;background:#4B4B4B;text-align: center;line-height: 50px;color: #eee; cursor: move;}
    .dialog_content{width: 100%;height:300px;}
</style>

下面是重点的JS部分,先介绍

一、原生JS的写法:

这里有一个比较实用的技巧,首先定义一个g()函数用于获取对象

function g(id){return document.getElementById(id)};

这个函数用起来很方便,用于获取对象,在原生JS种可以少写很多代码,有一点JS封装的思想(感觉上,不知道说的对不对)。

弹出和关闭对话框

//点击弹出对话框
        g('callout').onclick = function(){
            g('dialog').style.display = 'block';
             g('mask').style.display = 'block';
             autoCenter(g('dialog'));
        };
//点击关闭对话框
        g('close').onclick = function(){
            g('dialog').style.display = 'none';
             g('mask').style.display = 'none';
        };

点击拖动对话框有个重要的内容就是要设置对话框内容不可被选中

//禁止选中对话框内容
        if(document.attachEvent) {//ie的事件监听,拖拽div时禁止选中内容,firefox与chrome已在css中设置过-moz-user-select: none; -webkit-user-select: none;
            g('dialog').attachEvent('onselectstart', function() {
              return false;
            });
        }

点击弹出对话框中代码中的autoCenter()函数,让对话框保持自动居中

function autoCenter(el){
            //获取可见窗口大小
            var bodyW = document.documentElement.clientWidth;
            var bodyH = document.documentElement.clientHeight;
            //获取对话框宽、高
            var elW = el.offsetWidth;
            var elH = el.offsetHeight;

            el.style.left = (bodyW - elW)/2 + 'px';
            el.style.top = (bodyH - elH)/2 + 'px';
        };

当窗口改变大小时,对话框自动居中

//窗口大小改变时,对话框始终居中
        window.onresize = function(){
            autoCenter(g('dialog'));
        };

最核心的部分来了,对话框拖动的实现这个效果的实现要分为三个步骤:

1.鼠标点击时,设置对话框可拖动,记录鼠标的初始位置;

2.鼠标拖动时,根据鼠标新位置更新对话框位置(有两种算法);

3.鼠标离开时移出对话框可拖动属性;

第一步:鼠标按下时

//声明需要用到的变量
        var mx = 0,my = 0;      //鼠标x、y轴坐标(相对于left,top)
        var dx = 0,dy = 0;      //对话框坐标(同上)
        var isDraging = false;      //不可拖动

        //鼠标按下
        g('move_part').addEventListener('mousedown',function(e){
            var e = e || window.event;
            mx = e.pageX;      //点击时鼠标X坐标
              my = e.pageY;      //点击时鼠标Y坐标
              dx = g('dialog').offsetLeft;
            dy = g('dialog').offsetTop;
            isDraging = true;      //标记对话框可拖动
        });

第二步:鼠标移动时

document.onmousemove = function(e){
            var e = e || window.event;
            var x = e.pageX;      //移动时鼠标X坐标
              var y = e.pageY;      //移动时鼠标Y坐标
              if(isDraging){        //判断对话框能否拖动
                var moveX = dx + x - mx;      //移动后对话框新的left值
                var moveY = dy + y - my;      //移动后对话框新的top值
                g('dialog').style.left = moveX +'px';       //重新设置对话框的left
              g('dialog').style.top =  moveY +'px';     //重新设置对话框的top

            };
};

前面提过更新对话框位置有两种算法,这里用的是第一种方法:

       先算出鼠标移动的坐标偏移量,用对话框的位置(对话框top,left值)加上这个偏移量就是对话框新的位置;

这种方法是参考了另一篇博客,原文地址http://www.jb51.net/article/67663.htm,慕课网的教学视频中采用的是另一种算法:

       先算出鼠标按下时的坐标和对话框位置(对话框top,left值)的距离,再用鼠标移动的新坐标减去得到的距离更新对话框位置;即

     moveX = mx – (x – dx);

      moveY = my – (y – dy);

无论哪种办法都可以实现对话框的拖动。

第三步:鼠标离开时

//鼠标离开
        g('move_part').addEventListener('mouseup',function(){
            isDraging = false;
        });

这一步比较简单,重新设置对话框不可拖动。

另一个比较重要的是限制对话框的拖动范围,代码如下(这段代码应插入到第二步的if判断中

//设置拖动范围
                  var pageW = document.documentElement.clientWidth;
                var pageH = document.documentElement.clientHeight;
                var dialogW = g('dialog').offsetWidth;
                var dialogH = g('dialog').offsetHeight;
                var maxX = pageW - dialogW;       //X轴可拖动最大值
                   var maxY = pageH - dialogH;       //Y轴可拖动最大值
                   moveX = Math.min(Math.max(0,moveX),maxX);     //X轴可拖动范围
                   moveY = Math.min(Math.max(0,moveY),maxY);     //Y轴可拖动范围

                  g('dialog').style.left = moveX +'px';       //重新设置对话框的left
                g('dialog').style.top =  moveY +'px';        //重新设置对话框的top

限制对话框在可视窗口内拖动,原理就是设置合理的对话框的left、top值范围,其中

     left值的范围是:【0,pageW – dialogW】

     top值的范围是:【0,pageH – dialogH】

需要注意的是给这两个值设定范围的Math.max(),Math.min()方法。

下面是jQuery写法的具体代码,由于原理在JS部分中已有介绍,这里就不赘述了。

二、jQuery写法

$(document).ready(function(){
            var $dialog = $("#dialog");
            var $mask = $("#mask");
            
            //自动居中对话框
            function autoCenter(el){
                var bodyW = $(window).width();
                var bodyH = $(window).height();
                var elW = el.width();
                var elH = el.height();
                $dialog.css({"left":(bodyW-elW)/2 + 'px',"top":(bodyH-elH)/2 + 'px'});        
            };
            
            //点击弹出对话框
            $("#callout").click(function(){
                $dialog.css("display","block"); 
                $mask.css("display","block");
                autoCenter($dialog); 
            });            
            
            //禁止选中对话框内容
            if(document.attachEvent) {//ie的事件监听,拖拽div时禁止选中内容,firefox与chrome已在css中设置过-moz-user-select: none; -webkit-user-select: none;
                g('dialog').attachEvent('onselectstart', function() {
                  return false;
                });
            }
            //声明需要用到的变量
            var mx = 0,my = 0;      //鼠标x、y轴坐标(相对于left,top)
            var dx = 0,dy = 0;      //对话框坐标(同上)
            var isDraging = false;      //不可拖动

            //鼠标按下
            $("#move_part").mousedown(function(e){
                e = e || window.event;
                mx = e.pageX;     //点击时鼠标X坐标
                my = e.pageY;     //点击时鼠标Y坐标
                dx = $dialog.offset().left;
                dy = $dialog.offset().top;
                isDraging = true;      //标记对话框可拖动                
            });

            //鼠标移动更新窗口位置
            $(document).mousemove(function(e){
                var e = e || window.event;
                var x = e.pageX;      //移动时鼠标X坐标
                var y = e.pageY;      //移动时鼠标Y坐标
                if(isDraging){        //判断对话框能否拖动
                    var moveX = dx + x - mx;      //移动后对话框新的left值
                    var moveY = dy + y - my;      //移动后对话框新的top值
                    //设置拖动范围
                    var pageW = $(window).width();
                    var pageH = $(window).height();
                    var dialogW = $dialog.width();
                    var dialogH = $dialog.height();
                    var maxX = pageW - dialogW;       //X轴可拖动最大值
                    var maxY = pageH - dialogH;       //Y轴可拖动最大值
                    moveX = Math.min(Math.max(0,moveX),maxX);     //X轴可拖动范围
                    moveY = Math.min(Math.max(0,moveY),maxY);     //Y轴可拖动范围
                    //重新设置对话框的left、top
                    $dialog.css({"left":moveX + 'px',"top":moveY + 'px'});
                };
            });

            //鼠标离开
            $("#move_part").mouseup(function(){
                isDraging = false;
            });

            //点击关闭对话框
            $("#close").click(function(){
                $dialog.css("display","none");
                $mask.css("display","none");
            });

            //窗口大小改变时,对话框始终居中
            window.onresize = function(){
                autoCenter($dialog);
            };
        });

注意分析对比原生JS和jQuery的异同点!获取元素宽高,绑定事件等的写法………….

三、末尾

可拖拽对话框效果实现,JS和jQuery两种写法就是这样了,感谢前人栽阴!

同时学海无涯苦作舟,js插件不仅要会用,努力弄懂一个又一个效果的实现原理,自己能写出来才是真的懂了,共勉!!!

转载于:https://www.cnblogs.com/adventureofraindrop/p/6086298.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值