鼠标拖拽移动子窗体的JS实现


Posted in Javascript onFebruary 25, 2014

1.子窗体

在设计网站的时候,我们需要设计一些模态的子窗体,比如

鼠标拖拽移动子窗体的JS实现

这一步很容易实现,只需要div+css就ok了,请看代码:

    <div class="modal-background"></div>
    <div class="modal-window">
        <div class="head">
            <center>点住着块区域可以改变我的位置</center>
        </div>
    </div>

.modal-background
{
    background-color: #999999;
    bottom: 0;
    left: 0;
    opacity: 0.3;
    position: fixed;
    right: 0;
    top: 0;
    z-index: 1100;
}
.modal-window
{
    background-color: #FFFFFF;
    border: 1px solid #6B94AD;
    box-shadow: 5px 5px 5px #6B94AD;
    font-family: 'Microsoft YaHei';
    font-size: 12px;
    height: 120px;
    left: 50%;
    margin-left: -160px;
    margin-top: -160px;
    opacity: 1;
    position: fixed;
    top: 50%;
    width: 320px;
    z-index: 1110;
}
    .modal-window .head
    {
        height: 25px;
        color: #fff;
        font-weight: 600;
        background-image: -moz-linear-gradient(top, #4A8CC5, #2963A5); /* Firefox */
        background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #4A8CC5), color-stop(1, #2963A5)); /* Saf4+, Chrome */
        filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#4A8CC5', endColorstr='#2963A5', GradientType='0'); /* IE*/
    }
        .modal-window .head center
        {
            padding-top: 2px;
        }

加上上述html和css就可以很容易实现上述模态窗体的效果。其中left: 50%;top: 50%; margin-left: -160px; margin-top: -160px;是为了实现这个模态窗体的居中效果。

当然,模态窗体的大小在样式类.modal-window中是固定写好的了,这并不是说不可修改模态窗体的大小,比如我写如代码:

    <div class="modal-background"></div>
    <div class="modal-window list-window">
        <div class="head">
            <center>点住着块区域可以改变我的位置</center>
        </div>
    </div>

在第二行代码中追加了.list-window这个样式类来覆盖.modal-window类中的大小和位置,但同时保证模态窗体居中显示

.list-window
{
    width:600px;
    height:400px;
    margin-left:-300px;
    margin-top:-200px;
}

如图

鼠标拖拽移动子窗体的JS实现

可以看得出来,这一步的实现是非常简单的,掌握几个关键行的css属性就"完虐"这个模态子窗体,各类其它的模态子窗体可以举一反三咯。

2.当鼠标点住子窗体的头部时,如何实现子窗体的拖拽移动呢?当引入jQ后,我们只需要很少的脚本就搞定这个小功能。不信我们看

var left, top, $this;
$(document).delegate('.modal-window .head', 'mousedown', function (e) {
    left = e.clientX, top = e.clientY, $this = $(this).css('cursor', 'move');
    this.setCapture ? (
    this.setCapture(),
    this.onmousemove = function (ev) { mouseMove(ev || event); },
    this.onmouseup = mouseUp
    ) : $(document).bind("mousemove", mouseMove).bind("mouseup", mouseUp);
});
function mouseMove(e) {
    var target = $this.parents('.modal-window');
    var l = Math.max((e.clientX - left + Number(target.css('margin-left').replace(/px$/, '')) || 0), -target.position().left);
    var t = Math.max((e.clientY - top + Number(target.css('margin-top').replace(/px$/, '')) || 0), -target.position().top);
    l = Math.min(l, $(window).width() - target.width() - target.position().left);
    t = Math.min(t, $(window).height() - target.height() - target.position().top);
    left = e.clientX;
    top = e.clientY;
    target.css({ 'margin-left': l, 'margin-top': t });
}
function mouseUp(e) {
    var el = $this.css('cursor', 'default').get(0);
    el.releaseCapture ?
    (
        el.releaseCapture(),
        el.onmousemove = el.onmouseup = null
    ) : $(document).unbind("mousemove", mouseMove).unbind("mouseup", mouseUp);
}

这段代码非常简短,能否在各种浏览器中很流畅的运行。

其实它的实现原理非常简单,大致分为三步:

①当鼠标在模态窗体头部点下(mousedown)时,立即给document绑定mousemove和mouseup事件

②当鼠标没有弹起时(没有mouseup)时,若鼠标在窗体内移动时,激活mouseMove函数,通过计算鼠标移动的距离来及时整个窗体的位置移动。

③当鼠标弹起(mouseup)时,调用mouseUp事件,将document上绑定的mousemove事件和mouseup事件解除绑定。

整个过程的原理就是:当鼠标mousedown时,鼠标的移动事件转移到document上来,通过鼠标在document上的移动事件来对整个窗体进行处理。

另外,在mouseMove中有个小技巧,就是全局的left,top变量记录上一次鼠标停止时的位置,然后下一次移动时鼠标的位置与left,top变量进行对比来确定鼠标移动了多少距离,来对整个模态子窗体做出相应的位置移动即可。

经过这一段代码的分析,发现鼠标移动窗体乃至document上的任何元素都是相当easy的

比如,如果想要通过拖拽来改变窗体的大小,一样我们只需要在mouseMove事件处理函数中调整窗体的大小就ok了,是不是又发现自己有多学会了一招,又精进了一小步呢?

有人会问setCapture和releaseCapture分别都是干什么的呢?其实这是为了兼容IE,仅有IE才有这俩函数,在此鄙视IE。setCapture可以让当前元素捕获鼠标的所有事件,如果不使用它们,可能不兼容IE浏览器哦。

Javascript 相关文章推荐
javascript 限制输入和粘贴(IE,firefox测试通过)
Nov 14 Javascript
javascript HTMLEncode HTMLDecode的完整实例(兼容ie和火狐)
Jun 02 Javascript
对采用动态原型方式无法展示继承机制得思考
Dec 04 Javascript
常用js字符串判断方法整理
Oct 18 Javascript
javascript中返回顶部按钮的实现
May 05 Javascript
js 获取元素的具体样式信息getcss(实例讲解)
Jul 05 Javascript
浅谈JavaScript中的属性:如何遍历属性
Sep 14 Javascript
Angular实现较为复杂的表格过滤,删除功能示例
Dec 23 Javascript
微信小程序自定义底部导航带跳转功能
Nov 27 Javascript
seajs和requirejs模块化简单案例分析
Aug 26 Javascript
深入理解javascript prototype的相关知识
Sep 19 Javascript
vue和小程序项目中使用iconfont的方法
May 19 Javascript
js判断为空Null与字符串为空简写方法
Feb 24 #Javascript
JS清空多文本框、文本域示例代码
Feb 24 #Javascript
脚本合并提升javascript性能示例
Feb 24 #Javascript
动态加载脚本提升javascript性能
Feb 24 #Javascript
巧用局部变量提升javascript性能
Feb 24 #Javascript
javascript中的原型链深入理解
Feb 24 #Javascript
JSONP获取Twitter和Facebook文章数的具体步骤
Feb 24 #Javascript
You might like
php addslashes和mysql_real_escape_string
2010/01/24 PHP
PHP使用openssl扩展实现加解密方法示例
2020/02/20 PHP
Dom加载让图片加载完再执行的脚本代码
2008/05/15 Javascript
JavaScript 设计模式学习 Singleton
2009/07/27 Javascript
使用原生javascript创建通用表单验证——更锋利的使用dom对象
2011/09/13 Javascript
推荐40款强大的 jQuery 导航插件和教程(上篇)
2012/09/14 Javascript
深入理解JavaScript系列(25):设计模式之单例模式详解
2015/03/03 Javascript
关于原生js中bind函数的简单实现
2016/08/10 Javascript
真正好用的js验证上传文件大小的简单方法
2016/10/27 Javascript
angular学习之从零搭建一个angular4.0项目
2017/07/10 Javascript
vue elementUI tree树形控件获取父节点ID的实例
2018/09/12 Javascript
jQuery操作事件完整实例分析
2020/01/10 jQuery
小程序实现点击tab切换左右滑动
2020/11/16 Javascript
对于Python异常处理慎用“except:pass”建议
2015/04/02 Python
python浪漫表白源码
2019/04/05 Python
python 一篇文章搞懂装饰器所有用法(建议收藏)
2019/08/23 Python
Python3 实现减少可调用对象的参数个数
2019/12/20 Python
Python函数基本使用原理详解
2020/03/19 Python
4行Python代码生成图像验证码(2种)
2020/04/07 Python
获取python运行输出的数据并解析存为dataFrame实例
2020/07/07 Python
Python 常用日期处理 -- calendar 与 dateutil 模块的使用
2020/09/02 Python
CSS3 please 跨浏览器的CSS3产生器
2010/03/14 HTML / CSS
Html5嵌入钉钉的实现示例
2020/06/04 HTML / CSS
中学生打架检讨书
2014/02/10 职场文书
模具设计与制造专业求职信
2014/07/19 职场文书
2014年卫生工作总结
2014/11/27 职场文书
先进工作者推荐材料
2014/12/23 职场文书
晚会开幕词
2015/01/28 职场文书
介绍信的写法
2015/01/31 职场文书
世界遗产的导游词
2015/02/13 职场文书
房租涨价通知
2015/04/23 职场文书
2019年怎样才能撰写出优秀的自荐信
2019/03/25 职场文书
CSS3 实现的图片悬停的切换按钮
2021/04/13 HTML / CSS
Python time库的时间时钟处理
2021/05/02 Python
Oracle中update和select 关联操作
2022/01/18 Oracle
Win11 Beta 22621.601 和 22622.601今日发布 KB5017384修复内容汇总
2022/09/23 数码科技