Как добавить привязку к адресу при открытии модального окна? - PullRequest
0 голосов
/ 17 февраля 2019

Сайт использует windows на Uikit.Как добавить привязку к адресу при вызове модального окна?

1 Ответ

0 голосов
/ 17 февраля 2019

Введение

Итак, из того, что я понимаю (я пояснил это с помощью OP в комментариях к вопросу), мы хотим изменить URL-адрес всякий раз, когда пользователь открывает модальное окно / закрывает модальное, чтобы предоставить ссылку наэтот модальный.Google Chrome делает то же самое на своей странице настроек, и я также вижу несколько других вариантов использования для этого.

Мы могли бы использовать window.history API, так как он предназначен для этого.за.Однако это, вероятно, дает нам дополнительную работу - если кто-то вводит один из этих URL-адресов, вам нужны серверные правила для работы с ним (например, .htaccess), и я бы предпочел, чтобы этот работал для максимально возможного числа людей.

Поэтому я собираюсь использовать часть URL #.Идея состоит в том, что, если пользователь открывает модальное окно, конец URL-адреса может измениться на #modalOne (например) и вернуться к #, когда пользователь закроет его.Если пользователь вручную вводит # или щелкает по ссылке в ссылке, появится соответствующий модал (если такой модал существует).

Это будет сделано в двух частях: добавление модалов /удалите URL-адреса # и отобразите модалы, основанные на URL-адресе.

Код

Я хочу, чтобы это было максимально простым и расширяемым для вас - его легко масштабировать сиспользование его для 1 модального до 100 без написания дополнительного кода.

Метод, который, кажется, работает лучше всего, использует атрибут данных на модале, чтобы указать его # заголовок URL.Атрибут данных - это просто пользовательский атрибут HTML, который вы можете поместить в любой элемент.В нашем случае это будет тот же элемент с атрибутом UIKit uk-modal.Я решил назвать это data-modal, но вы можете называть это как угодно, если вы везде непротиворечивы, мы ссылаемся на него и начинаем имя с data-.

Вот как модальное определение можетпосмотрите:

<div id="modal" uk-modal data-modal="test">
    <div class="uk-modal-dialog uk-modal-body">
        <h2 class="uk-modal-title">Modal</h2>
        Some modal window<br>
        <button class="uk-modal-close" type="button">Close</button>
    </div>
</div>

Этот модал имеет атрибут data-modal, равный test - это означает, что при открытии он изменит URL-адрес на #test.

Теперь,нам нужно на самом деле реализовать это.Вам нужно добавить следующий код JS где-нибудь на вашей странице:

let isChangingModal = false;

window.addEventListener("load", ()=>{
    for (let modal of document.querySelectorAll("[data-modal]")) {
        modal.addEventListener("beforeshow", ()=>{
            isChangingModal = true;
            window.location.hash = "#" + modal.getAttribute("data-modal");
        });
        modal.addEventListener("beforehide", ()=>{
            isChangingModal = true;
            window.location.hash = "#";
        });
    }

    showModalFromURL();
});     

function showModalFromURL() {
    if (isChangingModal) {
        isChangingModal = false;
        return;
    }
    let modal = document.querySelector(`[data-modal="${window.location.hash.slice(1)}"]`);
    if (modal) {
        UIkit.modal(modal).show();
    }
}

window.onhashchange = showModalFromURL;

Ниже я объясню, как это работает.

Как это работает

Когда страница загружается,нам нужно добавить обработчики событий во все модалы с атрибутами data-modal - нам нужно обработать события onbeforeshow и onbeforehide.Это позволяет нам вызывать код, когда эти модалы показаны или скрыты.Обратите внимание, что это означает, что вы можете исключить модальное из этой схемы, просто не добавляя к нему атрибут data-modal.

Мы делаем это путем зацикливания всех модальных атрибутов с атрибутом при загрузке страницы.

Примечание: предполагается, что вы не добавляете модалы через JS после загрузки страницы.Если вы это сделаете, просто измените это на функцию и вызывайте ее как при загрузке страницы, так и всякий раз, когда добавляете новый модал.

document.querySelectorAll("[data-modal]") дает вам все DOM-узлы для элементов, которые имеют этот атрибут -посмотрите дополнительную документацию (селекторы атрибутов CSS и MDN для querySelector).Затем мы последовательно перебираем их и добавляем к ним оба события.

В каждом обработчике событий мы хотим изменить часть URL #, что мы и делаем.Когда вы открываете модальное значение, мы меняем его на "#" + modal.getAttribute("data-modal") - это означает # перед любым значением, которое вы установили для этого атрибута.Для закрытия мы просто устанавливаем его в хэш.

Это все, что нам нужно для первой части.Для второй части я написал функцию, которая проверяет, что находится в хэше, пытается найти модал с атрибутом data-modal с тем же значением, и, если это так, показывает его.Это должно происходить как при загрузке страницы (они щелкали по внешней ссылке), так и всякий раз, когда хэш-часть URL-адреса изменяется (они щелкали ссылку на странице, редактировали URL-адрес, вы изменяли ее с помощью кода в другом месте и т. Д.).

Конечно, была только одна проблема - сами модали изменяют хеш - мы не хотим, чтобы открытие модала вызывало его открытие, которое затем вызывало бы его открытие, которое затем .........

Вот почему у нас есть isChangingModal логическое значение.Если это так, это означает, что мы меняем модальное состояние, и последующее изменение хеш-функции не должно использоваться в качестве события.

В противном случае мы используем querySelector, чтобы найти модальное, а затем UIKit, чтобы открыть его..

Дайте мне знать, если что-то не так / у вас есть какие-либо проблемы с этой реализацией.

Дальнейшее чтение

Использованиес UIKit 2.25

UIKit имеет только события hide и show (вместо beforehide и `beforeshow) - разница в том, что они запускают после анимаций, а не перед ними.Это не должно быть большой проблемой для портирования.

Большая проблема в том, что они не работают изначально, только с jQuery.Если у вас все в порядке, вот небольшая часть моего кода, ранее измененного для работы с этими различными событиями - замените аналогичную часть в этом скрипте на это, и вы должны быть в порядке:

window.addEventListener("load", ()=>{

    for (let modal of document.querySelectorAll("[data-popup]")) {
        $(modal).on({
            "show.uk.modal" : ()=>{
                isChangingModal = true;
                window.location.hash = "#" + modal.getAttribute("data-popup");
            },

            "hide.uk.modal" : ()=>{
                isChangingModal = true;
                window.location.hash = "#";
            }
        });
    }

    showModalFromURL();
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...