Почему instanceof возвращает false в Chrome, Safari и Edge и true в FireFox?

Я использую CKEditor для загрузки некоторых файлов, перетаскивая их в редактор.

Я вижу это странное поведение в событии падения. При проверке объекта события я могу добраться до свойства files. Отладчик показывает, что это тип FileList. Однако, когда я делаю files instanceof FileList, я получаю false в Chrome, Safari и Edge и true в FireFox (см. эту скрипку).

Что здесь происходит?

Кажется, это должно иметь какое-то отношение к тому, как CKEditor маршрутизирует события, потому что без CKEditor кажется, что это работает. Вот основной файл jsfiddle с перетаскиванием, который я разветвил, чтобы он печатал instanceof FileList.

Сейчас я работаю над этим, делая Object.prototype.toString.call(files) == "[object FileList]". Но это не похоже на хорошее долгосрочное решение.

Изменить: я разместил отчет об ошибке в Chromium как Я чувствую, что это что-то в Chrome, что-то не так


person Matthijs Wessels    schedule 24.04.2017    source источник


Ответы (1)


Ответ на этот вопрос содержится в ответах на отчет об ошибке.

Автор rbyers:

Это касается не только FileList, но и всего DragEvent. При отладке я обнаружил, что CKEditor создает iframe, поэтому типы событий, доставляемые в iframe, имеют объекты-прототипы, отличные от объектов главного окна, в котором работает обработчик событий. Прерывание прослушивателя событий «отбрасывания» (до того, как любой из JS запустится и потенциально испортит событие):

Object.getPrototypeOf(c)===window.DragEvent.prototype
false

Object.getPrototypeOf(c)===document.querySelector('iframe.cke_wysiwyg_frame').contentWindow.DragEvent.prototype
true

См. документацию по instanceof и нескольким контекстам здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof#instanceof_and_multiple_context_(e.g._frames_or_windows)

Однако я действительно вижу, что экземпляр возвращает true для таких случаев в Firefox. Вот очень простое воспроизведение: http://jsbin.com/yefesuv.

Если вы прочитаете больше ответов, окажется, что между спецификацией Web IDL и ES было несоответствие, где FireFox следовал Web IDL, а все остальные браузеры ES. Они обновили спецификацию Web IDL, и есть отчет об ошибке для FireFox. Пройдет некоторое время, прежде чем FireFox изменит свое поведение из-за обратной совместимости.

person Matthijs Wessels    schedule 04.05.2017