可拖动弹窗的JS和jQuery两种写法
最近在慕课⽹上学习了⼀个⽹页可拖动对话框js实现的演⽰视频,这个demo中的例⼦是百度⾸页登录按钮的弹窗,如下图:
当点击左上⾓的登录按钮时,弹窗出现并⾃动居中,同时窗⼝可拖动的范围被限制在了可视区域内,即浏览器视窗的上下左右边界,弹窗⽆法移出移动出四个边界,也不会出现滚动条。
另⼀个效果就是,当改变窗⼝⼤⼩时,对话框⾃动居中。
这个视频中⽤了原⽣js,jQuery两种写法实现案例,但本质上,对话框居中,限制拖动范围的的计算思路是⼀致的。
为了简化页⾯,总结核⼼思路,我重新写了⼀个⼩demo,界⾯如下:
依旧保持着点击弹出按钮,对话框⾃动居中,拖动范围限制,改变窗⼝⼤⼩弹窗居中等效果,下⾯是本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){ElementById(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';
p = (bodyH - elH)/2 + 'px';
};
当窗⼝改变⼤⼩时,对话框⾃动居中
//窗⼝⼤⼩改变时,对话框始终居中
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; //标记对话框可拖动
});
第⼆步:⿏标移动时
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').p = moveY +'px'; //重新设置对话框的top
};
};
前⾯提过更新对话框位置有两种算法,这⾥⽤的是第⼀种⽅法:
先算出⿏标移动的坐标偏移量,⽤对话框的位置(对话框top,left值)加上这个偏移量就是对话框新的位置;
这种⽅法是参考了另⼀篇博客,原⽂地址,慕课⽹的教学视频中采⽤的是另⼀种算法:
先算出⿏标按下时的坐标和对话框位置(对话框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').p = 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);
});
原生js和js的区别//禁⽌选中对话框内容
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");
});
/
/窗⼝⼤⼩改变时,对话框始终居中
autoCenter($dialog);
};
});
注意分析对⽐原⽣JS和jQuery的异同点!获取元素宽⾼,绑定事件等的写法………….
三、末尾
可拖拽对话框效果实现,JS和jQuery两种写法就是这样了,感谢前⼈栽阴!
同时学海⽆涯苦作⾈,js插件不仅要会⽤,努⼒弄懂⼀个⼜⼀个效果的实现原理,⾃⼰能写出来才是真的懂了,共勉!!!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论