Добрый день! Меня зовут Черепанов Борис, я занимаюсь разработкой сайтов на wordpress и bitrix. Я тут над проектом работал. Одно из ограничений было не использовать jquery, а мне нужно было вызвать одно и тоже модальное окно с разных кнопок. Собственно, это довольно простая задача, но я решил пойти дальше и сделать модальное окно, которое бы создавалось при первом клике, сохраняло своё состояние, имело конструктор для вызова и т.д. И в итоге я не пожалел. Объясню почему позже. Я «обернул» это модальное окно в готовое решение, которое можно использовать постоянно.

Установка


Установить такую «модалку» просто. Скачиваете js-файл и подключаете. Он не зависит от каких-то событий или библиотек, так что можете подключать где вам нужно. Вот ссылка на github

Инициализация


На той странице на которой вам нужно вызвать вы пишите в js:

new XMC({
    bodyID: 'body',
    backgroundLayerID: 'wrapper',
    selector: 'data-type',
    selectorValue: 'openModalForm',
    btnId: 'mfClose',
    content: 'Привет',
    classListBg: ['zuzu', 'zaza'],
    classListBody: ['zuzu', 'zaza2'],
    classListBtn: ['zuzu', 'zaza3'],
    styleBg: {
        top: '0',
        left:'0',
        right: '0',
        bottom: '0',
        position: 'fixed',
        background: '#00000090',
        justifyContent: 'center',
        alignItems: 'center',
        zIndex: '6'
    },
    styleBody: {
        minWidth: '200px',
        minHeight: '200px',
        background: '#ffffff',
        justifyContent: 'center',
        alignItems: 'center',
    },
    btnStyle: {
        width: '40px',
        height: "40px",
        background: '#ffffff',
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        position: 'absolute',
        top: '5%',
        right: '5%',
        cursor: 'pointer'
    }
});

Подробнее о пунктах в объекте


Есть 6 обязательных пунктов:

  • bodyID – это идентификатор блока в котором будет содержаться контент модального окна
  • backgroundLayerID – id затемняющего слоя
  • selector – html атрибут который будет у всех кнопок которые будут вызывать модальное окно
  • selectorValue – значение селектора
  • bntID – id кнопки закрытия модального окна
  • content – текст или html внутри модального окна

Необязательные, но очень важные пункты:

  • classListBg, classListBody, classListBtn – массивы классов для затемняющего слоя, основного окна и кнопки закрыть соответственно
  • styleBg, styleBody, btnStyle – объекты со стилями затемняющего слоя, основного окна и кнопки закрыть соответственно

Немного о самом модальном окне


Я уже говорил, что основная задача, которую решает это модальное окно — это вызов с нескольких кнопок. Клик по нескольким кнопка для вызова js это типичный пример делегирования и в XMC (так я назвал своё модальное окно) оно реализовано так:

XMC.prototype.delegateClick = function () {
    var mf = this;
    window.addEventListener('click', function () {
// Проверяю есть ли у элемента, на который я нажимаю соответствующий атрибут и его значение
if(event.target.hasAttribute(mf.selector) && event.target.getAttribute(mf.selector) === mf.selectorValue ){
               mf.show(); // Показываю модальное окно
               mf.delegateClose(); // Вешаю обработчик на закрытие
           }
    }, mf, false);
};

Соответственно и в конструкторе нужно прописать:

var XMC = function (object) {
/* Прочий код */

this.delegateClick();

}

Кстати, в своё время, мне помогла с этим разобраться статья с learn javascript. Ознакомиться с ней будет полезным.

AJAX для формы


В моём «кейсе» необходимо было загружать форму по ajax (эта задача появилась в процессе). Благодаря моему изначальному подходу мне удалось сэкономить не мало времени. Я расширил через прототип.

XMC.prototype.ajax = function () {
    var mf = this;
    var data = new Object();
// Немного вырезал, не хочу показывать данные, которые я отправлял
    data = JSON.stringify(data);
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function () {
        if(this.readyState == 4 && this.status == 200){
            mf.body.innerHTML = this.responseText;
            mf.sendClickDelegate(mf.form);
            mf.i18n();
        }
    };
    xhttp.open('POST', localizationPreloader.adminUrl + "?action=my_action", true);
    xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhttp.send("data="+data);
    return this;
}

Такой код запроса у меня был для CMS Wordpress.

Итог


В итоге благодаря объектному подходу у меня получилось сделать не просто всплывающие окно, а почти web-приложение в котором у меня 2 ajax для получения формы и отправки, перевод в зависимости от браузера, чтение cookie, анимация загрузки. Благодаря этому же мне не пришлось искать новые элементы по различным селекторам для перевода или работы с данными формы, которая «прилетела» по ajax.

