HTML DOM元素的Dragdrop

在前端web页面中,为了提高用户体验,通常会希望将页面中的元素设计成可dragdop的,简化用户操作。这一设计特性在缺少鼠标的触摸屏设备上,显得更为重要。

在早期的应用中,我们通常需要借助第三方的javascript库(Jquery插件等)。在HTML5已经将这一特性引入,提供原生的支持,不用再借助第三方的javascript库。现代化的程序设计中,各种前端库的引入(Jquery, nodejs, ract, angularjs),提高了开发效率,而各自的库也有相应的插件来处理dragdrop,使得开发更为便捷。那HTML5原生的支持,到底是怎么样的?

关键就在DOM元素的 draggable 属性,如果是 draggable = “true” ,表示该元素可被拖拽。 draggable = “false” 或其它值则不可拖拽。

看一个例子:

本样例以table形式呈现,本质是div+css布局(从业务的角度,每一个是一个业务单位,而非单独的列。但只有test item列中的元素是可拖拽的)。每一行作为一个业务单元,但只有test item所在列的元素可拖拽。当其被拖拽到其它其它行的时候,以行为单位进行整体交换。

看一下行的元素布局

1 <div id="div0" class="containerDiv" ondrop="drop(event)" data-dropable="true" ondragover="dragOver(event)" data-dropEl=‘drag0‘ >
2                     <span class="headerCellStyle"> 1</span>
3                      <span id="drag0" ondragstart="drag(event)" data-dragable="true" data-dropElHost=‘div0‘ data-sequence=‘1361‘ data-key=‘1361‘ data-orginalSequence=‘1361‘>
4                         <span style="width:4.3vw;" class="bodyCellStyle" >100</span>
5                         <span  style="width:8.9vw;" class="bodyCellStyle" >Rake</span>
6                         <span id="testitem0" style="vertical-align:middle; display:inline-block;width:21vw;overflow:hidden;white-space:nowrap" class=" dropElCSS" onmouseover="OnMouseEnterEvent(event)" onmouseout="OnMouseLeaveEvent(event)">Max_Load_Clamp </span>
7                         <span style="display:inline-block; width:8.9vw;border-left:0.1vw solid #aaaaaa;border-right:0px;padding:0.2vw 0.2vw;white-space:nowrap"  >2016-09-25 11:07:39</span>
8                     </span>
9                 </div>

可拖拽DOM元素 id="testitem0" 需要特别注意,以testitem作为前缀,在拖拽判断的时候会使用到:

1 if(targetContainer.id.indexOf("testitem")>=0) {
2                 targetContainer = ev.target.parentNode || ev.target.parentElement;
3                 targetContainer = targetContainer.parentNode || targetContainer.parentElement;
4             }

因为span的限制,drapdrop的属性会冒泡到第一个block元素上,影响到parent容器DIV,形成拖拽错乱:drag的元素被pending到drop的容器中,本应该是需要交换的两个元素被合并到一个DIV容器中。通过设定鼠标进入离开事件onmouseover="OnMouseEnterEvent(event)" onmouseout="OnMouseLeaveEvent(event)" ,设定属性dragdrop为true或者false.

 1 function SetItemDragable(dragable, dragEl){
 2             var gloableStatus = true;
 3             if(dragEl)
 4                 dragEl.setAttribute("draggable", gloableStatus&&dragable);
 5         }
 6
 7         function OnMouseEnterEvent(ev){
 8             var elID = ev.target.id;
 9             var parentEl = ev.target.parentNode || ev.target.parentElement;
10             if(parentEl) SetItemDragable(true, parentEl);
11         }
12
13         function OnMouseLeaveEvent(ev){
14             var elID = ev.target.id;
15             var parentEl = ev.target.parentNode || ev.target.parentElement;
16             if(parentEl) SetItemDragable(false, parentEl);
17         }

MouseEvent

你会注意到在dragdrop元素的parent元素上,会有 data- 开头的这种自定义属性:

data-dragable="true" data-dropElHost=‘div0‘ data-sequence=‘1361‘ data-key=‘1361‘ data-orginalSequence=‘1361‘

这些属性是被用来存储业务数据或其它自定义用途的数据。其中,最重要的data-dropElHost指向级元素的DOM(拖拽最终的效果中的整体元素)。 data-dragable="true" 标记该元素从业务角度是否可拖拽,有别于HTML5的自定义属性 dragdrop = "true/false" ,它们唯一的区别就是业务上和技术角度是否可拖拽。

