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



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Итак, насколько я понимаю (я пояснил это с помощью 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, чтобы открыть его.
Дайте мне знать, если что-то не так / у вас возникли проблемы с этой реализацией.
document.querySelector на МДН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();
});
Невероятно. Я пытаюсь использовать код. Но пока он не работает. Я думаю, потому что мое модальное окно называется так: может помешать запуску вашего кода?
Я использовал такую кнопку в своем тесте, и все работало нормально. Ошибки в консоли есть? Вот мой урезанный тестовый HTML-файл; проверьте, работает ли это для вас: pastebin.com/sfK4Z33B
Консоль чистая. Всплывающее окно работает, но URL не меняется. В кодовой ручке этот код должен работать? codepen.io/Grione/pen/vbvBoq
Ах, CodePen не показывает вам URL. Попробуйте это как отдельную веб-страницу (например, файл .html)
Думаю проблема в версии Uikit. Joomla Они используют Uikit 2.25.0. Но я не понимаю, почему эта проблема.
Я не использовал имя модель данных, потому что в консоли была ошибка. Я взял всплывающее окно с данными. Ошибки нет, но адрес не меняется. это мой пример test.endlesstest.ru
У тебя получилось в итоге? Потому что это работает для меня, когда я посещаю сайт. В противном случае, может быть, есть ошибка, связанная с браузером / ОС? Какую систему вы используете?
Нет. (Я экспериментировал с вашим кодом. Посмотрите сейчас. Может быть, версия 2.25 не поддерживает события beforeshow, beforehide?
Ни одно из этих событий ("beforeshow", "beforehide") в версии 2.25...
Эй, не знал, что ты используешь 2.25. Я внес правку внизу своего поста, в которой используются события, поддерживаемые являются в этой версии, так что, надеюсь, это решит для вас все проблемы.
Это работает! Вы были невероятно полезны. Большое спасибо. Приятно осознавать, что есть люди, которые так искренне готовы помочь.
Рад, что смог помочь :)
Пожалуйста, вставьте свой код в свой вопрос! Без кода вам сложно помочь.