Надеюсь, что для вас будет полезна моя статья. Удачи!

Комментарии (57)


  1. sazareks
    19.11.2018 18:13

    Еще бы рабочую дэмку!


    1. xakplant Автор
      20.11.2018 10:11

      1. andreymal
        20.11.2018 11:13

        При клике по кнопкам пишет в js-консоль ошибку ReferenceError: event is not defined и ничего не происходит. Даже на кроссбраузерность не проверяли?


        1. xakplant Автор
          20.11.2018 13:16

          Да, действительно, моя ошибка у себя на продакшн версии исправил, а на гитхаб нет.
          Я исправил в примере и на codepen'е


  1. dopusteam
    19.11.2018 18:38
    +1

    Использовать такую поделку в проде крайне не рекомендую.
    Неужели нельзя найти готовое решение на js?


    1. vlreshet
      19.11.2018 18:45
      +1

      Всегда когда вижу пост который начинается с фразы вроде «я занимаюсь разработкой сайтов на wordpress и bitrix» ожидаю увидеть привет из 2010-го, и что-то вроде кривой библиотеки на PHP, очумительной вёрстки таблицами, или вот такой вот поделки. И ещё ни разу чутьё меня не подводило!

      P.S Интересный факт — «из коробки» закрыть модалку крестиком невозможно. Крестик есть, а толку нет. codepen.io/anon/pen/GwORRE


    1. ThunderCat
      19.11.2018 18:49
      +1

      Конечно можно, bootstrap modal, magnific popup, fancybox, это самые очевидные решения которые уже обкатаны и хорошо задокументированы.


      1. Grox
        20.11.2018 02:15

        Одно из ограничений было не использовать jquery
        Ну вы предлагаете то, что уже сразу нарушает условие задачи.


        1. mayorovp
          20.11.2018 13:26

          Осталось понять чем это ограничение обосновано.


        1. ThunderCat
          20.11.2018 15:35

          Одно из ограничений было не использовать jquery
          Ну вы предлагаете то, что уже сразу нарушает условие задачи.

          Уже на этапе постановки задачи можно определить что нужно в проекте и что не нужно, так что если это «без жквери по тому что, ну, мы же крутые!», то как архитектору и программисту вам грош цена. Если есть необходимость в каком-то функционале, который уже 40 раз реализован и обкатан, его не пилят на коленке «по тому что могут», а берут готовый. С ходу слабо могу представить чем не угодила библиотека весом 70 кб. Бутстрап тоже нельзя? А то там тоже жквери нужен… С таким проектом я бы вообще постеснялся не то что бы на Хабр, на прикабу публиковаться…


          1. Grox
            20.11.2018 16:28

            Мы не знаем, по каким причинам у автора это ограничение. Но есть много поводов не тащить в зависимости Jquery или другие крупные либы ради одной мелкой задачи.


          1. andreymal
            20.11.2018 17:06

            Бутстрап тоже нельзя?

            Да, он ужасен по всем параметрам — от проблем с изоляцией (см. БЭМ, например) до проблем с гибкостью и протеканием стилей из CSS-файлов в вёрстку.


            библиотека весом 70 кб

            Многовато для библиотеки, которая (в вашем примере) сама по себе ничего не делает и является лишь основой для других библиотек.


            jQuery есть смысл тащить, когда есть очень качественное готовое решение, построенное на базе jQuery, и взять его намного проще, чем взять что-то другое, но вот лично в моей практике обычно оказывалось вполне возможно или взять другое готовое решение на базе ванильного JS (тоже вполне качественное), или вообще написать всё своё конкретно под свою задачу за час-другой. За последние шесть лет мне ни разу не понадобились ни jQuery, ни бутстрап (не считая поддержки сайтов, сделанных не мной).


            1. mayorovp
              20.11.2018 17:15

              Бутстрап нужен когда в команде нет ни одного веб-дизайнера.


              1. andreymal
                20.11.2018 17:17

                Дизайн бутстрапа мне как простому пользователю тоже категорически не нравится, тошнит от него


            1. ThunderCat
              21.11.2018 00:09

              Многовато для библиотеки, которая (в вашем примере) сама по себе ничего не делает и является лишь основой для других библиотек.
              Спорно, учитывая как раз то что на ее основе написано более 70% популярных инструментов. Собственно ее задача — качественный сахар с удобным набором функций и коротким читаемым синтаксисом.
              лично в моей практике обычно оказывалось вполне возможно или взять другое готовое решение на базе ванильного JS (тоже вполне качественное), или вообще написать всё своё конкретно под свою задачу за час-другой.
              Любой более-менее крупный проект включает 5-6 типовых задач, таких как попапы, слайдеры, табы, галереи, загрузчики, редакторы и еще много всякого. На 1 ванильный модуль приходится 3-5 написаных под jq. Причем чаще всего и функционалом и качеством не в пользу ванилы. Прям вот по вышеперечисленным задачам у меня уже есть набор готовых хорошо зарекомендовавших себя библиотек, из них на ваниле только ckeditor. Не вижу причины отказываться от готовых отлаженных решений ради такого вот костылестроения, как представленный в топике код. Да, он короткий, без жквери и без особых претензий, но до магнифика ему еще весьма далеко, а пилить самому такой функционал имхо расточительно, разве что если времени дофига, а заняться нечем.


              1. andreymal
                21.11.2018 00:19
                +1

                качественный сахар с удобным набором функций и коротким читаемым синтаксисом

                Как хорошо, что всё перечисленное давно есть в ES6 и всех современных браузерах


                попапы

                Пара строчек на classList.toggle


                слайдеры

                Навалом ванильных. Да и свой простенький тоже можно написать за 10-20 минут


                табы

                Реализуются без единой строчки на js


                галереи

                Слишком общее слово


                загрузчики

                <input type="file">? Ладно, шучу, dropzone покрывает большинство потребностей и не требует никакого jQuery. Хотя я писал свой собственный загрузчик без каких-либо проблем (если я правильно понял о чём речь)


                редакторы

                Опять же, навалом ванильных. А также на реакте, на Vue и прочих модных нынче вещах


                На 1 ванильный модуль приходится 3-5 написаных под jq

                Которые не нужны, потому что можно взять этот самый 1 ванильный модуль. Или даже самому написать, зачастую это нетрудно


                Причем чаще всего и функционалом и качеством не в пользу ванилы.

                Вы где-то проспали последние лет пять


                ckeditor

                Ну точно проспали


                Не вижу причины отказываться от готовых отлаженных решений ради такого вот костылестроения

                Отказываться от прогресса — ваш выбор, окей


                представленный в топике код

                Он ужасен, я с этим не спорю


                магнифика

                Очередной слайдер сомнительной нужности, причём разработка заброшена


                1. dopusteam
                  21.11.2018 12:22

                  Как хорошо, что всё перечисленное давно есть в ES6 и всех современных браузерах

                  Не всегда современных браузеров достаточно. (Только не говорите, что идите лесом пользователи IE)

                  Пара строчек на classList.toggle

                  Продемонстрируйте, пожалуйста, очень интересно посмотреть как Вы парой строчек это сделайте

                  Навалом ванильных. Да и свой простенький тоже можно написать за 10-20 минут

                  А если не простенький, а так чтоб работал хорошо? Что входит в понятие 'простенький'?

                  Реализуются без единой строчки на js

                  Думаю, с поддержкой браузерами проблемы будут, покажите пример тогда уж

                  Опять же, навалом ванильных.

                  Покажите ванильные редакторы? Сколько они весят?

                  Которые не нужны, потому что можно взять этот самый 1 ванильный модуль. Или даже самому написать, зачастую это нетрудно

                  Выбор — это всегда хорошо. А написать всё что угодно можно, но нужно ли? Вы хотите заниматься бизнес логикой или переписывать в сотый раз слайдеры и попапы?

                  Отказываться от прогресса — ваш выбор, окей

                  Интересное мнение, что костыли и велосипеды — это прогресс

                  Он ужасен, я с этим не спорю

                  Как и в любом решении, которое 'несложно самому написать' или 'можно написать за 10-20 минут'. Ну ладно, практически в любом, если не тратить время на поддержку и допилы
                  Если всё писать самому и с нуля на ваниле, то рано или поздно Вы напишите подобие jq только с худшей поддержкой, без тестов, без комьюнити.


                  1. andreymal
                    21.11.2018 12:30

                    (Только не говорите, что идите лесом пользователи IE)

                    Нормально жить можно уже начиная с IE9


                    Продемонстрируйте, пожалуйста, очень интересно посмотреть как Вы парой строчек это сделайте

                    Что конкретно? Огласите полное ТЗ, пожалуйста


                    А если не простенький, а так чтоб работал хорошо?

                    Что такое «чтоб работал хорошо»? Самый-самый простой слайдер сводится и переключению классов prev/next/current у слайдов в пару десятков строчек, и это работает вполне хорошо там, где такое решение уместно.


                    Думаю, с поддержкой браузерами проблемы будут

                    IE9+. В интернете примеров много, гуглите css tabs


                    Покажите ванильные редакторы? Сколько они весят?

                    Лучше вы расскажите, чем вам это всё не угодило, потому что в моей практике пока не попадалось задач, где был бы позарез нужен редактор, и я в этой теме не особо компетентен


                    Вы хотите заниматься бизнес логикой или переписывать в сотый раз слайдеры и попапы?

                    Во-первых, одно другому не мешает, во-вторых, это всё пишется один раз


                    Интересное мнение, что костыли и велосипеды — это прогресс

                    Интересное мнение, что использование протухших библиотек пяти- и десятилетней давности (в том числе jQuery) это прогресс


                    Как и в любом решении, которое 'несложно самому написать' или 'можно написать за 10-20 минут'. Ну ладно, практически в любом, если не тратить время на поддержку и допилы

                    Демагогия какая-то


                    1. dopusteam
                      21.11.2018 12:40

                      качественный сахар с удобным набором функций и коротким читаемым синтаксисом

                      Нормально жить можно уже начиная с IE9

                      То есть начиная с IE9 ничего нового нет?

                      Что конкретно? Огласите полное ТЗ, пожалуйста

                      Попап, который принимает рандомный контент, центруется корректно, блокирует всё, то под ним, позволяет закрыть его, который можно двигать с анимацией появления\удаления

                      Лучше вы расскажите, чем вам это всё не угодило, потому что в моей практике пока не попадалось задач, где был бы позарез нужен редактор, и я в этой теме не особо компетентен

                      Что именно 'это'? Покажите ванильный сначала редактор, я не знаю таких

                      Во-первых, одно другому не мешает, во-вторых, это всё пишется один раз

                      Мешает. Время отнимает. И пишется не один раз, отнюдь. Допиливать придётся, как всегда бывает. Вам даже в комментах указали уже на неработающую кнопку 'закрыть'. (Да, Вы её поправили, но, блин, это самый базовый функционал). Или Вы хотите сказать, что Вы написали попап уже один раз и его можно использовать? Больше Вы ничего править не будете?

                      Интересное мнение, что использование протухших библиотек пяти- и десятилетней давности (в том числе jQuery) это прогресс

                      Замените jq на angular (vue etc...), суть не меняется. Не стОит самому писАть то, что написано уже тысячу раз. Мой коммент не конкретно о jq

                      Демагогия какая-то

                      Серьёзно? Я не прав?


                      1. andreymal
                        21.11.2018 12:52

                        То есть начиная с IE9 ничего нового нет?

                        Я такого не говорил. В IE9 есть достаточно для нормальной жизни, а для полной радости есть Babel и core-js


                        Попап, который принимает рандомный контент

                        innerHTML


                        центруется корректно

                        flex


                        блокирует всё, то под ним

                        overlay


                        позволяет закрыть его

                        overlay.onclick


                        который можно двигать

                        Нафига его двигать? Но ладно, это тоже должен любой js-программист уметь писать, это даже на learn.javascript.ru описывается


                        с анимацией появления\удаления

                        CSS3 transition и classList.toggle


                        Ваши желания в пару строчек уже не уместятся.


                        Что именно 'это'?

                        А это я вас спрашиваю. Не я же тут про редакторы ною


                        Покажите ванильный сначала редактор

                        В гугле забанили?


                        Мешает. Время отнимает.

                        Жаль вас, если вы такой медленный специалист


                        И пишется не один раз, отнюдь. Допиливать придётся, как всегда бывает.

                        Допиливать ? переписывать с нуля


                        Вам даже в комментах указали уже на неработающую кнопку 'закрыть'.

                        Если внимательно прочитать ники комментаторов, то можно заметить, что это я и указал :)


                        (Да, Вы её поправили, но, блин, это самый базовый функционал).

                        Поправил не я, но опять же — поправилось за минуту.


                        Или Вы хотите сказать, что Вы написали попап уже один раз и его можно использовать? Больше Вы ничего править не будете?

                        Вот когда возникнет задача что-нибудь поправить, тогда и поправится. Но опять же, многие вещи правятся за минуту.


                        Замените jq на angular (vue etc...), суть не меняется.

                        Ничего из упомянутого я в своих сайтах не использую


                        Не стОит самому писАть то, что написано уже тысячу раз.

                        Полностью согласен. Но это не значит, что нужно брать готовое решение только ради того, чтобы взять готовое решение. Иногда проще, гибче и быстрее (!) написать своё. Особенно в перспективе на будущие правки, когда готовое решение может оказаться недостаточно гибким и придётся от него отказываться — замена одного готового решения на другое готовое решение может оказаться даже дольше, чем самостоятельное написание с нуля.


                        Демагогия какая-то

                        Серьёзно? Я не прав?

                        Мне нечего на это ответить, потому что демагогия какая-то


                        1. dopusteam
                          21.11.2018 13:02

                          flex

                          Внезапно flex не работает в IE 9

                          overlay

                          Кода нет, ну ок,

                          Ваши желания в пару строчек уже не уместятся.

                          Я Вам о том же толкую. Сделать самое простое решение можно и самому, но надолго ли его хватит?

                          В гугле забанили?

                          Я даже не знаю, что Вам ответить

                          Жаль вас, если вы такой медленный специалист

                          Ну на личности то зачем

                          Допиливать ? переписывать с нуля

                          Хаха, очень удобно. Можно бесконечно перепиливать, (утрирую) тратить по 8 часов в день, но ПИШЕТСЯ ЖЕ ОДИН РАЗ, я просто переписываю

                          Если внимательно прочитать ники комментаторов, то можно заметить, что это я и указал :)

                          Да, уже заметил, прошу прощения. Но это лишь подтверждает мою правоту

                          Поправил не я, но опять же — поправилось за минуту.

                          Я не знаю, как Вас убедить. Если 'простое решение', которое 'делается' за 5 минут имеет проблемы в базовой функциональности, то может стОит всё же взять готовое решение? Сколько потенциальны ошибок будет при допиле?

                          Ничего из упомянутого я в своих сайтах не использую

                          Советую всё же попробовать. Круто писАть всё с нуля, все так делали, наверное, но нужно тратить время на решение нерешённых задач

                          Иногда проще, гибче и быстрее (!) написать своё.

                          Имхо, лучше форкнуть готовое решение. Свой велосипед в 99% будет худшим решением. Для замены обычно можно сделать свою обёртку над готовым решением и тогда замена не такая болезненная.

                          Нафига его двигать?

                          Я просто зашёл на jquery popup и взял первую базовую демку.
                          Заказчик так хочет и, внезапно, это удобно бывает. Особенно если ресайзить можно ещё.
                          Вы сказали, что сделать это можно парой строчек кода, а когда я накинул требований Вы ничего вдруг не делаете.

                          А это я вас спрашиваю. Не я же тут про редакторы ною

                          Опять же, навалом ванильных.

                          Покажите хоть один уже


                          1. andreymal
                            21.11.2018 13:16
                            -1

                            Внезапно flex не работает в IE 9

                            Зато работает в IE11. Но в самом крайнем случае (а то говорят, что flex в IE11 баганутый) можно сделать хоть для IE5, высчитывая координаты в JS — опять же пара строчек с getBoundingClientRect и тривиальнейшей арифметикой.


                            Я Вам о том же толкую. Сделать самое простое решение можно и самому, но надолго ли его хватит?

                            Ваши желания влезут в пару сотен строчек, и тащить jQuery или готовые библиотеки для них совсем не обязательно (ну разве что для drag&drop можно притащить, там код нетривиальный всё-таки)


                            Хаха, очень удобно. Можно бесконечно перепиливать, (утрирую) тратить по 8 часов в день, но ПИШЕТСЯ ЖЕ ОДИН РАЗ, я просто переписываю

                            Снова демагогия


                            имеет проблемы в базовой функциональности

                            Это автор поста такой 'хороший' специалист. Естественно, если не уметь кодить на js, то, очевидно, лучше всегда брать готовые решения. Но я вот, например, умею кодить на js — мне готовые решения в большинстве случаев просто не нужны. (Для совсем тяжёлых задач вроде того же редактора взять готовое решение пожалуй стоит, но какой-нибудь попап явно не относится к таким сложным задачам)


                            Имхо, лучше форкнуть готовое решение.

                            А потом разбираться в тамошнем говнокоде в три раза дольше, чем писать своё с нуля. Плавали, знаем


                            Вы сказали, что сделать это можно парой строчек кода

                            Я сказал это до появления таких странных требований


                            Я просто зашёл на jquery popup и взял первую базовую демку. Заказчик так хочет и, внезапно, это удобно бывает.

                            А потом у заказчика появится ещё какое-нибудь одно требование, которое не решается найденным готовым решением. И придётся или искать другое, или форкать имеющееся, или писать своё. И что-то я совсем не уверен, что первые два варианта быстрее третьего


                            Я даже не знаю, что Вам ответить

                            Наверно, на этом можно и закончить)


                    1. dopusteam
                      21.11.2018 12:47

                      Прошу прощения, думал, что Вы автор


                    1. ThunderCat
                      21.11.2018 15:44

                      Нормально жить можно уже начиная с IE9
                      Неправда, до 11 включительно полной совместимости нет.
                      Интересное мнение, что использование протухших библиотек пяти- и десятилетней давности (в том числе jQuery) это прогресс
                      JQ — последний пул реквест 7 денй назад, не думаю что дата создания проекта влияет на протухлость продукта. Хабр вот использует JQ «и не жужжит». Тот же дропзон тоже древний, причем изначально тоже был на JQ. И сейчас регистрируется как его модуль, если доступен. В целом в большинстве случаев прогресс ради прогресса нафиг никому не сдался, все упирается в стоимость решения, блидинг эйдж используется на 0,1% задач. Eсли есть что-то рабочее уже сейчас — писать что-то новое на ваниле как минимум не рационально.

                      Магнифик — Очередной слайдер сомнительной нужности, причём разработка заброшена
                      Его большое преимущество — он работает и имеет много гитик, внешний вид вообще зависит только от самого блока попапа, так что вообще не понятно причем тут наружность, код легко правится если чего-то не хватает. Ничего ванильного лежащего рядом пока не встретил. 3 наиболее популярные альтернативы с примерно подходящим функционалом тоже на JQ. Напишите что-то похожее на ваниле — с удовольствием перейду на ваш.


                      1. andreymal
                        21.11.2018 16:03
                        -1

                        Неправда, до 11 включительно полной совместимости нет.

                        Не поленился и проверил код по ссылке — всё отлично добавляется даже вместе с svg-элементом в IE11 в Windows 7. Так что или автор что-то не договаривает, или просто врёт. Вы, следовательно, тоже врёте.


                        Кроме того, у меня есть целых два сайта, которые целиком полагаются на innerHTML, и они тоже отлично работают в IE11.


                        JQ — последний пул реквест 7 денй назад

                        Всего лишь поддержка легаси, даты коммитов сами по себе ничего не значат


                        Хабр вот использует JQ «и не жужжит»

                        Всего лишь поддержка легаси. А вот какой-нибудь GitHub взял и отказался от jQuery, например


                        причем изначально [дропзон] тоже был на JQ.

                        Воот, дропзон очень даже развивается :)


                        прогресс ради прогресса нафиг никому не сдался

                        Примерно поэтому мир говно (не только в программировании, вообще везде)


                        Напишите что-то похожее на ваниле

                        Огласите полный список требований, пожалуйста. Я, посмотрев примеры на сайте, вообще не понял, зачем он нужен


                        1. ThunderCat
                          21.11.2018 17:11

                          пруф на SO, работает НЕ ТАК КАК В ДРУГИХ БРАУЗЕРАХ, то есть совместимости нет, + на момент вопроса было проверено что представленный в первом линке код тоже не работал в ваниле.

                          Примерно поэтому мир говно (не только в программировании, вообще везде)
                          Да не все так мрачно, все же 0,1% использует и двигает все вперед, просто это выбор единиц, ибо не все готовы положить еще 1 день на алтарь прогресса, когда старое работает и выполняет все как надо.

                          Всего лишь поддержка легаси. А вот какой-нибудь GitHub взял и отказался от jQuery, например
                          Это говорит лишь о том что там он не нужен, или как в примере ТС — «давайте сделаем без жквери!» сказали сверху, и причины могут быть абсолютно разные, вплоть до имиджевых. Никто не говорит что нельзя, просто рынок ищет наиболее выгодные решения минимум затрат/максимум выработки.


                          1. andreymal
                            21.11.2018 17:20
                            +1

                            пруф на SO

                            Не увидел в вашем «пруфе» воспроизводимого примера, который я бы мог проверить.


                            Попытавшись запустить те несчастные три строчки из кода вопроса, я получил в IE11 поведение, полностью аналогичное фаерфоксу — контент не изменился (и не должен был измениться).


                            Так что нет, не пруф. Всё работает.


                            Я даже попытался использовать таблицу <table id="mainForm:table_1"> как упомянуто в комментарии к вопросу — и нет, она тоже работает!


                            Это говорит лишь о том что там он не нужен

                            Он не нужен почти везде.


                            рынок ищет наиболее выгодные решения минимум затрат/максимум выработки

                            Как я уже говорил,


                            Примерно поэтому мир говно

                            Рынок со мной обсуждать нет смысла.


  1. ArsenAbakarov
    19.11.2018 18:44

    classList, styleBg…
    Раз уж прям ничего нельзя использовать (а я сомневаюсь..), берешь data атрибут, пихаешь роль popup, делаешь еще data атрибут, связывешь контрол с контентом, в js находишь свои контролы с нужной ролью, подписываешься на нужное событие, в коллбеке находишь контент и рендеришь со свистелками и перделками, все стили в css.


  1. Bartlab
    19.11.2018 19:03
    +1

    возможно, я придираюсь, но:
    — стиль кода оставляет желать лучшего
    — было бы здорово увидеть живое демо
    — es5…



    1. Zenitchik
      20.11.2018 16:34

      es5

      Задачи разные бывают. Бывают большие и толстые клиенты с десятками тысяч сотрудников на старых (ОЧЕНЬ СТАРЫХ) компах под ХР.


  1. BigDflz
    19.11.2018 19:18
    -3

    ну если для таких поделок пишут статью то не грех и без написания похвастаться
    github.com/JonHappy/JonHappy.github.io — описание
    jonhappy.github.io демка


  1. Rulexec
    19.11.2018 21:51

    Зачем нужны обязательные идентификаторы, которые будут присвоены элементам? Если для стилей, то лучше сделать их опциональными. Хорошо, что есть возможность задавать классы. Идентификаторы никогда не стоит использовать. Если очень нужно — генерировать уникальные.


    В конструкторе вы используете оператор in для проверки наличия опций и записываете их в this. А дальше проверяете эти опции на !== null. Что-то мне кажется, что если не подать classListBg, случится исключение в setClasses. in не нужен, вместо x !== null для таких проверок лучше просто проверять x, либо typeof x === 'string', либо Array.isArray(x), в зависимости от того, что ожидаем. Ещё лучше — хранить в опциях дефолтные валидные значения, использование которых ничего не изменит (вроде пустого списка/нуля/etc), чтобы проверки вообще не были нужны.


    Ваш delegateClick создаёт утечку памяти. Вы подписываетесь на клики по всему окну, но никогда не отписываетесь. Каждый раз, когда я буду создавать экземпляр XMC, я буду подписываться на клики и держать указатель на mf/this, который будет держать всё остальное.


    Хотя и никаких методов для того, чтобы удалить все созданные элементы из DOM тоже нет.


    this.body.innerHTML = this.content;

    Никогда не используйте innerHTML. Кроме случаев, когда HTML небольшой, находится прямо перед глазами и в него ничего не вклеивается. Передавайте всё элементами/фрагментами. Если нужно показать текст — document.createTextNode('text'), если нужна более сложная структура — как-нибудь постройте дерево элементов, выберите узлы и используйте textContent.


    А если я хочу анимацию появления окна? А если у меня в проекте уже есть модуль, отвечающий за оверлеинг интерфейса (то, что у вас делает backgroundLayer)?


    Для библиотеки слишком много лишних вещей, которые могут быть мало кому нужны и нет возможностей кастомизировать поведение.


    Помню тоже как-то на хабр про свой велосипедный PHP-шаблонизатор писал. Не расстраивайтесь, продолжайте абстрагировать.


    1. andreymal
      19.11.2018 21:54

      Никогда не используйте innerHTML.

      Почему?


      как-нибудь постройте дерево элементов

      Где-то по хабру ходили слухи, что у innerHTML производительность лучше


      1. Rulexec
        19.11.2018 22:11

        Потому что когда-нибудь получится:


        div.innerHTML = '<span>' + item.getDescription() + '</span>';

        А в description однозначно проникнет:


        <script src='//example.org/evil.js'></script>

        Где-то по хабру ходили слухи, что у innerHTML производительность лучше

        Тоже видел, не могу найти. Если этот HTML показывает не просто статику, а является куском интерфейса, в любом случае придётся селекторами выбирать из него элементы, чтобы навешивать обработчики/управлять отображением. И тогда cloneNode(true) должен быть быстрее, ибо не нужно парсить строку. По крайней мере в 2009 был.


        1. andreymal
          19.11.2018 22:16

          '<span>' + item.getDescription() + '</span>'

          А, ну в таком случае да. Только вот два нюанса: во-первых, innerHTML блокирует запуск скриптов тегов <script> (впрочем, от произвольного html-кода тоже ничего приятного, да), а во-вторых, если стоит задача просто отобразить кусок html-кода, пришедшего с сервера по аяксу, то такого не будет


          в любом случае придётся селекторами выбирать из него элементы, чтобы навешивать обработчики

          delegateClick :) (ну, если взять адекватную реализацию)


          1. andreymal
            19.11.2018 22:29

            Меня терзали смутные сомненья, перепроверил — не, onclick в innerHTML всё-таки не блокируется, слава XSS


            Правда, теперь стало непонятно, зачем блокировать <script> и при этом не блокировать onclick


            1. ZaEzzz
              20.11.2018 07:43

              Вроде script там не блокируется, а просто не исполняется, так как событие для этого уже прошло. По этому onclick и «не блокируется». Есть DOM элемент с onclick. Почему нельзя его выполнить? Зачем браузеру помнить о том, что вставлено через innerHTML итд?


              1. andreymal
                20.11.2018 13:22

                О каком событии речь? Если создать script через createElement, то он исполняется, например, поэтому как-то больше похоже на специальную блокировку


                Зачем браузеру помнить о том, что вставлено через innerHTML итд?

                Теоретически можно было бы вычищать все onclick'и при парсинге innerHTML-кода, и помнить ничего не надо


                1. mayorovp
                  20.11.2018 13:30

                  Затем, что когда-то давно любили делать document.body.innetHTML += '...';. Было бы печально если бы этот код начал повторно выполнять все скрипты на странице.


                  1. andreymal
                    20.11.2018 13:49

                    Это многое объясняет, спасибо


                    Обнаружил интересный факт: IE6-8 всё же исполняют скрипты при наличии атрибута defer


        1. BigDflz
          19.11.2018 22:30
          +1

          Если этот HTML показывает не просто статику, а является куском интерфейса, в любом случае придётся селекторами выбирать из него элементы, чтобы навешивать обработчики/управлять отображением.
          совершенно лишняя операция.
          learn.javascript.ru/event-delegation
          один раз обработчик вешается на родителя и меняйте внутренности родителя как угодно
          клики (к примеру) будут отработаны на нужном элементе


        1. BigDflz
          20.11.2018 22:33

          andreymal
          Rulexec
          сделал простейшую демку для сравнения
          github.com/JonHappy/innerHTML_VS
          innerHTML быстрее


          1. BigDflz
            20.11.2018 23:13

            тут демка
            jonhappy.github.io/inner
            в консоли смотрим время


          1. mayorovp
            21.11.2018 08:57

            Конечно быстрее — когда у вас готовый HTML есть. А вы попробуйте превратить ваш json в html циклом… И обработчики событий на элементы развесить не забудьте!


            1. BigDflz
              21.11.2018 09:00

              Конечно быстрее — когда у вас готовый HTML есть
              Ура!
              А вы попробуйте превратить ваш json в html циклом...
              смысл делать такую глупость? когда можно сделать готовый html на сервере сразу из нужных данных?


              1. mayorovp
                21.11.2018 09:03

                Затем что, сам вопрос "что быстрее — innerHTML или createElement" возникает в тех ситуациях когда, сюрприз, готового HTML нету!


              1. andreymal
                21.11.2018 10:56

                Смысл делать готовый html на сервере, когда можно передать json на клиент и уменьшить нагрузку на сервер? :)


                1. Free_ze
                  21.11.2018 11:48

                  Не заниматься рендерингом промежуточного представления (json), например.


                  1. andreymal
                    21.11.2018 11:49

                    Имеет смысл, только если создание json тормозит так же или сильнее чем создание html, в чём я сомневаюсь


                1. BigDflz
                  21.11.2018 13:55
                  -1

                  для сервера что json, что html — это простые строки и нагрузка на сервер что для формирования json, что для формирования html одинакова.
                  если рассматривать ответы fw то можно увидеть, что в json включают одним из полей и строку html.
                  это объясняется тем, что протокол ajax требует на один запрос — один ответ, поэтому передаются и данные и строка html, json это позволяет.
                  при использовании ws такой необходимости нет — можно одним ответом отправить только строку html, а вторым ответом — набор данных в виде json.
                  а то что fw не брезгуют отправкой html строки достаточно нагуглить серверный рендеринг


      1. BigDflz
        19.11.2018 22:18

        вот небольшое объяснение,
        learn.javascript.ru/memory-removechild-innerhtml
        learn.javascript.ru/multi-insert
        но ни чего про быстродействие.
        суть в том на чем будет потеря, если вы вставляете (допустим в див всю таблицу) вы можете вставить через innerHTML, и произойдет удаление и вставка. dom обработает это все за один раз. но если вы будете вставлять через другие команды вам потребуется ещё и циклы js что соответственно добавит к небольшому времени работы команд поэлементной вставки дополнительное время.
        в итоге суммарное время будет больше.
        вставка таким методом ul.innerHTML = ul.innerHTML + "..." — совершенно не верная.


        1. andreymal
          19.11.2018 22:20

          вставка таким методом ul.innerHTML = ul.innerHTML + "..." — совершенно не верная.

          Ну о таком методе никто здесь речи и не ведёт, это очевидно неправильное использование innerHTML, я не об этом


          1. BigDflz
            19.11.2018 22:35

            про такую вставку — чисто дополнение :)
            а так проверял — innerHTML быстрее. если учесть что с сервера пришла готовая строка HTML — это называется «серверный рендеринг»


      1. BigDflz
        21.11.2018 07:35

        Никогда не используйте innerHTML.

        Почему?

        потому что автор не знает что такое серверный рендеринг :)


    1. xakplant Автор
      20.11.2018 10:15

      Спасибо за ваш комментарий. Я думаю, что внедрю то что вы написали)


  1. Fragster
    20.11.2018 11:00

    Ради интереса набросал модалку на vue + bulma
    codepen.io/anon/pen/YREjXW