Не разбираясь во всех ваших хитросплетениях, давайте просто отдебажим ваш код:
const modal = new Modal(document.querySelector('.modal'));
Это то, что выполнится первым. В конструктор передается результат поиска элемента. Если элемент не найден, то querySelector выдаст null. Очевидно. Здесь нет проверок на null, но будем надеяться, что в теле конструктора они точно есть. Ну или хотя бы есть полная уверенность, что элемент с таким классом обязательно есть на странице.
И здесь происходит ошибка. Странно, проверки на null нигде нет. И судя по тексту ошибки, вы пытаетесь вызвать метод querySelector переменной modalElement, которая имеет значение null. Следовательно, в самом начале элемента с классом modal не было на странице.
Вызывается конструктор, в котором есть проверка на null и кусок внутри if просто не работает.
Кроме этого вешается обработчик this.create на первую картинку. Всё.
При нажатии на картинку:
Вызывается обработчик this.create
Создаются всякие красивости.
Создается кнопка. При этом на кнопку не вешается никакой обработчик. Она как бы пустая.
Больше ничего не происходит.
Собственно, точек входа в this.delete нет.
Если не секрет, то зачем вы вообще используете ООП? Оно обычно помогает справиться со сложностиями, разбить комплексную задачу на подзадачи. Но вам оно мешает. Ведь нужно понимать, в какой последовательности выполняется ассинхронный код. Что, когда, где, зачем и кого вызывает и т.д.
Иначе объясните, что по смыслу обозначает класс Modal? Чем является объект modal число логически, русским языком, то есть что это такое?
Как по мне, в императивном стиле с нормальными названиями переменных и функций было бы куда проще.
dollar, В данном случае, пример - в целях самообразования. Класс Modal - для создания и закрытия всплывающего окна с изображением. Вариант без ООП есть, поэтому пытаюсь сделать с использованием ООП.
Иван Симонов, не для чего, а что это такое? Вы же создаете класс объектов. А потом вы создаете экземпляр этого класса, то есть сам объект. Вот что это за объект? Что он из себя представляет? Я пойму, если вы скажете, что это "решалка проблемы создания и закрытия окон", но это такое себе определение, ни разу не красивое и не свойственное ООП, хотя формально будет подходить по смыслу.
В ООП объект - это обычно именно объект: окно, кнопка, вид, даже время или мысль можно представить в виде объекта. Но всегда должно быть понятно, что это. Иначе это не ООП, а изврат какой-то. Без обид.
В фанке create сохраняйте элемент модалки в переменную (желательно приватную, например _modal), в close() обращайтесь к этой переменной и либо делайте display = 'none', либо удаляйте сам элемент.