JS 登录框拖拽
登陆框拖拽是比较常用的功能,拖拽的时候要考虑到不能超出可视区域,并且ie在html的overflow:hidden;的情况下还是会产生滚动条,废话不多说,我们先看下效果图:
首先做出拖拽功能:
var login = document.getElementById('login');
login.onmousedown = function() {
this.onmousemove = function(event) {
var e = event || window.event;
login.style.top = e.clientY + 'px';
login.style.left = e.clientX + 'px';
}
this.onmouseup = function() {
this.onmousemove = null;
this.onmouseup = null;
}
}
当login被鼠标点击不放并且移动的时候触发事件,login的top和left等于当前鼠标的坐标,当鼠标移出login上方时,删除掉onmousedown 和onmousemove 事件。
这样写后我们会发现虽然login能够有一些拖拽的效果,但是只能往右边和下面移动,因为onmousemove获取鼠标坐标只能在login上方才可以,但实际上我们要在整个可视区域移动,所以onmousemove要改为document.onmousemove才行。
于是改为:
var login = document.getElementById('login');
login.onmousedown = function() {
document.onmousemove = function(event) {
var e = event || window.event;
login.style.top = e.clientY + 'px';
login.style.left = e.clientX + 'px';
}
document.onmouseup = function() {
this.onmousemove = null;
this.onmouseup = null;
}
}
效果图:
这样可视窗口都可以拖拽了,但是每次鼠标左键按住并移动的时候,窗口的左上角总是会自动移动到鼠标下方,这样并不友好,我们应该让窗口自然的移动,所以这里我们要计算出login正确的top和left。
首先我们只能即时获取鼠标的坐标,鼠标在login上点击时,鼠标的xy轴坐标和login的xy轴坐标存在着不固定的距离,如果我们将这个不固定的距离计算出来,然后让鼠标的xy轴减去这个距离,不就可以得到即时的login元素xy轴坐标了。
如图所示,我们只需要将红色的差距算出来,就可以即时获取到login的xy轴坐标了。
var login = document.getElementById('login');
login.onmousedown = function(event) {
var e = event || window.event;
var ctop = e.clientY - this.offsetTop;
var cleft = e.clientX - this.offsetLeft;
document.onmousemove = function(event) {
var e = event || window.event;
login.style.top = e.clientY - ctop + 'px';
login.style.left = e.clientX - cleft + 'px';
}
document.onmouseup = function() {
this.onmousemove = null;
this.onmouseup = null;
}
}
效果图:
即时拖拽效果完成,但是登录框拖拽会超出可视区域,并且ie浏览器在html的overflow:hidden的情况下还可以可以产生滚动条,下面我们要一一修复。
修复超出可视区域:
var login = document.getElementById('login');
login.onmousedown = function(event) {
var e = event || window.event;
var ctop = e.clientY - this.offsetTop;
var cleft = e.clientX - this.offsetLeft;
document.onmousemove = function(event) {
var e = event || window.event;
var logintop = e.clientY - ctop;
var loginleft = e.clientX - cleft;
if (logintop < 0) {
logintop = 0;
} else if (logintop > getInner().height - login.offsetHeight) {
logintop = getInner().height - login.offsetHeight;
}
if (loginleft < 0) {
loginleft = 0;
} else if (loginleft > getInner().width - login.offsetWidth) {
loginleft = getInner().width - login.offsetWidth;
}
login.style.top = logintop + 'px';
login.style.left = loginleft + 'px';
}
document.onmouseup = function() {
this.onmousemove = null;
this.onmouseup = null;
}
}
if判断,如果login的top和left的值大于最大可显示位置(可视宽高减去login自身宽高得到的值),如果大于,就让他的值等于最大可显示位置值,如果小于0说明已经超出了左边和上边,直接就他的值等于0即可,这样就不会超出可视范围。
getInner()是上一篇写的,跨浏览器获取可视宽高的函数。
修复ie产生的滚动条:
在onmousedown事件下使用this.setCapture();
在onmouseup事件下使用this.releaseCapture();
于是:
var login = document.getElementById('login');
login.onmousedown = function(event) {
var e = event || window.event;
var ctop = e.clientY - this.offsetTop;
var cleft = e.clientX - this.offsetLeft;
if (typeof this.setCapture != 'undefined') {
this.setCapture();
}
document.onmousemove = function(event) {
var e = event || window.event;
var logintop = e.clientY - ctop;
var loginleft = e.clientX - cleft;
if (logintop < 0) {
logintop = 0;
} else if (logintop > getInner().height - login.offsetHeight) {
logintop = getInner().height - login.offsetHeight;
}
if (loginleft < 0) {
loginleft = 0;
} else if (loginleft > getInner().width - login.offsetWidth) {
loginleft = getInner().width - login.offsetWidth;
}
login.style.top = logintop + 'px';
login.style.left = loginleft + 'px';
}
document.onmouseup = function() {
this.onmousemove = null;
this.onmouseup = null;
if (typeof this.releaseCapture != 'undefined') {
this.releaseCapture();
}
}
}
这样基本就完成了,开始封装到Base中去。
封装至Base:
Base.prototype.drag = function() {
for (var i = 0; i < this.arr.length; i++) {
this.arr[i].onmousedown = function(event) {
var e = getEvent(event);
var _this = this;
var ctop = e.clientY - _this.offsetTop;
var cleft = e.clientX - _this.offsetLeft;
if (typeof _this.setCapture != 'undefined') {
_this.setCapture();
}
document.onmousemove = function(event) {
var e = getEvent(event);
var logintop = e.clientY - ctop;
var loginleft = e.clientX - cleft;
if (logintop < 0) {
logintop = 0;
} else if (logintop > getInner().height - login.offsetHeight) {
logintop = getInner().height - login.offsetHeight;
}
if (loginleft < 0) {
loginleft = 0;
} else if (loginleft > getInner().width - login.offsetWidth) {
loginleft = getInner().width - login.offsetWidth;
}
login.style.top = logintop + 'px';
login.style.left = loginleft + 'px';
}
document.onmouseup = function() {
this.onmousemove = null;
this.onmouseup = null;
if (typeof this.releaseCapture != 'undefined') {
_this.releaseCapture();
}
}
}
return this;
}
//跨浏览返回event
function getEvent(e) {
return e || window.event;
}
调用代码:
$().getId('login').drag();
修复两个bug:
- 当login里面没有内容是,拖拽时错位!
- 当浏览器窗口发生改变时,login会自动居中
当login里面没有内容是,拖拽时错位!
在旧版火狐上会有这个问题,处理方法就是将onmousedown 的默认行为阻止即可。
Base.prototype.drag = function() {
for (var i = 0; i < this.arr.length; i++) {
this.arr[i].onmousedown = function(event) {
preDef(event);
var e = getEvent(event);
var _this = this;
var ctop = e.clientY - _this.offsetTop;
var cleft = e.clientX - _this.offsetLeft;
if (typeof _this.setCapture != 'undefined') {
_this.setCapture();
}
document.onmousemove = function(event) {
var e = getEvent(event);
var logintop = e.clientY - ctop;
var loginleft = e.clientX - cleft;
if (logintop < 0) {
logintop = 0;
} else if (logintop > getInner().height - login.offsetHeight) {
logintop = getInner().height - login.offsetHeight;
}
if (loginleft < 0) {
loginleft = 0;
} else if (loginleft > getInner().width - login.offsetWidth) {
loginleft = getInner().width - login.offsetWidth;
}
login.style.top = logintop + 'px';
login.style.left = loginleft + 'px';
}
document.onmouseup = function() {
this.onmousemove = null;
this.onmouseup = null;
if (typeof this.releaseCapture != 'undefined') {
_this.releaseCapture();
}
}
}
return this;
}
//跨浏览返回event
function getEvent(e) {
return e || window.event;
}
//跨浏览器阻止默认行为
function preDef(event) {
var e = event || window.event;
if (typeof e.preventDefault != 'undefined') {
e.preventDefault();
} else {
e.returnValue = false;
}
}
当浏览器窗口发生改变时,login会自动居中
由于在弹出登录框时我们使用了resize()函数,当浏览器窗口发生变化是,自动居住,但是我们加了拖拽功能后就不需要自动居中了,我们只需要当login超出可视区域是自动移动到能见区域;于是:
Base.prototype.resize = function(fn) {
for (var i = 0; i < this.arr.length; i++) {
var element = this.arr[i];
window.onresize = function() {
fn();
if (element.offsetLeft > getInner().width - element.offsetWidth) {
element.style.left = getInner().width - element.offsetWidth + 'px';
}
if (element.offsetTop > getInner().height - element.offsetHeight) {
element.style.top = getInner().height - element.offsetHeight + 'px';
}
}
}
return this;
}
在窗口发生变化时,判断login的xy轴坐标是否大于最大可见xy轴坐标,如果大于,说明login看不到了,于是让他的xy轴坐标等于最大可见xy轴坐标即可。
resize()函数调用的function中也不需要再对login加.center()居中函数了。
$().getId('login').css('clip', 'auto').css('opacity', '1').center().Masked().resize(function() {
if ($().getId('login').css('opacity') == '1') {
$().getId('login').Masked();
};
});
css部分,我们只需要为login顶部加一个十字光标,表示可以移动,由于我的上部分只用了class为title的h2标题,所以只要加上cursor: move;即可。
#login>.login_title {
font-weight: normal;
font-size: 16px;
line-height: 30px;
letter-spacing: 1px;
background-color: #eee;
cursor: move;
}
以上完成。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据