鼠标拖拽移动子窗体的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数组组合成字符串的脚本
Jan 06 Javascript
原生javascript和jquery判断浏览器版本等信息
Jul 04 Javascript
js实现身份证号码验证的简单实例
Feb 19 Javascript
node.js调用C++开发的模块实例
Jul 03 Javascript
使用Script元素发送JSONP请求的方法
Jun 12 Javascript
AngularJS入门教程之ng-checked 指令详解
Aug 01 Javascript
BootStrap Typeahead自动补全插件实例代码
Aug 10 Javascript
JavaScript文件的同步和异步加载的实现代码
Aug 19 Javascript
JavaScript学习笔记之惰性函数示例详解
Aug 27 Javascript
javaScript 连接打印机,打印小票的实例
Dec 29 Javascript
JS 实现获取验证码 倒计时功能
Oct 29 Javascript
教你一步步实现一个简易promise
Nov 02 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 Session变量不能传送到下一页的解决方法
2009/11/27 PHP
PHP转盘抽奖接口实例
2015/02/09 PHP
PHP二分查找算法示例【递归与非递归方法】
2016/09/29 PHP
Javascript的构造函数和constructor属性
2010/01/09 Javascript
使用js写的一个简易的投票
2013/11/27 Javascript
深入理解javascript的执行顺序
2014/04/04 Javascript
div失去焦点事件实现思路
2014/04/22 Javascript
jQuery源码分析之Callbacks详解
2015/03/13 Javascript
jquery实现标签支持图文排列带上下箭头按钮的选项卡
2015/03/14 Javascript
jquery实现动静态条形统计图
2015/08/17 Javascript
深入理解vue.js中$watch的oldvalue与newValue
2017/08/07 Javascript
jQuery滑动效果实现方法分析
2018/09/05 jQuery
webuploader分片上传的实现代码(前后端分离)
2018/09/10 Javascript
vue实现的树形结构加多选框示例
2019/02/02 Javascript
JS面向对象之单选框实现
2020/01/17 Javascript
python制作最美应用的爬虫
2015/10/28 Python
Python简单定义与使用二叉树示例
2018/05/11 Python
python opencv捕获摄像头并显示内容的实现
2019/07/11 Python
django 通过url实现简单的权限控制的例子
2019/08/16 Python
python监控nginx端口和进程状态
2019/09/06 Python
Python分割训练集和测试集的方法示例
2019/09/19 Python
Python基于BeautifulSoup爬取京东商品信息
2020/06/01 Python
Guess荷兰官网:美国服饰品牌
2020/01/22 全球购物
莫斯科大型旅游休闲商品超市:Camping.ru
2020/09/16 全球购物
什么是继承
2013/12/07 面试题
学生党员思想汇报
2013/12/28 职场文书
采购部部长岗位职责
2014/02/06 职场文书
优秀女职工事迹材料
2014/02/06 职场文书
《兰亭集序》教学反思
2014/02/11 职场文书
2014年国庆节演讲稿
2014/09/02 职场文书
中秋节国旗下演讲稿
2014/09/13 职场文书
安全承诺书格式范本
2015/04/28 职场文书
2015年秋季运动会前导词
2015/07/20 职场文书
教师反邪教心得体会
2016/01/15 职场文书
导游词创作书写原则以及开场白技巧怎么学?
2019/09/25 职场文书
Jedis操作Redis实现模拟验证码发送功能
2021/09/25 Redis