页面上的Save按钮,点击后显示拖拽后变动的元素,将 data-key, data-sequence 中的值作为一个二元组(data-key, data-sequence)表示一个元素的最终值,以字符‘;’作为多个元素值的分隔符。

完整的javascript代码为:

 1 function dragOver(ev) {
 2             ev.preventDefault();
 3
 4         }
 5
 6         function drag(ev) {
 7             if(ev.target.getAttribute("data-dragable")!="true") return;
 8             ev.dataTransfer.setData("text", ev.target.id);
 9         }
10
11         function drop(ev) {
12             ev.preventDefault();
13             var targetContainer = ev.target;
14
15             if(targetContainer.id.indexOf("testitem")>=0) {
16                 targetContainer = ev.target.parentNode || ev.target.parentElement;
17                 targetContainer = targetContainer.parentNode || targetContainer.parentElement;
18             }
19
20             if(targetContainer.getAttribute("data-dropable")!="true") return;
21
22             var data = ev.dataTransfer.getData("text");
23             var dropEl = document.getElementById(data);
24             targetContainer.appendChild(dropEl);
25
26             var dropElHost = document.getElementById(dropEl.getAttribute("data-dropElHost"));
27             var hostOrginalEl = document.getElementById(targetContainer.getAttribute("data-dropEl"));
28             targetContainer.removeChild(hostOrginalEl);
29             dropElHost.appendChild(hostOrginalEl);
30
31             //swap host id of each element
32             hostOrginalEl.setAttribute("data-dropElHost", dropEl.getAttribute("data-dropElHost"));
33             dropEl.setAttribute("data-dropElHost", targetContainer.id);
34
35             //swap drop element id of its container div
36             targetContainer.setAttribute("data-dropEl", data);
37             dropElHost.setAttribute("data-dropEl", hostOrginalEl.id);
38
39             //swap sequence of drop element
40             var hostOrginalElSequence = hostOrginalEl.getAttribute("data-sequence");
41             hostOrginalEl.setAttribute("data-sequence", dropEl.getAttribute("data-sequence"));
42             dropEl.setAttribute("data-sequence", hostOrginalElSequence);
43
44
45             SetSaveBtnStatus(true);
46
47         }
48
49         function ShowSequence() {
50             var idPrefix = "drag";
51             var result = "";
52
53             var data="";
54             var dragElementLength = 504; //there‘re not so many elements now.
55             for (var i = 0; i < dragElementLength; i++) {
56                 var id = idPrefix + i;
57                 var el = document.getElementById(id);
58                 if(el==null) continue;
59                 var currentSequence = el.getAttribute("data-sequence");
60                 var orginalSequence = el.getAttribute("data-orginalSequence");
61
62                 if(currentSequence == orginalSequence) continue;
63
64                 data += "("+el.getAttribute("data-key") +"," +currentSequence+")";
65             }
66
67             if(data.length==0){
68                 MessageBox("ERROR: There‘s no item for order change!");
69                 return;
70             }
71
72             document.getElementById("resultInput").value = escape( data);
73
74             //document.getElementById("form1").submit();
75             document.getElementById("resultDiv").innerHTML = "The updated items are(data-key, data-sequence):" + data;
76         }
77
78         function SetSaveBtnStatus(activity){
79             document.getElementById("saveBtn").disabled = !activity;
80         }
81
82         function SetItemDragable(dragable, dragEl){
83             var gloableStatus = true;
84             if(dragEl)
85                 dragEl.setAttribute("draggable", gloableStatus&&dragable);
86         }
87
88         function OnMouseEnterEvent(ev){
89             var elID = ev.target.id;
90             var parentEl = ev.target.parentNode || ev.target.parentElement;
91             if(parentEl) SetItemDragable(true, parentEl);
92         }
93
94         function OnMouseLeaveEvent(ev){
95             var elID = ev.target.id;
96             var parentEl = ev.target.parentNode || ev.target.parentElement;
97             if(parentEl) SetItemDragable(false, parentEl);
98         }

JavaScript

样式表为:

