该网站使用Uikit上的Windows。 调用模态窗口时,如何在地址中添加锚点?
答案 0 :(得分:0)
因此,据我了解(我在问题注释中使用OP对此进行了澄清),我们希望每当用户打开模式/关闭模式时都更改URL,以提供指向该模式的链接。 Google Chrome在其“设置”页面中做了类似的操作,我也可以看到一些其他用例。
我们可以使用window.history
API,因为这是它设计的目的。但是,这可能会给我们带来额外的工作-如果有人输入这些URL之一,则您需要服务器规则来处理它(例如.htaccess之类的东西),而我宁愿让该URL为尽可能多的人使用。
因此,我将使用URL的#
部分。这个想法是,如果用户打开模式,则URL的末尾可能会更改为#modalOne
(例如),而当用户关闭它时,URL的末尾可能会更改为#
。如果用户手动输入#
或单击链接中的一个,则将显示尊重的模式(如果存在这样的模式)。
这将分为两个部分:使模式添加/删除#
URL,并根据URL显示模式。
我希望这对您来说尽可能简单和可扩展-应该容易地将它从用于1个模式的模式扩展到100个,而无需编写任何额外的代码。
最有效的方法是在模式上使用data属性来指定其#
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
的{{1}}属性-表示它将在打开时将URL更改为以test
结尾。
现在,我们需要实际执行此操作。您需要在页面的某处添加以下JS代码:
#test
我将在下面解释其工作原理。
页面加载时,我们需要向具有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
来将模式保留在该模式之外。
我们通过循环所有具有页面加载属性的模式来做到这一点。
注意:这假设您在页面加载后不通过JS添加模态。如果这样做,只需将其更改为一个函数,并在页面加载以及添加新模式时都调用它即可。
data-modal
为您提供具有该属性的元素的所有DOM节点-有关更多信息,请参阅相关文档(CSS属性选择器和querySelector的MDN)。然后,我们一个接一个地遍历它们,并将两个事件都添加到它们中。
在每个事件处理程序中,我们都想更改URL的document.querySelectorAll("[data-modal]")
部分-这样做。当您打开模式时,我们将其更改为#
-这意味着您将属性设置为任何值之前的"#" + modal.getAttribute("data-modal")
。对于结束,我们只是将其设置为哈希。
这是我们第一部分所需要的。对于第二部分,我编写了一个函数,该函数检查哈希中的内容,尝试查找具有#
属性且具有相同值的模式,如果显示,则显示该模式。这需要在页面加载(单击外部链接)以及URL的哈希部分更改时(单击页面上的链接,编辑URL,然后通过其他地方的代码进行更改,等等)发生。
当然,只有一个问题-模态本身会更改哈希值-我们不希望打开一个模态导致自身被打开,然后又导致其自身被打开,然后...... ...
这就是为什么我们有data-modal
布尔值的原因。如果是这样,则意味着我们正在更改模式,并且后续的哈希更改将不用作事件。
否则,我们使用querySelector查找模式,然后使用UIKit将其打开。
让我知道是否存在任何错误/此实现有任何问题。
UIKit仅具有isChangingModal
和hide
事件(而不是show
和`beforeshow)-区别在于它们在动画之后触发,而不是在动画之前触发。移植到这里并不是什么大问题。
更大的问题是,它们不适用于本地,仅适用于jQuery。如果您对此感到满意,那么这是我的代码中的一小部分,之前经过修改可以处理这些不同的事件-用此脚本替换该脚本中的类似部分,您应该会做得很好:
beforehide