前世:项目中需要拖动div,然后和某个div进行位置交换,这不是关键,关键是还要保存位置,然后在下次打开的时候按照保存的位置显示。还好本人功力深厚,一下子就想到了用localStorage来保存,事实证明真的很好用哦。保存数据的方法有了,然后开始"探索"如何用html(5)和js来实现拖拽的效果,由于H5给了比较规范的实现方式,所以在Chrome中轻松实现,万恶的IE(很少骂IE)竟然不兼容,NONONONO,心塞,只好用了两种方式分别实现拖拽效果。(其实两种方式内的代码很相似,唯一不同的就是事件的名称罢了,方法体几乎一模一样)。

今世:

先来段HTML代码吧.

<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代码:

 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中,这样我们的拖动并保存已经完成了;

在IE中的处理,和H5的标准方式基本一致,唯一区别就是对setData 的访问,和对dataTransfer的访问,在上文中由于setData一直出错,索性就放弃了,直接使用了一个局部变量,对dataTransfer的访问也给出了正确的使用方式,另外就是Ie对拖拽行为的事件名称和H5标准的事件名称有一些区别,方法体基本一致。

还没结束,哈哈哈。我们只做了保存,可是加载呢,没错保存是其次,重新加载显示正确的顺序才是最主要的。
在init方法体中我们先判断是否已经存在了localStorage.indexs,如果不存在,说明我们没有保存过,那么就给他一个默认值吧(其实也可以不给它,反正拖拽后还是要保存的额),如果存在则取出indexs,然后拆分成一个数组,最后遍历整个数组,找到索引对应的div(可以是任意一个元素,不一定是div),然后放入目标div父容器中即可。

好了,这个功能在Chrome中实现起来挺简单的,就是一些标准的事件,然后进行数据传递,保存,加载即可。在IE中真是够了,各种不兼容,各种出错,还好最后也是给弄出来了。希望能帮助到大家。

HTML5之拖拽(兼容IE和非IE)的更多相关文章

  1. html5 文件拖拽上传

    本文首先发表在  码蜂笔记 : http://coderbee.net/index.php/web/20130703/266 html5 文件拖拽上传是个老话题了,网上有很多例子,我一开始的代码也是网 ...

  2. 基于html5可拖拽图片循环滚动切换

    分享一款基于html5可拖拽图片循环滚动切换.这是一款支持手机端拖拽切换的网站图片循环滚动特效.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div id="s ...

  3. 关于HTML5的拖拽

    不介绍具体情况,先看API,注意看后面括号的说明 dragstart:拖拽开始(应用于被拖拽对象) drag:拖拽中(应用于被拖拽对象) dragenter:拖拽到指定位置(应用于拖拽目标) drag ...

  4. HTML5图片拖拽预览原理及实现

    一.前言 这两天恰好有一位同事问我怎样做一个图片预览功能.作为现代人的我们首先想到的当然是HTML5啦,其实HTML5做图片预览已经是一个老生常谈的问题了.我在这里就简单说说其中相关的一些东西,当然会 ...

  5. [开源应用]利用HTTPHandler+resumableJs+HTML5实现拖拽上传[大]文件

    前言: 大文件传输一直是技术上的一大难点.文件过大时,一些性提交所有的内容进内存是不现实的.大文件带来问题还有是否支持断点传输和多文件同时传输. 本文以resumableJs为例,介绍了如何在ASP. ...

  6. HTML5文件拖拽

    HTML5新增的File API, 可以获取名称.文件大小.类型等信息,需先对DOM中的Element进行拖拽事件绑定 相关API 首先获取节点,绑定拖动到该节点的事件,可以改变鼠标形状 var dr ...

  7. HTML5 实现拖拽

    如图 可以从第一个方框拖拽花色到第二个方框中. 也可以再拖动回来. 具体代码实现 index.html <!DOCTYPE HTML> <html> <head> ...

  8. html5实现拖拽文件上传

    以下是自学it网--中级班上课笔记 网址:www.zixue.it html文件 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict ...

  9. HTML5原生拖拽/拖放⎡Drag & Drop⎦详解

    前言 拖放(drap && drop)在我们平时的工作中,经常遇到.它表示:抓取对象以后拖放到另一个位置.目前,它是HTML5标准的一部分.我从几个方面学习并实践这个功能. 拖放的流程 ...

随机推荐

  1. 1.1 MySQL 逻辑架构

  2. KinectStudio使用教程

    在Kinect SDK 2.0安装结束之后,会有一个KinectStudio的调试工具,他可以将动作记录下,以后即便脱离了Kinect传感器也可以愉快的调试了.现在我们来看看如何使用 首先打开Kine ...

  3. 20145105 《Java程序设计》第2周学习总结

    20145105 <Java程序设计>第2周学习总结 教材学习内容总结 第三章主要的学习内容与c语言有很多相似的地方,讲述了Java的基本语法.其中涵盖: 1. 类型: - short整数 ...

  4. php图形图像处理之生成验证码

    \(^o^)/~ 现在网上越来越离不开验证码了,不知道小伙伴们知不知利用php的GD库就可以生成验证码,Σ(⊙▽⊙"a ...... 首先介绍几个需要用的函数. 1.imagesetpixe ...

  5. Java Synchronized Blocks vs. Methods

    It's possible to synchronize both an entire method and a section of code within a method, and you ma ...

  6. git学习,什么是git?

    什么是 Git? 百度百科显示,Git是 Linux 之父 Linus Trovalds,为管理 Linux 内核代码而建立的,被认为是分布式版本控制工具中的顶级水准.智能.友好.强健.高效. 正如所 ...

  7. JVM 崩溃 Failed to write core dump解决办法 WINDOWS

    JVM 崩溃 Failed to write core dump解决办法 WINDOWS MIT key words: JVM,崩溃,windows,Failed,core dump,虚拟内存 最近从 ...

  8. 【BZOJ】【1028】【JSOI2007】麻将

    暴力/模拟 $n\leq400$,嗯……这是一个很小的数据范围= = 判断一副牌是不是听牌并求出听什么牌太麻烦了,干脆我们直接判是不是胡牌好了~ 枚举胡的是哪张牌,然后判一下加上这张牌后是否能胡. 算 ...

  9. 2016ACM-ICPC Qingdao Online青岛网络赛题解

    TonyFang+Sps+我=5/12 滚了个大粗 2016年9月21日16:42:36 10题完工辣 01 题意:求形同的数中大于n的最小值 题解:预处理所有的(5194个),在这里面二分 #inc ...

  10. 深入理解python之self

    首先明确的是self只有在类的方法中才会有,独立的函数或方法是不必带有self的.self在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数. self名称不是必须的,在python中self ...