鼠标拖拽移动子窗体的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 相关文章推荐
js数据验证集合、js email验证、js url验证、js长度验证、js数字验证等简单封装
May 15 Javascript
使用ImageMagick进行图片缩放、合成与裁剪(js+python)
Sep 16 Javascript
Jquery $.getJSON 在IE下的缓存问题解决方法
Oct 10 Javascript
深入浅析JavaScript中的constructor
Apr 19 Javascript
Jquery跨域获得Json的简单实例
May 18 Javascript
js中setTimeout的妙用--防止循环超时
Mar 06 Javascript
详解vue slot插槽的使用方法
Jun 13 Javascript
js学习总结之dom2级事件基础知识详解
Jul 27 Javascript
Angular.js前台传list数组由后台spring MVC接收数组示例代码
Jul 31 Javascript
Node.js一行代码实现静态文件服务器的方法步骤
May 07 Javascript
echarts统计x轴区间的数值实例代码详解
Jul 07 Javascript
JavaScript基于面向对象实现的无缝滚动轮播示例
Jan 17 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
打造计数器DIY三步曲(中)
2006/10/09 PHP
windows下PHP APACHE MYSQ完整配置
2007/01/02 PHP
php中函数的形参与实参的问题说明
2010/09/01 PHP
PHP编码转换
2012/11/05 PHP
php登陆页的密码处理方式分享
2013/10/14 PHP
javascript题目,重写函数让其无限相加
2012/02/15 Javascript
JavaScript调用堆栈及setTimeout使用方法深入剖析
2013/02/16 Javascript
基于javascipt-dom编程 table对象的使用
2013/04/22 Javascript
jquery遍历筛选数组的几种方法和遍历解析json对象
2013/12/13 Javascript
利用js动态添加删除table行的示例代码
2013/12/16 Javascript
鼠标移入移出事件改变图片的分辨率的两种方法
2013/12/17 Javascript
JS实现动态移动层及拖动浮层关闭的方法
2015/04/30 Javascript
JS模拟并美化的表单控件完整实例
2015/08/19 Javascript
详解VueJs异步动态加载块
2017/03/09 Javascript
利用babel将es6语法转es5的简单示例
2017/12/01 Javascript
详解Node.js中的Async和Await函数
2018/02/22 Javascript
基于ionic实现下拉刷新功能
2018/05/10 Javascript
vue+webpack模拟后台数据的示例代码
2018/07/26 Javascript
解决vue中虚拟dom,无法实时更新的问题
2018/09/15 Javascript
基于nodejs的雪碧图制作工具的示例代码
2018/11/05 NodeJs
关于自定义Egg.js的请求级别日志详解
2018/12/12 Javascript
jQuery实现的导航条点击后高亮显示功能示例
2019/03/04 jQuery
JavaScript JSON数据处理全集(小结)
2019/08/15 Javascript
vue路由缓存的几种实现方式小结
2020/02/02 Javascript
JavaScript实现多个物体同时运动
2020/03/12 Javascript
对Python 字典元素进行删除的方法
2020/07/31 Python
利用Python实现学生信息管理系统的完整实例
2020/12/30 Python
python日志通过不同的等级打印不同的颜色(示例代码)
2021/01/13 Python
世界领先的艺术图书出版社:TASCHEN
2018/07/23 全球购物
French Connection官网:女装、男装及家居用品
2019/03/18 全球购物
北欧最好的童装网上商店:Babyshop
2019/09/15 全球购物
2014年庆元旦活动方案
2014/02/15 职场文书
司机岗位职责范本
2015/04/10 职场文书
2019幼儿园感恩节活动策划书
2019/11/28 职场文书
SQL IDENTITY_INSERT作用案例详解
2021/08/23 MySQL
德生BCL3000抢先使用感受和评价
2022/04/07 无线电