拖拽功能不兼容主要有4大主要原因:
1是event的path属性引起的bug(ie,firebox,safari) 2是event的dataTransfer.setData属性(ie,firebox) 3是firefox在拖动的时候会打开一个新窗口 (firbox) 4是ie11不支持onclick属性方法 ; ie11 里元素对象的attributes的排序和其他浏览器不同, ie11 中 remove()方法不work (ie)
其中IE11 压根就不支持path属性,firefox和Safari还勉强通过hack的方式获取到path,获取方式如下:
const path = event.path || (event.composedPath && event.composedPath());
console.log(path) //[button#btn, div, body, html, document, Window]
那么要兼容IE11怎么办,如果你使用了path,只有一个办法就是规避使用path,用其他方式代替path,比如通过参数直接传入元素的id 通过document.getElementById处理元素。
IE11, firefox 都有dataTransfer.setData的问题, Safari没有可以不用管。
firefox要求拖拽的元素必须实现dataTransfer.setData方法,也就是代码里必须写 dataTransfer.setData,如果你不需要设置什么值,但是为了兼容firefox又必须设置一个值,就随便设置一个糊弄过去。
IE11 只能获取dataTransfer.getData('Text') ,如果你需要传里数据 ,就只能用'Text'这个键名,如果你的代码里设置了很多传输的变量,可以考虑通过对象的方式 用JSON.stringify串行话这个对象装入dataTransfer.setData('Text' ,对象) ,获取的时候用JSON.parse 转回。 如果你传递的数据含有html标签,对象串行化前还需要对html encode ,JSON.parse之后对html在进行decode即可。
如果你firefox和ie11都想兼容,我们就设置好 dataTransfer.setData('Text',数据) ,就好。
在页面初始化的时候加上以下代码
document.body.ondrop = function (event) {
event.preventDefault();
event.stopPropagation();
};
可以把对象.onclick=function(){} 改为 对象.addEventListener('click', function () {})
如果你的业务代码里包含 获取对象attributes的值的代码,比如 event.target.attributes[n].xxx 在ie11中attributes的属性排序和其他浏览器不同,会引起bug。
解决这个问题 ,我是通过遍历attributes 找到符合我要的代替之前的写死的attributes顺序
针对ie11 remove()不work的情况,可以用代码 parent.removeChild(child) 代替