IE11 Неправильно реагирует на Прослушиватель событий изменений (Всегда кэширующий компонент DOM)

#javascript #closures #dom-events #internet-explorer-11

Вопрос:

Итак, у меня есть страница, на которой в HTML есть одна кнопка загрузки. При загрузке страницы я вызываю приведенную ниже функцию, чтобы прикрепить прослушиватель событий изменений ко всем кнопкам загрузки:

 // FileUpload JS
export function registerFileUploadEvents() {
  const fileUploadElements = document.querySelectorAll('.file-upload')
  Array.prototype.forEach.call(fileUploadElements, (fileUploadElement) => {
    const fileInput = fileUploadElement.querySelector('input[type="file"]')
    fileInput.addEventListener('change', e => {
      const selectedFile = e.target.files[0]
      if (selectedFile) {
        e.target.closest('.file-upload').querySelector('.file-upload__filename').innerHTML = selectedFile.name // show uploaded file's name inside fileupload component
      }
    })
  })
}

// Main JS
import 'registerFileUploadEvents' from './FileUpload.js'
registerFileUploadEvents()
 

После этого пользователь может добавить новую кнопку загрузки файлов, чтобы загрузить другой файл (не спрашивайте меня, почему они не позволяют пользователю загружать несколько файлов одновременно, это бизнес-решение). И поскольку я хочу прикрепить тот же прослушиватель событий к этой новой кнопке, вот что я сделал:

 // CloneButton JS File
import 'registerFileUploadEvents' from './FileUpload.js'
// ... after adding cloned fileupload button
registerFileUploadEvents()
 

Так что это отлично работает во всех других браузерах, имя загруженного файла отображается в каждом новом компоненте, например:

———Компонент загрузки файлов 1——— xxx.jpg

———Компонент загрузки файлов 2——— xyz.png

Проблема в IE11, который делает что-то вроде этого:

———Компонент загрузки файлов 1——— xyz.png

———Компонент загрузки файлов 2——— (пусто)

Т. е. когда я нажимаю кнопку «Загрузить» во втором компоненте и загружаю файл xyz. png, вместо того, чтобы поместить имя файла xyz.png во второй компонент, он заменяет имя файла первого компонента.

It seemed to me that this is a case of the fileInput variable being cached, so I used closure to try and retain the scope:

 export function registerFileUploadEvents() {
  const fileUploadElements = document.querySelectorAll('.file-upload')
  Array.prototype.forEach.call(fileUploadElements, (fileUploadElement) => {
    const fileInput = fileUploadElement.querySelector('input[type="file"]')
    fileInput.addEventListener('change', seriouslyMan(fileInput))
  })
}

function seriouslyMan(fileInput) {
  console.log(fileInput.getAttribute('id')) // For normal browsers and IE, logs respective IDs of 1st and second component

  return function() {
    console.log('fileinput should be scoped correctly', fileInput) // For normal browsers, when clicked 2nd component, 2nd component's DOM element is logged but for IE, the first component's DOM element is still logged
  }
}
 

Таким образом, эта возвращаемая функция должна сохранять ввод файла с правильной областью, но я понятия не имею, почему этого не происходит в IE.

Я также попытался зациклить ввод[тип=»файл»] напрямую, чтобы добавить прослушиватели событий, но произошло то же самое.

Затем я попытался создать новую функцию для подключения прослушивателя событий изменений напрямую и только к недавно клонированной кнопке загрузки:

 newFileUploadElement.querySelector('input[type="file"]').addEventListener('change', (e) => {
      const selectedFile = e.target.files[0]
      if (selectedFile) {
        e.target.closest('.file-upload').querySelector('.file-upload__filename').innerHTML = selectedFile.name
      }
    })
 

Еще раз, это отлично работает во всех браузерах, кроме IE, который снова помещает второе имя файла в первый компонент.

Затем я попытался не добавлять прослушиватель событий во второй компонент, и снова при нажатии на 2-й компонент он запускает событие изменения. Заполнение первого компонента, конечно. Т. е. только, конечно.

К настоящему времени я полностью запутался и больше не знаю, как это отладить. Я упустил что-то очевидное? Любые предложения о том, как это отладить, будут высоко оценены.

Заранее спасибо за любую помощь.

Комментарии:

1. Насколько я знаю, IE не поддерживает функции со стрелками, вы можете это проверить. Могут возникнуть и другие проблемы. Если вы можете предоставить минимальный пример фрагмента кода, который может воспроизвести проблему, это поможет решить проблему.