为什么 instanceof return 在 Chrome、Safari 和 Edge 上为 false 而在 FireFox 上为 true?
Why does instanceof return false on Chrome, Safari and Edge and true on FireFox?
我正在使用 CKEditor 通过将文件拖到编辑器来上传它们。
我在放置事件中看到了这种奇怪的行为。检查事件对象时,我可以到达 files
属性。调试器将其显示为类型 FileList
。但是,当我执行 files instanceof FileList
时,我在 Chrome、Safari 和 Edge 中得到 false
,在 FireFox 中得到 true
(参见 this fiddle)。
这是怎么回事?
这似乎与 CKEditor 路由事件的方式有关,因为没有 CKEditor 它似乎确实有效。这是我分叉的 basic file drag-drop jsfiddle 以便打印 instanceof FileList
.
我现在正在通过 Object.prototype.toString.call(files) == "[object FileList]"
解决这个问题。但这似乎不是一个好的长期解决方案。
编辑:我已经在 Chromium 上发布了 a bug report,因为我觉得这在 Chrome 中是错误的
错误报告的回复包含了这个问题的答案。
来自 rbyers:
This isn't just about the FileList but the entire DragEvent. Debugging this I found that CKEditor is creating an iframe, and so the event types delivered to the iframe have different prototype objects than the main window where the event handler is running. Breaking on the 'drop' event listener (before any of the JS runs and potentially mucks with the event):
Object.getPrototypeOf(c)===window.DragEvent.prototype
false
Object.getPrototypeOf(c)===document.querySelector('iframe.cke_wysiwyg_frame').contentWindow.DragEvent.prototype
true
See the documentation of instanceof and multiple contexts here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof#instanceof_and_multiple_context_(e.g._frames_or_windows)
However, I indeed see that instance of returns true for such cases in Firefox. Here's a really simple reproduction: http://jsbin.com/yefesuv
如果您阅读更多回复,就会发现 Web IDL 和 ES 规范之间存在差异,其中 FireFox 遵循 Web IDL 和所有其他浏览器 ES。 They have updated the Web IDL spec and there is a bug report 适用于 FireFox。由于向后兼容性,FireFox 还需要一段时间才能改变其行为。
我正在使用 CKEditor 通过将文件拖到编辑器来上传它们。
我在放置事件中看到了这种奇怪的行为。检查事件对象时,我可以到达 files
属性。调试器将其显示为类型 FileList
。但是,当我执行 files instanceof FileList
时,我在 Chrome、Safari 和 Edge 中得到 false
,在 FireFox 中得到 true
(参见 this fiddle)。
这是怎么回事?
这似乎与 CKEditor 路由事件的方式有关,因为没有 CKEditor 它似乎确实有效。这是我分叉的 basic file drag-drop jsfiddle 以便打印 instanceof FileList
.
我现在正在通过 Object.prototype.toString.call(files) == "[object FileList]"
解决这个问题。但这似乎不是一个好的长期解决方案。
编辑:我已经在 Chromium 上发布了 a bug report,因为我觉得这在 Chrome 中是错误的
错误报告的回复包含了这个问题的答案。
来自 rbyers:
This isn't just about the FileList but the entire DragEvent. Debugging this I found that CKEditor is creating an iframe, and so the event types delivered to the iframe have different prototype objects than the main window where the event handler is running. Breaking on the 'drop' event listener (before any of the JS runs and potentially mucks with the event):
Object.getPrototypeOf(c)===window.DragEvent.prototype
false
Object.getPrototypeOf(c)===document.querySelector('iframe.cke_wysiwyg_frame').contentWindow.DragEvent.prototype
true
See the documentation of instanceof and multiple contexts here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof#instanceof_and_multiple_context_(e.g._frames_or_windows)
However, I indeed see that instance of returns true for such cases in Firefox. Here's a really simple reproduction: http://jsbin.com/yefesuv
如果您阅读更多回复,就会发现 Web IDL 和 ES 规范之间存在差异,其中 FireFox 遵循 Web IDL 和所有其他浏览器 ES。 They have updated the Web IDL spec and there is a bug report 适用于 FireFox。由于向后兼容性,FireFox 还需要一段时间才能改变其行为。