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

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

Пожалуйста, вставьте свой код в свой вопрос! Без кода вам сложно помочь.

FZs 17.02.2019 11:54

Итак, вы хотите поместить ссылку в модальное окно? Или вы хотите, чтобы ссылка открывала модальное окно?

Toastrackenigma 17.02.2019 11:55

@Toastrackenigma, мне нужно поставить ссылку, когда открываются окна.

Григорий 17.02.2019 11:59

@Григорий Извините, я все еще не понимаю - вы (1) хотите поместить ссылку внутри модального окна, (2) хотите иметь ссылку на своей странице, которая открывает модальное окно, или (3) хотите, чтобы ваша страница Изменение URL-адреса при открытии модального окна, чтобы люди могли ссылаться на это модальное окно (Настройки Chrome / стиль window.history)

Toastrackenigma 17.02.2019 12:02

@Toastrackenigma, 3) пункт.

Григорий 17.02.2019 12:06

@Григорий Привет, я написал для тебя решение! Я опубликовал это до того, как закончил по ошибке, но теперь все готово :) Дайте мне знать, если это сработает для вас.

Toastrackenigma 17.02.2019 13:11
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
6
405
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Введение

Итак, насколько я понимаю (я пояснил это с помощью 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-modaltest, что означает, что он изменит 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.

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

Note: This assumes you don't add modals via JS after the page is loaded. If you do, just change this to a function, and call it both on page load AND whenever you add a new modal.

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();
});

Невероятно. Я пытаюсь использовать код. Но пока он не работает. Я думаю, потому что мое модальное окно называется так: может помешать запуску вашего кода?

Григорий 17.02.2019 13:32

Я использовал такую ​​кнопку в своем тесте, и все работало нормально. Ошибки в консоли есть? Вот мой урезанный тестовый HTML-файл; проверьте, работает ли это для вас: pastebin.com/sfK4Z33B

Toastrackenigma 17.02.2019 13:35

Консоль чистая. Всплывающее окно работает, но URL не меняется. В кодовой ручке этот код должен работать? codepen.io/Grione/pen/vbvBoq

Григорий 17.02.2019 13:59

Ах, CodePen не показывает вам URL. Попробуйте это как отдельную веб-страницу (например, файл .html)

Toastrackenigma 17.02.2019 14:01

Думаю проблема в версии Uikit. Joomla Они используют Uikit 2.25.0. Но я не понимаю, почему эта проблема.

Григорий 17.02.2019 14:57

Я не использовал имя модель данных, потому что в консоли была ошибка. Я взял всплывающее окно с данными. Ошибки нет, но адрес не меняется. это мой пример test.endlesstest.ru

Григорий 17.02.2019 15:02

У тебя получилось в итоге? Потому что это работает для меня, когда я посещаю сайт. В противном случае, может быть, есть ошибка, связанная с браузером / ОС? Какую систему вы используете?

Toastrackenigma 17.02.2019 16:33

Нет. (Я экспериментировал с вашим кодом. Посмотрите сейчас. Может быть, версия 2.25 не поддерживает события beforeshow, beforehide?

Григорий 17.02.2019 16:58

Ни одно из этих событий ("beforeshow", "beforehide") в версии 2.25...

Григорий 17.02.2019 18:37

Эй, не знал, что ты используешь 2.25. Я внес правку внизу своего поста, в которой используются события, поддерживаемые являются в этой версии, так что, надеюсь, это решит для вас все проблемы.

Toastrackenigma 17.02.2019 22:17

Это работает! Вы были невероятно полезны. Большое спасибо. Приятно осознавать, что есть люди, которые так искренне готовы помочь.

Григорий 18.02.2019 08:27

Рад, что смог помочь :)

Toastrackenigma 18.02.2019 09:28

Другие вопросы по теме