Foundation Reveal Modal和HTML5历史API操作

时间:2014-04-07 10:02:33

标签: zurb-foundation

我正在尝试解决模态问题。我想要做的是允许用户单击浏览器的后退按钮以关闭模态并返回到页面的原始状态,这是:没有模态。出于这个目的,我考虑使用HTML 5历史API。

我开始尝试将一个查询字符串参数附加到URL,例如http://...page.html?show_modal=[yes|no],但我结束了这种方法,因为我无法处理涉及 popstate 事件的所有内容, pageshow 事件等我无法使它工作,它让我不知所措。

然后我尝试了一种更简单的方法,包括附加到URL的哈希,例如http://...page.html#modal hashchange 事件。这种方法对我来说效果更好,我几乎拥有它。

当用户单击按钮以显示模态时,他或她可以单击浏览器的后退按钮,它将关闭模式。此外,之后,用户可以单击浏览器的前进按钮,它将再次显示模态。非常好!用户还可以使用散列直接导航到URL以直接访问页面的这种状态,以及他或她可以为页面的这种状态添加书签。它的工作非常整洁,我对结果非常满意。

问题在于它并不完美。当用户通过单击背景,ESC键或右上角的X来关闭模态时,历史记录开始变得混乱。试一试:点击按钮打开模态,然后单击背景将其关闭(查看地址栏中的URL,首先问题是没有删除哈希),然后单击浏览器后退按钮然后会看到它无法正常工作。您将在历史记录中以重复结束,并且必须单击两次后退按钮才能转到上一页。从UX的角度来看,这是不可取的。有谁知道解决这个问题?

我在此CodePen和本问题末尾提供了我的代码。我建议你在自己的机器上尝试,而不是在Codepen中,所以你可以在URL等中查看哈希值。此外,它在Codepen Full模式下不起作用,我不知道为什么。

谢谢!

我正在使用Foundation 5.2.1

HTML

<div class="row">
  <div class="small-12 columns">
    <h1>Reveal Modal</h1>
    <h2>Manipulation of the browser history for a better UX</h2>
    <a class="button radius" href="#" data-reveal-id="sampleModal" id="button">Show Modal...</a>
  </div>
</div>
<!-- ############# -->
<!--     MODAL     -->
<!-- ############# -->
<div id="sampleModal" class="reveal-modal medium" data-reveal>
  <h2>Hi!</h2>
  <p>You may think you are on a new page now, but you aren't. Try to click your browser <kbd>Back</kbd> button to dismiss this modal and return to the the page you were viewing.</p>
  <a class="close-reveal-modal">&times;</a>
</div>

的JavaScript

function setModalHash(url, present) {
  var a = $('<a>', { href:url } )[0]; // http://tutorialzine.com/2013/07/quick-tip-parse-urls/
  var newHash = "";
  if (present === true) {
     newHash = "#modal";
  }
  // Build the resulting URL
  result = a.protocol + "//" + a.hostname + ":" + a.port + a.pathname + a.search + newHash; 

  return result;
}

$("#button").on('click', function() {
  history.pushState(null, null, setModalHash(document.URL, true));         
});      

$(window).on("hashchange load",function(e) {
  // Handling also the load event allows navigation directly to http://host/path/to/file#modal and bookmarking it
  if (document.location.hash == "#modal") {
    $("#sampleModal").foundation("reveal","open");
  }
  else {
    $("#sampleModal").foundation("reveal","close");  
  }
});

1 个答案:

答案 0 :(得分:0)

我一直在将历史api / History.js与会话存储结合起来以保持模态状态,并根据用户导航打开/关闭。我终于实现了大约90%的目标,但在Safari和iOS Safari中实现历史很差,因此删除了这些浏览器的功能。

使用哈希方法可能遇到的一些问题是,当你使用带有pushstate的#时,它实际上并没有将新对象推入历史状态。它有时似乎将历史推送到堆栈上,您可以使用history.back()来触发popstate,但是如果您要使用hashurl刷新页面并在页面启动时进行某种检查,那么就没有&# 39;似乎是一个新的历史被推入堆栈,因此在向后导航时,用户将离开网站而不是关闭模态。

这是我的所有浏览器的实现,除了它恢复到正常行为的地方是Safari:

http://dtothefp.github.io/hosted_modal_history_sample/ https://github.com/dtothefp/html5history_express_modal_toggle

就像我说的,我将History.js与sessionstorage结合使用,因为令人讨厌,在关闭模态的popstate中删除了历史对象,这正是我需要的时候。在所有非常糟糕的API中。

我没有更改URL,因为此项目没有后端,因此如果我更改没有哈希的URL,则在页面刷新时将找不到页面。另一种实现方式是查询字符串,它将在pushstate中使用时正确更新历史记录,但最终会成为糟糕的UX,因为如果用户关闭模式而不使用向后导航(即点击取消按钮或单击关闭),则删除查询字符串将导致页面刷新。