一直以来,都对JS获取元素的位置感到非常的困惑:一会client、一会offset、一会scroll。

再加上各大浏览器之间的不兼容,唉,搞得哥晕晕乎乎的。

而很多页面效果都要用到这些位置。不得已,得练练,得记记。

下面就来说说这个基于 JQuery的简易拖拽插件吧。

按惯例,先说说拖拽的原理,以及搞这么一个东东的步骤:

那什么是拖拽呢? 看名字就知道了:就是把一个东东拖来拽去的。 放到我们的DOM上,就是改变它的位置。

它只有两个难点:1、如何知道是在拖? 2、如何知道从哪拖,拖到哪?

其实,这也算不上难点,毕竟两者都是基础的东西,关键在于熟练。

换到js 中,我们搞一个拖拽效果,大致有如下步骤:

1、让元素捕获事件(一般情况下,无非就是mousedown、mousemove、mouseup)

2、在mousedown时,标记开始拖拽,并获取元素及鼠标的位置。

3、在mousemove时,不断的获取鼠标的新位置,并通过相应的位置算法,来重新定位元素位置。

4、在mouseup时,结束拖拽。。。然后周而复始。

这中间,个需要注意的地方:被拖拽的元素,至少需要相对或绝对定位,否则拖拽不会有效果。

OK,不多说,无代码,无真相。相应的解释都在其中了:

猛击下载

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<meta name="keywords" content="Javascript自由拖拽类" />
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>

<script type="text/javascript">
   (function($)
    {
        $.extend({
            //获取鼠标当前坐标
            mouseCoords:function(ev){
                if(ev.pageX || ev.pageY){
                    return {x:ev.pageX, y:ev.pageY};
                }
                return {
                    x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
                    y:ev.clientY + document.body.scrollTop  - document.body.clientTop
                };
            },
            //获取样式值
            getStyle:function(obj,styleName)
            {
                return obj.currentStyle ? obj.currentStyle[styleName] : document.defaultView.getComputedStyle(obj,null)[styleName];
//                return obj.currentStyle ? obj.currentStyle[styleName] : document.defaultView.getComputedStyle(obj,null).getPropertyValue(styleName);
            }
        });

// 元素拖拽插件
        $.fn.dragDrop = function(options)
        {
            var opts = $.extend({},$.fn.dragDrop.defaults,options);

return this.each(function(){

//是否正在拖动
                var bDraging = false;   
                //移动的元素
                var moveEle = $(this);
                //点击哪个元素,以触发移动。
                //该元素需要是被移动元素的子元素(比如标题等)
                var focuEle = opts.focuEle ? $(opts.focuEle,moveEle) : moveEle ;
                if(!focuEle || focuEle.length<=0)
                {
                    alert('focuEle is not found! the element must be a child of '+this.id);
                    return false;
                }                
                // initDiffX|Y : 初始时,鼠标与被移动元素原点的距离
                // moveX|Y : 移动时,被移动元素定位位置 (新鼠标位置与initDiffX|Y的差值)
                // 如果定义了移动中的回调函数,该对象将以参数传入回调函数。
                var dragParams = {initDiffX:'',initDiffY:'',moveX:'',moveY:''};

//被移动元素,需要设置定位样式,否则拖拽效果将无效。
                moveEle.css({'position':'absolute','left':'0','top':'0'});
                
                //点击时,记录鼠标位置
                //DOM写法: getElementById('***').onmousedown= function(event);
                focuEle.bind('mousedown',function(e){                
                    //标记开始移动
                    bDraging = true;
                    //改变鼠标形状
                    moveEle.css({'cursor':'move'});
                    //捕获事件。(该用法,还有个好处,就是防止移动太快导致鼠标跑出被移动元素之外)
                    if(moveEle.get(0).setCapture)
                    {  
                        moveEle.get(0).setCapture();  
                    } 
                    //(实际上是鼠标当前位置相对于被移动元素原点的距离)
                    // DOM写法:(ev.clientX + document.body.scrollLeft - document.body.clientLeft) - document.getElementById('***').style.left;
                    dragParams.initDiffX = $.mouseCoords(e).x - moveEle.position().left;
                    dragParams.initDiffY = $.mouseCoords(e).y - moveEle.position().top;
                });

//移动过程
                focuEle.bind('mousemove',function(e){
                    if(bDraging)
                    {    
                        //被移动元素的新位置,实际上鼠标当前位置与原位置之差
                        //实际上,被移动元素的新位置,也可以直接是鼠标位置,这也能体现拖拽,但是元素的位置就不会精确。
                        dragParams.moveX = $.mouseCoords(e).x - dragParams.initDiffX;
                        dragParams.moveY = $.mouseCoords(e).y - dragParams.initDiffY;

//是否限定在某个区域中移动.
                        //fixarea格式: [x轴最小值,x轴最大值,y轴最小值,y轴最大值]
                        if(opts.fixarea)
                        {
                            if(dragParams.moveX<opts.fixarea[0])
                            {
                                dragParams.moveX=opts.fixarea[0]
                            }
                            if(dragParams.moveX>opts.fixarea[1])
                            {
                                dragParams.moveX=opts.fixarea[1]
                            }

if(dragParams.moveY<opts.fixarea[2])
                            {
                                dragParams.moveY=opts.fixarea[2]
                            }
                            if(dragParams.moveY>opts.fixarea[3])
                            {
                                dragParams.moveY=opts.fixarea[3]
                            }
                        }
                        
                        //移动方向:可以是不限定、垂直、水平。
                        if(opts.dragDirection=='all')
                        {
                            //DOM写法: document.getElementById('***').style.left = '***px'; 
                            moveEle.css({'left':dragParams.moveX,'top':dragParams.moveY});
                        }
                        else if (opts.dragDirection=='vertical')
                        {
                            moveEle.css({'top':dragParams.moveY});
                        }
                        else if(opts.dragDirection=='horizontal')
                        {
                            moveEle.css({'left':dragParams.moveX});
                        }

//如果有回调
                        if(opts.callback)
                        {
                            //将dragParams作为参数传递
                            opts.callback.call(opts.callback,dragParams);
                        }
                    }
                });

//鼠标弹起时,标记为取消移动
                focuEle.bind('mouseup',function(e){
                    bDraging=false;
                    moveEle.css({'cursor':'default'});
                    if(moveEle.get(0).releaseCapture)
                    {
                        moveEle.get(0).releaseCapture();
                    }
                });
            });
        };

//默认配置
        $.fn.dragDrop.defaults = 
        {
            focuEle:null,            //点击哪个元素开始拖动,可为空。不为空时,需要为被拖动元素的子元素。
            callback:null,            //拖动时触发的回调。
            dragDirection:'all',    //拖动方向:['all','vertical','horizontal']
            fixarea:null            //限制在哪个区域拖动,以数组形式提供[minX,maxX,minY,maxY]
        };

})(jQuery);

