前世:项目中须要拖动div,而后和某个div进行位置交换,这不是关键,关键是还要保存位置,而后在下次打开的时候按照保存的位置显示。还好本人功力深厚,一会儿就想到了用localStorage来保存,事实证实真的很好用哦。保存数据的方法有了,而后开始"探索"如何用html(5)和js来实现拖拽的效果,因为H5给了比较规范的实现方式,因此在Chrome中轻松实现,万恶的IE(不多骂IE)居然不兼容,NONONONO,心塞,只好用了两种方式分别实现拖拽效果。(其实两种方式内的代码很类似,惟一不一样的就是事件的名称罢了,方法体几乎如出一辙)。javascript
今世:html
先来段HTML代码吧.java
<body onload="init()"> <div id="content"></div> <div class="dragDiv" id="div1"> <img id="drag1" src="1.jpg" width="336" index="1" height="69" draggable="true" /> </div> <br> <div class="dragDiv" id="div2"> <img id="drag2" src="2.jpg" width="236" index="2" height="49" draggable="true" /> </div> <div class="dragDiv" id="div3"> <img id="drag3" src="big.png" width="336" index="3" height="69" draggable="true" /> </div> <br> <div class="dragDiv" id="div4"> <img id="drag4" src="mvp1.jpg" width="236" index="4" height="49" draggable="true" /> </div> </body>
代码为整个HTML代码片断,没有特别的地方,惟一须要注意的就是draggable属性,设置为true,这样就能够拖动他了。而后,给每一个img(能够换成本身须要的element标签)添加了一个自定义属性index,用于在交 换位置以后,保存元素的顺序。数组
Javascript代码:app
function init() { var data; $(".dragDiv").each(function () { //若是是IE if (!!window.ActiveXObject || "ActiveXObject" in window) { $(this).on("dragstart", function (ev) { /*拖拽开始*/ //拖拽效果 ev.originalEvent.dataTransfer.effectAllowed = "move"; data = ev.target.id; return true; }); $(this).on("dragend", function (ev) { return false }); $(this).on("dragover", function (ev) { /*拖拽元素在目标元素头上移动的时候*/ ev.preventDefault(); return true; }); $(this).on("dragenter", function (ev) { return true; }); $(this).on("drop", function (ev) { ev.preventDefault(); var src = document.getElementById(data); var srcParent = src.parentNode; var tgt = ev.currentTarget.firstElementChild; //用src替换tgt ev.currentTarget.replaceChild(src, tgt); srcParent.appendChild(tgt); var sourceIndex = $(src).attr("index"); var targetIndex = $(tgt).attr("index"); //存在保存的索引值 if (localStorage.indexs) { var indexs = localStorage.indexs; indexs = indexs.replace(sourceIndex, "*"); indexs = indexs.replace(targetIndex, "&"); indexs = indexs.replace("*", targetIndex); indexs = indexs.replace("&", sourceIndex); //将新的索引顺序保存在localStorage localStorage.indexs = indexs; } }); } //Html5的拖拽IE不支持 else { $(this).on("dragover", function (event) { event.preventDefault(); }); $(this).on("drop", function (ev) { ev.preventDefault(); var src = document.getElementById(ev.originalEvent.dataTransfer.getData("src")); var srcParent = src.parentNode; var tgt = ev.currentTarget.firstElementChild; //用src替换tgt ev.currentTarget.replaceChild(src, tgt); srcParent.appendChild(tgt); var sourceIndex = $(src).attr("index"); var targetIndex = $(tgt).attr("index"); //存在保存的索引值 if (localStorage.indexs) { var indexs = localStorage.indexs; indexs = indexs.replace(sourceIndex, "*"); indexs = indexs.replace(targetIndex, "&"); indexs = indexs.replace("*", targetIndex); indexs = indexs.replace("&", sourceIndex); //将新的索引顺序保存在localStorage localStorage.indexs = indexs; } }); $(this).children(0).on("dragstart", function (event) { event.originalEvent.dataTransfer.setData("src", event.target.id); }); } }); //不存在保存的索引值,则保存初始化 if (!localStorage.indexs) { localStorage.indexs = "1,2,3,4"; } else { //从保存的索引值中,按照顺序显示div var indexs = localStorage.indexs.toString().split(","); for (var i = 0; i < indexs.length; i++) { var index = indexs[i]; var divElement = document.getElementById("div" + index); document.getElementById("content").insertAdjacentElement("beforeend", divElement); } } }
上述代码好长,吓死人了,不要紧,慢慢分析。代码分为两部分,分别是处理IE和非IE的逻辑,咱们主要分析非IE的逻辑(由于通用)。一共有三个主要的事件:
ondragstart:开始拖拽,当在某一个可拖拽的Element上按下鼠标拖动就触发此事件。
在此方法中将用于拖拽(交换位置)的Element的Id经过setData保存起来,在dorp事件中会使用到此数据。
ondragover:当拖拽的动做,移动到目标Element。
此方法只有一行代码,event.preventDefault(),意思是阻止元素发生默认的行为,也就是不要显示元素默认的拖拽鼠标悬浮效果。
ondrop:当拖放结束,松开鼠标,触发此事件。
这个方法代码略多,主要作了几件事情。
1.经过getdata获得保存的数据,而后找到拖拽的元素Element,而后再获得目标Element,用于交换;
2.经过replaceChild方法将Source Element和Target Element进行替换操做,而后将Target从新添加到Source Element的父容器中(经过appendChild方法);
3.在上文的HTML中看到给每个可拖动的img添加了index属性,那么就须要获得Source Element和Target Element的index,用于保存到localStorage中;
4.在获得两个Index以后,就须要从localStorage中取出以前保存的indexs值,而后分别替换Source Index和Target Index为一个特殊字符(你也能够替换为任意的符号,主要是为了能够比较简单的进行替换);
5.在最后一步,咱们用Source Index替换Target Index的特殊字符,用Target Index替换Source Index的特殊字符,而后将新的indexs值保存在localStorage中,这样咱们的拖动并保存已经完成了;this
在IE中的处理,和H5的标准方式基本一致,惟一区别就是对setData 的访问,和对dataTransfer的访问,在上文中因为setData一直出错,索性就放弃了,直接使用了一个局部变量,对dataTransfer的访问也给出了正确的使用方式,另外就是Ie对拖拽行为的事件名称和H5标准的事件名称有一些区别,方法体基本一致。spa
还没结束,哈哈哈。咱们只作了保存,但是加载呢,没错保存是其次,从新加载显示正确的顺序才是最主要的。
在init方法体中咱们先判断是否已经存在了localStorage.indexs,若是不存在,说明咱们没有保存过,那么就给他一个默认值吧(其实也能够不给它,反正拖拽后仍是要保存的额),若是存在则取出indexs,而后拆分红一个数组,最后遍历整个数组,找到索引对应的div(能够是任意一个元素,不必定是div),而后放入目标div父容器中便可。htm
好了,这个功能在Chrome中实现起来挺简单的,就是一些标准的事件,而后进行数据传递,保存,加载便可。在IE中真是够了,各类不兼容,各类出错,还好最后也是给弄出来了。但愿能帮助到你们。blog