javascript拖放与部分preventDefault
作者:互联网
Gmail通过以下几种巧妙的方式来处理其拖放式文件附件上传:
1)将文件拖到浏览器中会导致出现dropzone.光标会显示反馈,指示您是否在拖放区中(在Windows中,如果在拖放区之外,则使用红色的交叉圆圈).如果将鼠标放在窗口内但在拖放区之外,则会拦截该拖放,从而阻止浏览器的默认行为(通常导航到显示已拖动的文件).
尝试执行此操作的最明显方法是在BODY上设置拖动处理程序,以使放置区出现并显示preventDefault,但是如何更改光标?有什么方法可以使用dataTransfer.effectAllowed =’none’吗?
2)将文本从窗口的一部分拖动到另一部分不会触发拖放处理(即,不会出现拖放区),并且#1中提到的preventDefault不会生效.
如果我捕获了BODY上的拖动事件(从#1开始),则可以防止窗口内文本拖动.他们如何同时完成这两项工作?似乎这比起初看起来要复杂得多.
更新:
在尝试完全解决这一问题时,我学到了两个相关的知识:
1)如果dropEffect =’none’,看来IE甚至不会触发drop事件处理程序…因此,我决定仅在存在e.dataTransfer.types的情况下才将其设置为none(在Chrome&FF中确实如此),但是不在IE中).不利的一面是光标没有红色的交叉线,但至少我可以拦截该滴以防止导航.确定e.dataTransfer.getData(‘Text’)== null是否是确定是否是IE中的文件删除的最佳猜测. (就我而言,我希望能够接收文件或文本的内容,因此这就是我可以区分IE的方式.)
2)当您离开浏览器时,Gmail如何隐藏拖放区并不清楚.如果您在页面上使用纯Dragleave事件,则即使您并未真正离开页面,拖入任何子级也会触发Dragleave处理程序.然后,我注意到Gmail在放置区域消失之前有一个延迟,因此我猜他们会使用计时器来隐藏放置区域(在拖动时会重置该区域).但我想出了一个替代解决方案,该解决方案到目前为止似乎仍然有效:
function areXYInside(e){
var w=e.target.offsetWidth;
var h=e.target.offsetHeight;
var x=e.offsetX;
var y=e.offsetY;
return !(x<0 || x>=w || y<0 || y>=h);
}
接着:
$("#page").bind('dragleave', function(e){
if(this!=e.target) return false;
if(!areXYInside(e)){
hideBox();
}
return false;
});
解决方法:
我相信他们正在设置dataTransfer.effectAllowedon拖移,具体取决于dataTransfer.types
属性.
编辑:我第一次错了,这是类型的实际值(至少在Chrome中):
-拖动文本[“ text / html”,“ text”,“ text / plain”]
-拖动文件[“文件”]
这是一个简短的jsFiddle example可以玩.
编辑:我设法在Chrome和FF(see here)上实现确切的行为
标签:gmail,drag-and-drop,javascript 来源: https://codeday.me/bug/20191208/2091168.html