// test 
   $(function(){
        //限定区域,有回调函数。
        $('#dragDiv').dragDrop({fixarea:[0,$('#dragContainer').width()-50,0,$('#dragContainer').height()-50],callback:function(params){
                $('#span1').text('X:'+params.moveX+' Y:'+params.moveY);
        }});
        //默认设置
        $('#dragDiv1').dragDrop();
   });
</script>

</head>
<body>
    <div id="dragContainer" style="position:relative;left:10px;top:10px;border:1px dashed blue;width:500px;height:500px;">

<div id="dragDiv" style="height:50px;width:50px;">
      </div>
      <div id="dragDiv1" style="border:1px solid red;height:50px;width:50px;">
      </div>

</div>

<span id="span1"></span>
</body>
</html>

JQuery之拖拽插件的更多相关文章

  1. jQuery网页元素拖拽插件

    效果说明:配合已有CSS样式,载入插件后,网页元素可以随意在窗口内拖拽,设置了原位置半透明和拖拽半透明的效果选项,可根据需要选择.另外,当页面上有多个可拖拽元素时,可以载入另外一个用于设置z-inde ...

  2. 网站开发常用jQuery插件总结(三)拖拽插件gridster

    1.gridster插件功能 实现类似于win8 磁贴拖拽的功能 2.gridster官方地址 http://gridster.net/ 在官方的网站上也有插件的帮助和实例,但是按照官方的说明,我在本 ...

  3. 一步一步实现JS拖拽插件

    js拖拽是常见的网页效果,本文将从零开始实现一个简单的js插件. 一.js拖拽插件的原理 常见的拖拽操作是什么样的呢?整过过程大概有下面几个步骤: 1.用鼠标点击被拖拽的元素 2.按住鼠标不放,移动鼠 ...

  4. jQuery可拖拽3D万花筒旋转特效

    这是一个使用了CSS3立体效果的强大特效,本特效使用jQuery跟CSS3 transform来实现在用户鼠标按下拖动时,环形图片墙可以跟随鼠标进行3D旋转动画. 效果体验:http://hovert ...

  5. jQuery可拖拽排序列表jquery-sortable-lists

    jquery-sortable-lists可以通过鼠标进行拖动排列树型菜单,可以定义某个列表元素是否拖动,拖动后回调,点击可以折叠树型结点,可以用来在后台模仿wordpress后台拖动菜单,实现多级菜 ...

  6. vue拖拽插件(弹框拖拽)

    // =======拖拽 插件 cnpm install vuedraggableimport draggable from 'vuedraggable' <draggable v-model= ...

  7. jquery实现拖拽以及jquery监听事件的写法

    很久之前写了一个jquery3D楼盘在线选择,这么一个插件,插件很简单,因为后期项目中没有实际用到,因此,有些地方不是很完善,后面也懒得再进行修改维护了.最近放到github上面,但是也少有人问津及s ...

  8. 自己写一个jqery的拖拽插件

    说实话,jQuery比原生的js好用多了,本来想用原生写的,也写出来的,仅仅是,感觉不像插件,所以用jQuery实现了一版. 实现的功能:能够指定拖拽的边界,在拖拽过程中,能够触发几个自己定义事件 先 ...

  9. 拖拽插件SortableJS

    在项目中,经常会遇到一些涉及到拖拽的需求,github上面有一个开源的SortableJS的插件,支持Vue,React,Angular等多种框架,实现效果很好,基本可以满足大部分的需求,下面就第一次 ...

