打开模式窗口时如何在地址上添加锚点?

时间:2019-02-17 10:52:56

标签: javascript html5 user-interface

该网站使用Uikit上的Windows。 调用模态窗口时,如何在地址中添加锚点?

1 个答案:

答案 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-modalonbeforeshow事件。当这些模式被显示或隐藏时,这使我们能够调用代码。请注意,这意味着您可以通过不向其添加模式onbeforehide来将模式保留在该模式之外。

我们通过循环所有具有页面加载属性的模式来做到这一点。

  

注意:这假设您在页面加载后不通过JS添加模态。如果这样做,只需将其更改为一个函数,并在页面加载以及添加新模式时都调用它即可。

data-modal为您提供具有该属性的元素的所有DOM节点-有关更多信息,请参阅相关文档(CSS属性选择器和querySelector的MDN)。然后,我们一个接一个地遍历它们,并将两个事件都添加到它们中。

在每个事件处理程序中,我们都想更改URL的document.querySelectorAll("[data-modal]")部分-这样做。当您打开模式时,我们将其更改为#-这意味着您将属性设置为任何值之前的"#" + modal.getAttribute("data-modal")。对于结束,我们只是将其设置为哈希。

这是我们第一部分所需要的。对于第二部分,我编写了一个函数,该函数检查哈希中的内容,尝试查找具有#属性且具有相同值的模式,如果显示,则显示该模式。这需要在页面加载(单击外部链接)以及URL的哈希部分更改时(单击页面上的链接,编辑URL,然后通过其他地方的代码进行更改,等等)发生。

当然,只有一个问题-模态本身会更改哈希值-我们不希望打开一个模态导致自身被打开,然后又导致其自身被打开,然后...... ...

这就是为什么我们有data-modal布尔值的原因。如果是这样,则意味着我们正在更改模式,并且后续的哈希更改将不用作事件。

否则,我们使用querySelector查找模式,然后使用UIKit将其打开。

让我知道是否存在任何错误/此实现有任何问题。

进一步阅读

与UIKit 2.25一起使用

UIKit仅具有isChangingModalhide事件(而不是show和`beforeshow)-区别在于它们在动画之后触发,而不是在动画之前触发。移植到这里并不是什么大问题。

更大的问题是,它们不适用于本地,仅适用于jQuery。如果您对此感到满意,那么这是我的代码中的一小部分,之前经过修改可以处理这些不同的事件-用此脚本替换该脚本中的类似部分,您应该会做得很好:

beforehide