鼠标拖拽移动子窗体的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 DOM 学习第五章 表单简介
Feb 19 Javascript
javascript中String类的subString()方法和slice()方法
May 24 Javascript
js捕获鼠标右键菜单中的粘帖事件实现代码
Apr 01 Javascript
JS模仿编辑器实时改变文本框宽度和高度大小的方法
Aug 17 Javascript
jQuery实现自动调用和触发某个事件的方法
Nov 18 Javascript
Javascript 引擎工作机制详解
Nov 30 Javascript
vue.js入门(3)——详解组件通信
Dec 02 Javascript
Angular2环境搭建具体操作步骤(推荐)
Aug 04 Javascript
提高Node.js性能的应用技巧分享
Aug 10 Javascript
angular之ng-template模板加载
Nov 09 Javascript
JavaScript RegExp 对象用法详解
Sep 24 Javascript
基于ajax实现上传图片代码示例解析
Dec 03 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
phpstrom使用xdebug配置方法
2013/12/17 PHP
thinkphp命名空间用法实例详解
2015/12/30 PHP
PHP构造二叉树算法示例
2017/06/21 PHP
laravel 修改.htaccess文件 重定向public的解决方法
2019/10/12 PHP
在多个页面使用同一个HTML片段《续》
2011/03/04 Javascript
js获取图片大小的函数代码
2011/09/20 Javascript
js中的eventType事件及其浏览器支持性介绍
2013/11/29 Javascript
可编辑下拉框的2种实现方式
2014/06/13 Javascript
js实现点击链接后延迟3秒再跳转的方法
2015/06/05 Javascript
JavaScript中数组添加值和访问值常见问题
2016/02/06 Javascript
jquery 点击元素后,滚动条滚动至该元素位置的方法
2016/08/05 Javascript
js 单引号替换成双引号,双引号替换成单引号的实现方法
2017/02/16 Javascript
基于vue v-for 循环复选框-默认勾选第一个的实现方法
2018/03/03 Javascript
javascript数据类型中的一些小知识点(推荐)
2019/04/18 Javascript
React+Redux实现简单的待办事项列表ToDoList
2019/09/29 Javascript
原生js实现密码强度验证功能
2020/03/18 Javascript
JavaScript正则表达式验证登录实例
2020/03/18 Javascript
[01:20]DOTA2上海特级锦标赛现场采访:谁的ID最受青睐
2016/03/25 DOTA
[37:29]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第二场 11.19
2020/11/19 DOTA
django模型中的字段和model名显示为中文小技巧分享
2014/11/18 Python
python打开文件并获取文件相关属性的方法
2015/04/23 Python
在pycharm中使用git版本管理以及同步github的方法
2019/01/16 Python
Python 分享10个PyCharm技巧
2019/07/13 Python
python如何通过twisted搭建socket服务
2020/02/03 Python
在Python中使用K-Means聚类和PCA主成分分析进行图像压缩
2020/04/10 Python
TensorFlow实现模型断点训练,checkpoint模型载入方式
2020/05/26 Python
洛杉矶时尚女装系列:J.ING US
2019/03/17 全球购物
财务人员个人自荐信范文
2013/09/26 职场文书
市场营销专业个人求职信范文
2013/12/14 职场文书
高三学习决心书
2014/03/11 职场文书
文化苦旅读书笔记
2015/06/29 职场文书
公司老总年会致辞
2015/07/30 职场文书
2016年记者节感言
2015/12/08 职场文书
JS中一些高效的魔法运算符总结
2021/05/06 Javascript
Redis基于Bitmap实现用户签到功能
2021/06/20 Redis
python脚本框架webpy模板控制结构
2021/11/20 Python