js 实现 pc 端 拖拽效果

点击目录标题预览效果

单个元素拖拽,不随页面滚动

css 部分

body{height:2000px;}
div{width:150px; height:150px;cursor: move;position: fixed;top:50px;color:#fff;box-sizing: border-box;z-index: 10;font-size: 16px}
#ele{background:#2196f3;left:10px; }

js 部分

window.onload=function(){
    // 获取元素
    var Div=document.getElementById('ele');
    drag(Div);
}
 1 // 拖拽运动
 2 function drag(obj){
 3       
 4     var lastX=0;
 5     var lastY=0;
 6     // ev 为系统自带参数
 7     obj.onmousedown=function(ev)
 8     {
 9        var Ev=ev||event; // FF || IE
10        var disX=Ev.clientX-parseInt(getStyle(obj,'left'));
11        var disY=Ev.clientY-parseInt(getStyle(obj,'top'));
12     
13        //事件捕获,设置页面鼠标事件集中到 拖拽元素上,针对低版本IE
14        if(obj.setCapture)
15        {
16               //两种写法都可以,document 是防止鼠标拖拽过快,obj 跟不上 鼠标
17               // 由于设置事件捕获,所以对象 可以设置为 obj, 应用于低版本IE
18               // document.onmousemove=Move;
19            // document.onmouseup=Up;
20            obj.onmousemove=Move;
21            obj.onmouseup=Up;
22            obj.setCapture();
23        }
24         else
25        {
26            document.onmousemove=Move;
27            document.onmouseup=Up;
28        }
29            // 鼠标移动,函数上的 ev 参数是系统传过来的
30         function Move(ev)
31         {
32            var Ev=ev||event; // FF || IE 
33            var l=Ev.clientX-disX;
34            var t=Ev.clientY-disY;
35         
36         
37            if(l>=document.documentElement.clientWidth-parseInt(getStyle(obj,'width')))
38            {
39                l=document.documentElement.clientWidth-parseInt(getStyle(obj,'width'));
40            }
41            else if(l<=0)
42            {  l=0;    }
43            
44            if(t>=document.documentElement.clientHeight-parseInt(getStyle(obj,'height')))
45            {
46                t=document.documentElement.clientHeight-parseInt(getStyle(obj,'height'));
47             }
48            else if(t<=0)
49            {  t=0;  }
50            
51            lastX=l;
52            lastY=t; // 当前的点赋给一个变量(上一个点)
53            obj.style.left=l+'px';
54              obj.style.top=t+'px'; //移动物体
55         }
56         // 鼠标抬起
57         function Up()
58           {
59             document.onmousemove=null;
60             document.onmouseup=null;
61             // 释放捕获
62             if(obj.releaseCapture)
63             { obj.releaseCapture(); }
64 
65           } 
66           // 解决 chrome ff IE9 浏览器拖拽时选择文字、内容问题
67         return false;
68     }
69 }
70 
71 //提取非行间样式
72 function getStyle(obj,attr)
73 {
74   if(obj.currentStyle)
75   { return obj.currentStyle[attr];}
76   else
77   { return getComputedStyle(obj,false)[attr];}    
78 }
View Code

html 部分

<body>
    <div id="ele">单个退拽元素<br/>原生js<br/>不跟随页面滚动</div>
</body>

多个元素拖拽,不随页面滚动

css 部分

body{height:2000px;}
div{width:150px; height:150px;cursor: move;position: fixed;top:50px;color:#fff;box-sizing: border-box;z-index: 10;font-size: 16px}
#ele1{background:#2196f3;left:10px; }
#ele2{background:#ff5722;left:180px;}
#ele3{background:#08c80f;left:360px; }

js 部分

window.onload=function(){
    //获取拖拽的元素
    var ele1=document.getElementById('ele1');
    var ele2=document.getElementById('ele2');
    var ele3=document.getElementById('ele3');
    // 层级问题默认 ele1:1,ele2:2,ele3:3
    // 定义公共层级变量,3个定义的一样,这里取了第一个
    this.layer=parseInt(getStyle(ele1,'z-index'))
    drag(ele1);
    drag(ele2);
    drag(ele3);
}
 1 // 拖拽运动
 2 function drag(obj){
 3     var lastX=0;
 4     var lastY=0;
 5     
 6     // ev 为系统自带参数
 7     obj.onmousedown=function(ev)
 8     {
 9        var Ev=ev||event; // FF || IE
10        var disX=Ev.clientX-parseInt(getStyle(obj,'left'));
11        var disY=Ev.clientY-parseInt(getStyle(obj,'top'));
12        // 层级问题,最后拖拽的在最上面,由于 zIndex 最大值是一个非常大的数,所以这里没有限制处理
13        obj.style.zIndex=window.layer=window.layer+1
14 
15        //事件捕获,设置页面鼠标事件集中到 拖拽元素上   针对IE
16        if(obj.setCapture) 
17        {
18            document.onmousemove=Move;
19            document.onmouseup=Up;
20            obj.setCapture();
21        }
22         else
23        {
24            document.onmousemove=Move;
25            document.onmouseup=Up;
26        }
27            // 鼠标移动
28         function Move(ev)
29         {
30            var Ev=ev||event;
31            var l=Ev.clientX-disX;
32            var t=Ev.clientY-disY;
33         
34            if(l>=document.documentElement.clientWidth-parseInt(getStyle(obj,'width')))
35            {
36                l=document.documentElement.clientWidth-parseInt(getStyle(obj,'width'));
37            }
38            else if(l<=0)
39            {  l=0;    }
40            
41            if(t>=document.documentElement.clientHeight-parseInt(getStyle(obj,'height')))
42            {
43                t=document.documentElement.clientHeight-parseInt(getStyle(obj,'height'));
44             }
45            else if(t<=0)
46            {  t=0;  }
47            
48            lastX=l;
49            lastY=t; // 当前的点赋给一个变量(上一个点)
50            obj.style.left=l+'px';
51              obj.style.top=t+'px'; //移动物体
52         }
53         // 鼠标抬起
54         function Up()
55           {
56             document.onmousemove=null;
57             document.onmouseup=null;
58             // 释放事件捕获
59             if(obj.releaseCapture)
60             { obj.releaseCapture(); }
61 
62           } 
63         return false; // 解决 chrome ff IE9 浏览器拖拽时选择文字、内容问题
64     }
65 }
66 
67 //提取非行间样式
68 function getStyle(obj,attr)
69 {
70   if(obj.currentStyle)
71   { return obj.currentStyle[attr];}
72   else
73   { return getComputedStyle(obj,false)[attr];}    
74 }
View Code

html 部分

<body>
    <div id="ele1">多个退拽元素<br/>原生js<br/>不跟随页面滚动<br/>最后拖拽的在最上面</div>
    <div id="ele2">多个退拽元素<br/>原生js<br/>不跟随页面滚动<br/>最后拖拽的在最上面</div>
    <div id="ele3">多个退拽元素<br/>原生js<br/>不跟随页面滚动<br/>最后拖拽的在最上面</div>
</body>

单个元素拖拽,添加选项配置

css 部分

/*body{height:2000px;width:2000px;}*/
*{margin:0px;padding:0px;}
p{margin:150px; }
/*如果父元素不是body,建议手动指定 left top 值,如果不指定 默认 bottom:0; left:50( 我这里设置margin:50 原因); */
#warp{width:500px;height:500px;border: 1px #ccc solid;margin:50px; background: #fff;left:50px;top:50px;}
#ele{width:150px; height:150px;cursor: move;color:#fff;box-sizing: border-box;z-index: 10;font-size: 16px;background:#2196f3; }

js 部分

配置参数:

top,bottom,left,right 默认值为 0 ,拖拽元素 距离 范围元素(默认body) 的距离
direction 拖拽方向,默认为任意方向,lr(左右) tb(上下)
parent:'warp', 为页面唯一元素,拖拽元素活动范围 元素,id 名称,例如 warp ,默认body整个页面
scroll:false 拖拽元素是否随 页面滚动 false 不随页面滚动,true 随页面滚动

window.onload=function(){
    // 配置选项
    var opt={
            top:0,
            bottom:0,
            left:20,
            right:10,
            parent:'warp', // 为页面唯一元素,id 名称,例如 warp ,默认body整个页面
            scroll:false // 拖拽元素是否随 页面滚动 false 不随页面滚动,true 随页面滚动
    }
    var obj=document.getElementById('ele');
    // 调用退拽函数
    drag(obj,opt);
}
  1 // 拖拽运动
  2 function drag(obj,opt={},){
  3     // 默认配置选项
  4     var option={
  5             direction:'auto',//方向 lr(左右)  tb(上下)
  6             // 运动范围 默认父级边界
  7             top:0,
  8             bottom:0,
  9             left:0,
 10             right:0,
 11             //parent:'warp', // 为页面唯一元素,id 名称,例如 warp ,默认body整个页面
 12             scroll:false // 拖拽元素是否随 页面滚动 false 不随页面滚动,true 随页面滚动
 13         }
 14          // 合并对象参数
 15         Object.assign(option,opt)
 16           
 17         var lastX=0;
 18         var lastY=0;
 19         var parent_width=0,parent_height=0,parent_left=0,parent_top=0;
 20         var ele_position='fixed'
 21         if(option.scroll){
 22             ele_position='absolute'
 23         }else{
 24             // 如果不跟随页面滚动,并且元素父级不是body,父元素定位,
 25             if(option.parent)
 26                 document.getElementById(option.parent).style.position='fixed'
 27         }
 28 
 29         // 设置元素的定位,需要放置获取 parent_* 值之前
 30         obj.style.position=ele_position
 31         
 32         if(option.parent){
 33             var parent_ele=document.getElementById(option.parent)
 34             parent_width=parent_ele.clientWidth;
 35             parent_height=parent_ele.clientHeight;
 36             parent_left=parent_ele.offsetLeft;
 37             parent_top=parent_ele.offsetTop;
 38         }else{
 39                 if(option.scroll){
 40                     parent_width=document.documentElement.scrollWidth
 41                     parent_height=document.documentElement.scrollHeight
 42                 }else{
 43                     parent_width=document.documentElement.clientWidth
 44                     parent_height=document.documentElement.clientHeight
 45                 }
 46         }
 47 
 48         // 设置元素位置
 49         obj.style.left=option.left+parent_left+'px'
 50         obj.style.top=option.top+parent_top+'px'
 51 
 52         obj.onmousedown=function(ev)
 53         {
 54            var Ev=ev||event;
 55            var disX=0,disY=0;
 56 
 57            if(option.direction=="lr"){
 58                      disX=Ev.clientX-parseInt(getStyle(obj,'left'));
 59            }else if(option.direction=="tb"){
 60                  disY=Ev.clientY-parseInt(getStyle(obj,'top'));
 61            }else{
 62                  disX=Ev.clientX-parseInt(getStyle(obj,'left'));
 63                  disY=Ev.clientY-parseInt(getStyle(obj,'top'));
 64            }
 65 
 66            if(obj.setCapture)//设置鼠标捕获  针对IE
 67            {
 68                document.onmousemove=Move;
 69                document.onmouseup=Up;
 70                obj.setCapture();
 71            }else
 72            {
 73                document.onmousemove=Move;
 74                document.onmouseup=Up;
 75            }
 76            // 鼠标移动
 77            function Move(ev)
 78            {
 79                var Ev=ev||event;
 80                var left=0,top=0,move_left=0,move_top=0
 81                if(option.direction=="lr"){
 82                        // 可移动的最大左边距离
 83                        move_left=parent_width-parseInt(getStyle(obj,'width'))-option.right+parent_left
 84                           if(left>=move_left){
 85                               left=move_left
 86                           }else if(left<=option.left+parent_left){
 87                               left=option.left+parent_left
 88                           }else{
 89                               left=Ev.clientX-disX;
 90                           }
 91                           lastX=left;
 92                           obj.style.left=left+'px';
 93                    
 94                    }else if(option.direction=="tb"){
 95                     // 可以移动的最大上边距
 96                     move_top=parent_height-parseInt(getStyle(obj,'height'))-option.top+parent_top
 97                     if(top>=move_top){
 98                         top=move_top
 99                     }else if(top<=option.bottom+parent_top){
100                         top=option.bottom
101                     }else{
102                             top=Ev.clientY-disY;
103                     }
104                     lastY=top; 
105                     obj.style.top=top+'px'; 
106                    }else{
107                     left=Ev.clientX-disX;
108                     top=Ev.clientY-disY;
109                 
110                     move_left=parent_width-parseInt(getStyle(obj,'width'))-option.right+parent_left
111                     move_top=parent_height-parseInt(getStyle(obj,'height'))-option.bottom+parent_top
112                 
113                     if(left>=move_left){
114                               left=move_left
115                           }else if(left<=option.left+parent_left){
116                               left=option.left+parent_left
117                           }
118                           if(top>=move_top){
119                         top=move_top
120                      }else if(top<=option.bottom+parent_top){
121                         top=option.bottom+parent_top
122                      }
123 
124                     lastX=left;
125                     lastY=top; // 当前的点赋给一个变量(上一个点)
126                     obj.style.left=left+'px';
127                       obj.style.top=top+'px'; //移动物体
128                    }
129             }
130             // 鼠标抬起
131             function Up()
132               {
133                 document.onmousemove=null;
134                 document.onmouseup=null;
135                 //释放捕获
136                 if(obj.releaseCapture)
137                 { obj.releaseCapture(); }
138 
139               } 
140         return false;
141     }// onmousedown 结束
142 }
143 
144 //提取非行间样式
145 function getStyle(obj,attr)
146 {
147       if(obj.currentStyle)
148       { return obj.currentStyle[attr];}
149       else
150       { return getComputedStyle(obj,false)[attr];}    
151 }
View Code

html 部分

<body>
    <div id="warp"><p>指定元素内拖拽</p></div>    <p>测试部分</p>
    <div id="ele">单个退拽元素<br/>原生js<br/>添加配置选项</div>
    <p>测试部分</p>
</body>
posted @ 2022-12-13 15:35  柔和的天空  阅读(149)  评论(0编辑  收藏  举报