html5拖拽兼容性,HTML5之拖拽(兼容IE和非IE)

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

今世:

先来段HTML代码吧.

1.jpg

2.jpg

big.png

mvp1.jpg

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

原文:http://www.cnblogs.com/ListenFly/p/4651720.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值