编程语言
首页 > 编程语言> > javascript拖放与部分preventDefault

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可以玩.

您可以在w3cmdc上查看有关拖放的更多信息.

编辑:我设法在Chrome和FF(see here)上实现确切的行为

标签:gmail,drag-and-drop,javascript
来源: https://codeday.me/bug/20191208/2091168.html