React-dnd: 如何在 canDrop 方法中获取有关拖动文件的信息?

创建于 2016-11-22  ·  27评论  ·  资料来源: react-dnd/react-dnd

我想限制允许的文件扩展名,并且需要知道用户正在拖动哪些文件,但控制台会抛出警告: NativeDragSources.js:61 Browser doesn't allow reading "files" until the drop event.那么在将文件拖放到放置目标之前检查文件扩展名或拖动文件计数的最佳方法是什么?

pinned

最有用的评论

是否可以通过event.dataTransfer对象(例如types )公开有关文件的一些信息? 我意识到这可能无法满足所有用例,但它至少会有所帮助。

所有27条评论

您是否正在寻找不允许在源上拖动或基于类型允许在目标上显示?

  1. 不允许拖动,您应该返回falsecanDrag源。
  2. 不允许下降,您应该使用types on targ

@thetechie no,我正在为我当前拖动的文件扩展名来欣赏一种方式。

所有源和目标方法都将monitor担任第二个参数。 (包括canDrop

您可以使用monitor.getItem()以获取当前拖动的项目。

参考:

canDrop(props, monitor): Optional. Use it to specify whether the drop target is able to accept the item. If you want to always allow it, just omit this method. Specifying it is handy if you'd like to disable dropping based on some predicate over props or monitor.getItem(). Note: You may not call monitor.canDrop() inside this method.
您可以使用monitor

它不适用于文件

真奇怪。
我相信您正在将文件从文件系统拖放到目标上?

我做过类似的事情,它似乎对我有用。 如果您可以共享一些代码,我们可能会看到问题所在。

您能否展示一下您如何在 canDrop 方法中读取文件扩展名?

正如我上面已经提到的, monitor.getItem().files里面的canDrop应该给你一个原生File对象的数组

阅读我的第一条评论,当您阅读 canDrop 中的文件时,它会像我提到的那样引发错误。 您是否有在 canDrop 中读取文件的工作示例,或者您只是参考文档? 错误说我无法读取文件,直到放置事件 NativeDragSources.js:61 浏览器不允许读取“文件”,直到放置事件

有可能我们使用了两个不同的版本,这个限制是后来添加的。 我正在使用 2.1.4。

好的,我将测试最新版本并让您知道它是否有效

在尝试按 MIME 类型过滤canDrop中的文件时,我也遇到了这个问题。 一旦我调用monitor.getItem().files ,它就会引发上述警告(Chrome 56.0.2924.87、react-dnd 2.2.4、react-dnd-html5-backend 2.2.4)。

根据MDN ,我的情况至少可以使用event.dataTransfer上的属性来完成,但据我所知,react-dnd 不会将该对象或其信息发布到任何地方。

@theTechie

有可能我们使用了两个不同的版本,这个限制是后来添加的。 我正在使用 2.1.4。

不,我使用相同的版本。 还更新到最新的可能版本(2.2.4)并得到相同的错误:

image

canDrop 方法如下所示:

canDrop: function (props, monitor) {      
        let files = monitor.getItem().files;
        console.log('Files: ', files);
        return true;
    }

它怎么能在你身边工作? 你有工作的例子吗?

我将很快分享一个工作示例。
2017 年 3 月 6 日星期一下午 4:12,Andrey Karavaychik [email protected]
写道:

@theTechie https://github.com/theTechie

有可能我们使用了两个不同的版本,这个限制有
后来添加的。 我正在使用 2.1.4。

不,我使用相同的版本。 也更新到最新的可能版本
(2.2.4)并得到相同的错误:

[图片:图片]
https://cloud.githubusercontent.com/assets/710513/23606619/8acabe7a-0272-11e7-8db1-b1c88870cf92.png

canDrop 方法如下所示:

canDrop:功能(道具,监视器){
让文件 = monitor.getItem().files;
console.log('文件:',文件);
返回真;
}

它怎么能在你身边工作? 你有工作的例子吗?


你收到这个是因为你被提到了。
直接回复此邮件,在 GitHub 上查看
https://github.com/react-dnd/react-dnd/issues/584#issuecomment-284361793
或使线程静音
https://github.com/notifications/unsubscribe-auth/AA_31panjV9Uo11jF63f2Pkx4FBKiV6Aks5ri-MtgaJpZM4K5hkG
.

>

问候,
加根

@andrewQwer - 真的很抱歉!
我对我实施的内容有错误的记忆,它没有在canDrop中使用monitor.getItem().files $ ,我所做的只是通过维护文件计数一次来限制可以删除的文件数量它掉了。

抱歉误导!

PS:我正在研究我们可以实现这一目标的方法,如果我能够做到,我会告诉你。

我认为这永远不可能。 出于安全目的,似乎有意限制阅读有关拖动项目的信息。

http://stackoverflow.com/questions/25016442/how-to-distinguish-if-a-file-or-folder-is-being-dragged-prior-to-it-being-droppe

是否可以通过event.dataTransfer对象(例如types )公开有关文件的一些信息? 我意识到这可能无法满足所有用例,但它至少会有所帮助。

这可能是要添加到 HTML5 后端的东西,但似乎可以在删除文件/文件夹之前确定文件是否适合一组可接受的 mime 类型。 具体来说,当您将项目悬停在 dropzone 上时,react-dropzone 会执行此操作,如本示例所示

这个问题还有解决方案吗?

此问题已自动标记为过时,因为它最近没有活动。 如果没有进一步的活动发生,它将被关闭。 感谢你的贡献。

不陈旧

我也在寻找一种允许删除特定文件的方法,例如:图像、视频,如 react-dropzone。 有没有人有办法解决吗?

此问题已自动标记为过时,因为它最近没有活动。 如果没有进一步的活动发生,它将被关闭。 感谢你的贡献。

我也有这个问题。 它似乎在“NativeDragSource.ts”中被硬编码。

然而,它创建了一个 DragSource 来访问值,它只是添加了一个控制台警告,指出浏览器不允许它。

但是,浏览器确实允许它,它只是处于保护模式,并且不允许更改它或访问文件的 DATA (,但是具有文件属性的项目应该能够被枚举。(就像 DropZone 一样) .

会尝试一些东西然后回到你身边

@LeopoldLerch @darthtrevino在我放弃之前我仍然无法访问files列表。 我想在悬停时检查文件的 mime 类型,并根据它是否是文件的有效格式来更改边框的颜色。 我正在为useDrop钩子使用canDrop方法。 它会在我放下时返回一个文件数组。 当我将鼠标悬停在放置区域上时,我有一个空数组

问题是,浏览器传递的事件是原样的,我们无法更改它们。 浏览器只允许在 dragstart 上访问数据。 之后,所有后续事件都处于保护模式,这意味着您无法访问数据。

如果你使用 useDrop 的 onHover 方法,你会得到空的元数据,因为浏览器不允许你在“dragenter”上访问它。 即使您将对象存储在 dragstart(或 collect-function)中,浏览器也会在后台清除属性,因为您确实有对该对象的引用,而不是它的副本。

解决这个问题的唯一方法是使用“收集”功能。 在这里您可以访问项目的“项目”或“文件”(取决于您使用的浏览器,IE11 将永远不允许您在 ondrop 之前访问它们)。

但是,您必须自己做所有事情:在例如验证和记住它。 一个使用参考。 例如

collect: monitor => {
            const item: DataTransfer = monitor.getItem();
            const isOver = monitor.isOver();
            let _canDrop: VerificationResult = null;
            if (item) {
                if (item.items) {
                    if (item.items.length > 0) {
                        draggedFilesValid.current = allFilesAccepted(
                            fromList<DataTransferItem>(item.items),
                            accept,
                            multiple,
                            maxSize,
                            minSize
                        )
                            ? VerificationResult.Valid
                            : VerificationResult.Invalid;
                    }
                }
            } else {
                draggedFilesValid.current = null;
            }

            if (isOver && item && item.files) {
                _canDrop = VerificationResult.Unknown;
                if (draggedFilesValid.current != null) {
                    _canDrop = disabled
                        ? VerificationResult.Invalid
                        : draggedFilesValid.current;
                }
            }

            return {
                isDragActive: item != null,
                canDrop: _canDrop
            };
        }

@LeopoldLerch
谢谢你的解释! 我会尝试这种解决方法

此页面是否有帮助?
0 / 5 - 0 等级