1 .containerDiv {min-width:350px;width:auto;border:0.1vw solid #aaaaaa;float:none;border-top:0px;}
2 .dateTip{font-style:italic;}
3 .userManual{min-width:350px;width:auto;/*border:0.1vw solid #aaaaaa;*/}
4 .headerCellStyle{font-weight:bold;width:3vw;display:inline-block;margin-left:0.4vw;padding:0.2vw 0px;border-right:0.1vw solid #aaaaaa;white-space:nowrap;}
5 .bodyCellStyle{display:inline-block;margin-left:0.4vw;padding:0.2vw 0px;border-right:0.1vw solid #aaaaaa;white-space:nowrap;}
6    .dropElCSS { width:90%; cursor: pointer;border-radius: 1vw;background-color:white; box-shadow: 0.1vw 0.3vw 0.3px #888888;border:0px dashed black ; }

CSS

附上完整的DEMO

时间: 2024-10-09 11:09:21

HTML DOM元素的Dragdrop的相关文章

操作DOM元素,Dom元素添加颜色,删除第二个li元素

<html> <head> <title>demo</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript"> /* 示例操作DOM元素 */ window.onload = function(){ //给Dom元素添

【温故而知新-Javascript】为DOM元素设置样式

1. 使用样式表 可以通过document.styleSheets属性访问文档中可用的CSS样式表,它会返回一组对象集合,这些对象代表了与文档管理的各个样式表. 每个样式表 都由一个CSSStyleSheet 对象代表,它提供了一组属性和方法来操作文档里的样式. 1.1 获得样式表的基本信息 第一步是获得定义在文档中的样式表的一些基本信息. <!DOCTYPE html> <html lang="en"> <head> <meta charse

点击事件然后页面跳转到指定DOM元素的位置

设置一个函数,执行函数滚动条自动拖动,页面跳转到指定DOM元素的位置. 实现方式很简单,首先引入animatescroll.js文件(要先引入JQuery),然后 $('#id').animatescroll(); 即可调到指定DOM元素在页面的位置. 为方便可以编写一个函数,传入DOM元素的ID function jumpTo(id){ $("#"+id).animatescroll(); } 附animatescroll.js /* 使用方法: $("#id")

IE attachEvent事件处理程序(事件绑定的函数)的this指向的是window不是执行当前事件的dom元素

IE attachEvent事件处理程序(事件绑定的函数)的this指向的是window不是执行当前事件的dom元素. attachEvent(type,listener); listener函数中的this不是指向执行当前事件的dom而是window切记,感觉这一点IE做的太奇怪了!

JavaScript HTML DOM 元素(节点)

JavaScript HTML DOM 元素(节点) 创建新的 HTML 元素 创建新的 HTML 元素 如需向 HTML DOM 添加新元素,您必须首先创建该元素(元素节点),然后向一个已存在的元素追加该元素. 实例 <div id="div1"><p id="p1">This is a paragraph.</p><p id="p2">This is another paragraph.<

html2canvas根据DOM元素样式实现网页截图

html2canvas根据DOM元素样式实现网页截图 html2canvas是一个相当不错的JavaScript类库,它使用了html5和css3的一些新功能特性,实现了在客户端对网页进行截图的功能.html2canvas通过获取页面的DOM和元素的样式信息,并将其渲染成canvas图片,从而实现给页面截图的功能. 它不需要来自服务器任何渲染,整张图片都是在客户端浏览器创建.当浏览器不支持Canvas时,将采用Flashcanvas或ExplorerCanvas技术代替实现.以下浏览器能够很好的

使用dom元素和jquery元素实现简单增删改的练习

软件开发实际就是数据的增删改查,javascript前端开发也不例外.今天学了jquery框架的简单使用.于是用它实现简单的增删改,接着也用原始的javascript实现同样的功能,以便看出jquery的强大: 代码如下: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" con

前端性能优化-精确的控制dom元素

6.dom操作 精确的控制dom元素(id 选择器) 1.浏览器的开发者工具针对页面进行调优 Network窗口 Stalled(阻塞) DNS Lookup(域名解析) dns缓存 建立持久连接 Initial connection(初始化连接) SSL(包含于HTTPS连接中) Waiting(等待响应) Request sent(发送请求) Content Download(下载) 2. js调试 设置在DOM node发生变化时触发断点 dom 右键 Break on 可以设置成这个节点

jQuery - DOM 元素方法

jQuery DOM 元素方法 - get() 方法 实例 获得第一个 p 元素的名称和值: <script type="text/javascript">   $(document).ready(function(){   $("button").click(function(){   x=$("p").get(0);   $("div").text(x.nodeName + ": " + x