HTML5之拖拽(兼容IE和非IE)

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

今世:

先来段HTML代码吧.

<body >
    <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中真是够了,各种不兼容,各种出错,还好最后也是给弄出来了。希望能帮助到大家。

时间: 2024-11-10 03:54:53

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

HTML5开发 拖拽文件上传

Drag&Drop 拖拽功能的处理 关于HTML5拖拽文件上传,其实国外已经有很多网站有这样的应用,最早推出拖拽上传应用的是 Gmail,它支持标准浏览器下拖拽本地文件到浏览器中作为邮件的附件发送,但其实现在利用HTML5的功能实现,主要借助于新版支持的浏览器来实现,IE还是弱很多. 拖拽上传应用主要使用了以下 HTML5技术: Drag&Drop : HTML5基于拖拽的事件机制.File API : 可以很方便的让 Web 应用访问文件对象,File API 包括FileList.Bl

Nodejs express、html5实现拖拽上传

Nodejs express.html5实现拖拽上传 一.前言 文件上传是一个比较常见的功能,传统的选择方式的上传比较麻烦,需要先点击上传按钮,然后再找到文件的路径,然后上传.给用户体验带来很大问题.html5开始支持拖拽上传的需要的api.nodejs也是一个最近越来越流行的技术,这也是自己第一次接触nodejs,在nodejs开发中,最常用的开发框架之一是expess,它是一个类似mvc模式的框架.结合html5.nodejs express实现了拖拽上传的功能. 二.基础知识普及 1.No

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

分享一款基于html5可拖拽图片循环滚动切换.这是一款支持手机端拖拽切换的网站图片循环滚动特效.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div id="site-wrapper"> <section id="section-header" data-coloroverlap="dark"></section> <section id="second-phase&qu

HTML5 的拖拽介绍

本文主要介绍与拖拽操作相关的对象及事件信息,但并不涉及太多的源码演示. 一个简单的示例 在html5中要实现拖放操作,相对于以前通过鼠标操作实现,要简单得多,数据安全性也更有保障.只需要以下几步即可. 给被拖拽元素添加draggable属性,如果是文件拖放. 为目标元素添加一个dropzone属性,这一步也不是必须的,可以省略. 在拖拽元素的dragstart中初始化相关的数据信息,主要是DataTransfer对象. 在目标元素的dragover事件中,取消其默认操作. 在目标元素的drop事

HTML5 鼠标拖拽以及web存储

html5 拖拽: (function(){}())执行匿名函数,要用括号包括起来: 1:用鼠标事件来做拖拽: 2:在HTML5中加入draggable="true",就可以拖拽但是是分成了两个,这个更有效率: ondragstart:拖拽开始: ondrag:拖拽中 ondragend:拖拽结束: ondragenter:进入投放去: ondragover:投放区移动: ondragleave:离开投放区: ondrop:投放区投放:           ondragover会阻止d

html5之拖拽(1)

1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title>图像拖动</title> 6 7 8 <style> 9 body { 10 margin: 0px;; 11 } 12 13 .container { 14 background-color: lightcyan; 15 w

[开源应用]利用HTML5+resumableJs拖拽上传大文件

前言: 大文件传输一直是技术上的一大难点.文件过大时,一些性提交所有的内容进内存是不现实的.大文件带来问题还有是否支持断点传输和多文件同时传输. 本文以resumableJs为例,介绍了如何在ASP.NET中实现大文件传输.同时本文利用了Html5的新特性:支持拖拽. 本文的主要技术点在于:如何接收resumableJs的传送内容(官网不太清楚)和如何合并文件,难度并不高. 注:原博客中,此文章为原站点个人代码备份所用,注释不多,如有不懂,请在评论中给出. 效果: ASPX File: <htm

Nodejs express、html5实现拖拽上传(转载)

一.前言 文件上传是一 个比较常见的功能,传统的选择方式的上传比较麻烦,需要先点击上传按钮,然后再找到文件的路径,然后上传.给用户体验带来很大问题.html5开始支持拖 拽上传的需要的api.nodejs也是一个最近越来越流行的技术,这也是自己第一次接触nodejs,在nodejs开发中,最常用的开发框架之一是 expess,它是一个类似mvc模式的框架.结合html5.nodejs express实现了拖拽上传的功能. 二.基础知识普及 1.NodeJs基础知识 nodejs简单来说就是一个可

html5 - drag 拖拽

参考资料: 张鑫旭             : http://www.zhangxinxu.com/wordpress/2011/02/html5-drag-drop-%E6%8B%96%E6%8B%BD%E4%B8%8E%E6%8B%96%E6%94%BE%E7%AE%80%E4%BB%8B/    ^_^肥仔John  :  http://www.cnblogs.com/fsjohnhuang/p/3961066.html   File API          : http://www.i