随机推荐

  1. Android: TextView 及其子类通过代码和 XML 设置字体大小的存在差异的分析

    原因: 在代码中通过 setTextSize(float size) 设置,使用的是 sp 为默认单位. 而 XML 中使用了 px,所以需要使用先把做好 sp 和 px 的转换工作. 最近在做 ap ...

  2. ubuntu18.04分辨率

    一.使用xrandr命令可以查询当前的显示状态.找出被连接的显示器名称:VGA-1 jack@noi:~$ xrandr Screen : minimum x , current x , maximu ...

  3. eclipse再见,android studio 新手新手教程(一)基本设置

    写在前面: 作为一个刚半仅仅脚踏入android开发的新手,在使用eclipse开发了两个自我感觉不甚成熟的商城类app之后.遇到了一些问题,总结为例如以下: 1,代码复用性. findviewByI ...

  4. HTML5学习笔记(十三):JavaScript函数

    函数定义 在JavaScript中,定义函数的方式如下: function abs(x) { if (x >= 0) { return x; } else { return -x; } } 上述 ...

  5. CCZone

    /**************************************************************************** Copyright (c) 2010 coc ...

  6. [转]Web App 框架选择之百度&腾讯

    百度的GMU GMU(Global Mobile UI)是百度前端通用组开发的移动端组件库,GMU是基于zepto的mobile UI组件库,提供webapp.pad端简单易用的UI组件.具有代码体积 ...

  7. form的验证包括手机号邮箱等等

    $(function(){    var checkedByVerifyCode = false;    var checkMobieCode = false;    var checkedMobil ...

  8. 【MLP】多层感知机网络

    BPN(Back Propagation Net) 反向传播神经网络是对非线性可微分函数进行权值训练的多层网络,是前向神经网络的一种. BP网络主要用于: 1)函数逼近与预测分析:用输入矢量和相应的输 ...

  9. zabbix告警邮件乱码问题

    ZABBIX报警内容:邮件标题正常,内容为乱码:微信报警正常. 曾试图改变环境变量:export LANG=zh_CN.UTF-8 依旧为乱码 原因:export只改变的环境变量 而ZABBIX报警内 ...

  10. 2. 集成学习(Ensemble Learning)Bagging

    1. 集成学习(Ensemble Learning)原理 2. 集成学习(Ensemble Learning)Bagging 3. 集成学习(Ensemble Learning)随机森林(Random ...