Gup*_*R4c 40 javascript jquery html5 drag-and-drop
考虑一下这个JSFiddle.它在Firefox(14.0.1)中工作正常,但在Windows(7)和OS X(10.8)上的Chrome(21.0.1180.75),Safari(?)和Opera(12.01?)都失败了.据我所知,问题在于对象上的setData()或者getData()方法dataTransfer.这是JSFiddle的相关代码.
var dragStartHandler = function (e) {
e.originalEvent.dataTransfer.effectAllowed = "move";
e.originalEvent.dataTransfer.setData("text/plain", this.id);
};
var dragEnterHandler = function (e) {
// dataTransferValue is a global variable declared higher up.
// No, I don't want to hear about why global variables are evil,
// that's not my issue.
dataTransferValue = e.originalEvent.dataTransfer.getData("text/plain");
console.log(dataTransferValue);
};
Run Code Online (Sandbox Code Playgroud)
据我所知,这应该可以正常工作,如果你在拖动项目的同时查看控制台,你会看到写出的id,这意味着它正好找到了元素并抓住了它的id属性.问题是,它是不是设置数据还是没有获取数据?
我很欣赏这些建议,因为经过一周的努力,经过三次尝试和200多个版本,我开始放松心情.我所知道的是它曾经在60左右的版本中工作,而且具体的代码根本没有改变......
实际上,6X和124之间的主要区别之一是我将事件绑定从更改这已经被揭穿了.事件绑定方法对此问题没有影响.live()为on().我不认为这是问题所在,但是在谈到DnD时,我已经看到Chrome出现了几次失败.
UPDATE
我已经创建了一个新的JSFiddle,它完全消除了所有内容,只留下了事件绑定和处理程序.我用jQuery 1.7.2和1.8既测试了它on()和live().问题持续存在,因此我删除了一个级别并删除了所有框架并使用了纯JavaScript.这个问题仍然存在,所以基于我的测试,我的代码不是失败的.相反,Chrome,Safari和Opera似乎都在实施setData()或getData()不执行规范,或者由于某种原因而失败.如果我错了,请纠正我.
无论如何,如果你看一下新的JSFiddle,你应该能够复制这个问题,只需在拖动指定接受drop的元素时查看控制台.我已经开始用Chromium开了一张票.最后我可能还在做错事,但我现在根本不知道怎么做DnD.新的JSFiddle就像它可以得到的那样......
Gup*_*R4c 71
好吧,经过多一点挖掘后,我发现问题实际上不是Chrome,Safari和Opera.放弃它的是Firefox支持它,我只是不能说其他浏览器都失败了,因为这是我通常接受的IE.
问题的真正原因是DnD规范本身.根据规范的drag,dragenter,dragleave,dragover和dragend事件拖拽数据存储模式保护模式.您问的保护模式是什么?它是:
对于所有其他活动.可以枚举拖动数据存储表示拖动数据的项目列表中的格式和种类,但数据本身不可用,并且不能添加新数据.
这意味着,"您无法访问您设置的数据,即使在只读模式下也无法访问!请转到f#self." .真?谁想出这个天才?
现在,为了解决这个限制,你几乎没有选择,我只想概括两个我想出来的.您的第一个是使用邪恶的全局变量并污染全局命名空间.您的第二选择是使用HTML5 localStorage API来执行与DnD API应该提供的完全相同的功能!
如果你沿着这条路走下去,你现在正在实现两个HTML5 API,不是因为你想要,而是因为你必须这样做.现在我开始欣赏PPK对HTML5 DnD API所带来的灾难的咆哮.
最重要的是,需要更改规范以允许访问存储的数据,即使它仅处于只读模式.在我的情况下,使用这个JSFiddle,我实际上是使用它dragenter作为一种方法来展望放置区域并验证我应该允许丢弃发生.
在这种情况下,Mozilla显然选择不完全符合规范,这就是为什么我的JSFiddle工作得很好.碰巧这是我完全支持不支持完整规范的一次.
小智 16
"受保护"位有一个原因......拖放可以跨越完全不同的窗口,他们不希望有人能够实现一个"监听器"DIV,它会窃听所有内容.拖过它(也许可以通过AJAX将这些内容发送给Elbonia的某个间谍服务器).只有DROP区域(更明显受用户控制)才能得到完整的独家新闻.
很烦人,但我明白为什么它可能被认为是必要的.
小智 13
var dragStartHandler = function (e) {
e.originalEvent.dataTransfer.effectAllowed = "move";
e.originalEvent.dataTransfer.setData("text/plain", this.id);
};
Run Code Online (Sandbox Code Playgroud)
问题在于"text/plain".setData的MSDN文档中的标准规范只是"文本"(没有/ plain).在我尝试的任何版本中,Chrome都接受/ plain,但IE不接受.
几个星期以来,我一直在努力解决同样的问题,试图弄清楚为什么我的"掉线"事件在他们在CHrome做的时候没有在IE中正常触发.这是因为dataTransfer数据没有正确加载.
我知道你已经回答了这个,但这是一个有用的线程 - 我只是想在这里添加一个附录 - 如果你自己设置数据,你总是可以将数据添加到字段本身(丑陋我知道),但它可以防止重新创建功能:
例如,如果设置自己的自定义数据:
dataTransfer.setData('mycustom/whatever', 'data');
Run Code Online (Sandbox Code Playgroud)
将数据附加为新数据条目,并迭代:
dataTransfer.setData('mycustom/whatever/data/{a json encoded string even}');
Run Code Online (Sandbox Code Playgroud)
查询:
// naive webkit only look at the datatransfer.types
if (dataTransfer.types.indexOf('mycustom/whatever') >= 0) {
var dataTest = 'mycustom/whatever/data/';
// loop through types and create a map
for (var i in types) {
if (types[i].substr(0, dataTest.length) == dataTest) {
// shows:
// {a json encoded string even}
console.log('data:', types[i].substr(dataTest.length));
return; // your custom handler
}
}
}
Run Code Online (Sandbox Code Playgroud)
仅在镀铬中测试过
| 归档时间: |
|
| 查看次数: |
37096 次 |
| 最近记录: |