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

今世:

先来段HTML代码吧.

  1. <body onload="init()">
  2. <div id="content"></div>
  3.  
  4. <div class="dragDiv" id="div1">
  5. <img id="drag1" src="1.jpg" width="336" index="1" height="69" draggable="true" />
  6. </div>
  7. <br>
  8. <div class="dragDiv" id="div2">
  9. <img id="drag2" src="2.jpg" width="236" index="2" height="49" draggable="true" />
  10. </div>
  11. <div class="dragDiv" id="div3">
  12. <img id="drag3" src="big.png" width="336" index="3" height="69" draggable="true" />
  13. </div>
  14. <br>
  15. <div class="dragDiv" id="div4">
  16. <img id="drag4" src="mvp1.jpg" width="236" index="4" height="49" draggable="true" />
  17. </div>
  18. </body>

代码为整个HTML代码片段,没有特别的地方,唯一需要注意的就是draggable属性,设置为true,这样就可以拖动他了。然后,给每个img(可以换成自己需要的element标签)添加了一个自定义属性index,用于在交   换位置之后,保存元素的顺序。

Javascript代码:

  1. function init() {
  2.  
  3. var data;
  4. $(".dragDiv").each(function () {
  5.  
  6. //如果是IE
  7. if (!!window.ActiveXObject || "ActiveXObject" in window) {
  8.  
  9. $(this).on("dragstart", function (ev) {
  10. /*拖拽开始*/
  11. //拖拽效果
  12. ev.originalEvent.dataTransfer.effectAllowed = "move";
  13.  
  14. data = ev.target.id;
  15. return true;
  16. });
  17.  
  18. $(this).on("dragend", function (ev) {
  19. return false
  20. });
  21.  
  22. $(this).on("dragover", function (ev) {
  23. /*拖拽元素在目标元素头上移动的时候*/
  24. ev.preventDefault();
  25. return true;
  26. });
  27.  
  28. $(this).on("dragenter", function (ev) {
  29.  
  30. return true;
  31. });
  32.  
  33. $(this).on("drop", function (ev) {
  34. ev.preventDefault();
  35. var src = document.getElementById(data);
  36.  
  37. var srcParent = src.parentNode;
  38. var tgt = ev.currentTarget.firstElementChild;
  39.  
  40. //用src替换tgt
  41. ev.currentTarget.replaceChild(src, tgt);
  42. srcParent.appendChild(tgt);
  43.  
  44. var sourceIndex = $(src).attr("index");
  45. var targetIndex = $(tgt).attr("index");
  46.  
  47. //存在保存的索引值
  48. if (localStorage.indexs) {
  49. var indexs = localStorage.indexs;
  50. indexs = indexs.replace(sourceIndex, "*");
  51. indexs = indexs.replace(targetIndex, "&");
  52. indexs = indexs.replace("*", targetIndex);
  53. indexs = indexs.replace("&", sourceIndex);
  54. //将新的索引顺序保存在localStorage
  55. localStorage.indexs = indexs;
  56. }
  57. });
  58.  
  59. }
  60. //Html5的拖拽IE不支持
  61. else {
  62.  
  63. $(this).on("dragover", function (event) {
  64. event.preventDefault();
  65. });
  66. $(this).on("drop", function (ev) {
  67.  
  68. ev.preventDefault();
  69. var src = document.getElementById(ev.originalEvent.dataTransfer.getData("src"));
  70.  
  71. var srcParent = src.parentNode;
  72. var tgt = ev.currentTarget.firstElementChild;
  73.  
  74. //用src替换tgt
  75. ev.currentTarget.replaceChild(src, tgt);
  76. srcParent.appendChild(tgt);
  77.  
  78. var sourceIndex = $(src).attr("index");
  79. var targetIndex = $(tgt).attr("index");
  80.  
  81. //存在保存的索引值
  82. if (localStorage.indexs) {
  83. var indexs = localStorage.indexs;
  84. indexs = indexs.replace(sourceIndex, "*");
  85. indexs = indexs.replace(targetIndex, "&");
  86. indexs = indexs.replace("*", targetIndex);
  87. indexs = indexs.replace("&", sourceIndex);
  88. //将新的索引顺序保存在localStorage
  89. localStorage.indexs = indexs;
  90. }
  91. });
  92.  
  93. $(this).children(0).on("dragstart", function (event) {
  94. event.originalEvent.dataTransfer.setData("src", event.target.id);
  95. });
  96. }
  97. });
  98.  
  99. //不存在保存的索引值,则保存初始化
  100. if (!localStorage.indexs) {
  101. localStorage.indexs = "1,2,3,4";
  102. }
  103. else {
  104. //从保存的索引值中,按照顺序显示div
  105. var indexs = localStorage.indexs.toString().split(",");
  106. for (var i = 0; i < indexs.length; i++) {
  107. var index = indexs[i];
  108. var divElement = document.getElementById("div" + index);
  109. document.getElementById("content").insertAdjacentElement("beforeend", divElement);
  110. }
  111. }
  112. }

上述代码好长,吓死人了,没关系,慢慢分析。代码分为两部分,分别是处理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. Windows平台下Python2.7中pip的安装方法

    本文允许转载,转载请保留全文! [请先阅读][说明&总目录]http://www.cnblogs.com/tbcaaa8/p/4415055.html 1. 文件下载 需要下载并运行ez_se ...

  2. java 顺序表

    想看看java版的数据结构,了解一下树的一些操作,写了个顺序表熟悉一下 package com.sqlist; /** * @author xiangfei * 定义一个顺序表 * */ public ...

  3. android数独游戏

    最近没事干,照着视频教程写了一个数独游戏,很粗糙还有很多要修改的地方.下面就来说说这个游戏吧 1.自定义一个View控件,用来在屏幕上显示一个9*9的格子,其实就是横着画8条线,竖着画8跳线,然后将其 ...

  4. VIMTUTOR《VIM教程》

    =============================================================================== =      欢     迎     阅 ...

  5. 学习ThinkPHP-1

    ThinkPHP 自建路由 关于文件关联 当在Applicatin\Home\Controller文件夹下建立一个控制器时如LoginController.class.php 在此文件夹下还有一个默认 ...

  6. Python编码设置

    系统编码顺序: 1, a.encode(sys.stdout.encoding) 2, a.encode(default_string) sys.stdout.encoding里的值可以用环境变量PY ...

  7. HDU 5151 Sit sit sit 区间dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5151 题解: 有n个椅子,编号为1到n. 现在有n个同学,编号为1到n,从第一个同学开始选择要坐的位 ...

  8. 小技巧--字符串输入从a[1]开始

    char a[100],b[100]; cin>>a>>(b+1);//cin: abcd abcd cout<<a[1]<<endl<<b ...

  9. 04.spring-data-redis与Jedis整合使用

    1.spring-data-redis与Jedis简单整合 spring-data-redis与Jedis简单整合,Redis没有任何集群只是单节点工作,使用连接池 1.创建spring-contex ...

  10. shell编程之环境变量

    在shell编程里我们首先接触到的是环境变量,常用命令说明 1. 使用echo命令查看单个环境变量.例如: echo $PATH 2. 使用env查看所有环境变量.例如: env 3. 使用set查看 ...