【问题标题】:jQuery mobile - close panel on history backjQuery mobile - 关闭历史面板
【发布时间】:2014-09-01 06:41:48
【问题描述】:

我有一个 jQuery 移动面板,它可以从侧面滑入,效果很好。 但是假设您有一个登录页面,该页面重定向到带有面板的主页。现在,如果用户打开面板,然后单击后退按钮,他希望面板关闭。但是浏览器会导航回登录页面。

我尝试在网址中添加一些内容:

window.location.hash = "panelOpen";

但这只会打乱 jQuery 移动历史状态模式。我还尝试监听导航事件,并在面板打开时阻止它:

$(window).on('navigate', function (e, hans) {
     var panels = $('[data-role="panel"].ui-panel-open');
     if (panels&&panels.length>0) {
         e.preventDefault();
         e.stopPropagation();
         $('#' + panels[0].id).panel('close');
           return false;
         }
});

这种工作,除了url改变了,我抓不到改变url的事件。此外,它还扰乱了 jQuery 移动历史模式。

那么人们如何使用 jQuery 移动面板实现这种预期的“类似应用程序”的行为?打开面板 > 历史返回 > 关闭面板。就是这样。

非常感谢!

【问题讨论】:

    标签: javascript jquery html jquery-mobile


    【解决方案1】:

    更新

    与其从 jQuery Mobile 的历史记录中检索当前 URL,不如从 hashchange 事件 event.originalEvent.newURL 中检索它,然后将其传递给 popstate 事件,使其成为带有该 URL 的 replaceState()


    不要听navigate,而是听之前触发的popstate。这里的技巧是操纵浏览器的历史和jQuery Mobile的历史通过replaceState()重新加载相同的页面没有transition

    var newUrl;
    $(window).on("hashchange", function (e) {
        /* retrieve URL */
        newUrl = e.originalEvent.newURL;
    }).on("popstate", function (e) {
        var direction = e.historyState.direction == "back" ? true : false,
            activePanel = $(".ui-panel-open").length > 0 ? true : false,
            url = newUrl,
            title = document.title;
        if (direction && activePanel) {
            $(".ui-panel-open").panel("close");
            $(".ui-header .ui-btn-active").removeClass("ui-btn-active");
            /* reload same page to maintain jQM's history */
            $.mobile.pageContainer.pagecontainer("change", url, {
                allowSamePageTransition: true
            });
            /* replace state to maintain browsers history */
            window.history.replaceState({}, title, url);
            /* prevent navigating into history */
            return false;
        }
    });
    

    这部分旨在保持之前使用的相同转换,因为在重新加载同一页面时将transition 设置为none

    $(document).on("pagebeforechange", function (e, data) {
        if (data.options && data.options.allowSamePageTransition) {
            data.options.transition = "none";
        } else {
            data.options.transition = $.mobile.defaultPageTransition;
        }
    });
    

    Demo - Code

    【讨论】:

    • 嗨奥马尔,我有同样的问题.. 有什么改变让它适用于 JQM 1.4.5?
    • @deblocker 嗨,老实说,自从我接近 jQM 以来,我并没有这么久。你能开始一个新问题吗,也许我可以帮你:)
    【解决方案2】:

    我参加聚会有点晚了,但我最近有同样的要求,我想分享一下我是如何做到的。因此,我将原始问题中的要求扩展到PanelsPopupsPages

    ...预期的“类似应用程序”的行为,历史回溯 > 关闭 什么都开。就是这样。

    .on("panelopen").on("popupafteropen").on("pagecontainershow") 中,我只需使用 HTML5 API (https://developer.mozilla.org/en-US/docs/Web/API/History_API) 将另一个条目添加到窗口历史记录中(我相信没有必要使用 JQM 导航浏览器怪癖那):

    window.history.pushState({}, window.document.title, window.location.href);
    

    之后,我或多或少地使用 Omar 的函数来拦截popstate 事件:

    $(window).on("popstate", function (e) {
      var pageId = $(":mobile-pagecontainer").pagecontainer("getActivePage").prop("id");
      var pageOpen = (pageId != "page-home");
      var panelOpen = $(".ui-panel-open").length > 0;
      var popupOpen = $(".ui-popup-active").length > 0;
    
      if(pageOpen) {
        $.mobile.pageContainer.pagecontainer("change", "#page-home", {reverse: true});
        return false;
      }
      if(panelOpen) {
        $(".ui-panel-open").panel("close");
        return false;
      }
      if(popupOpen) {
        $(".ui-popup-active .ui-popup").popup("close")
        return false;
      }
    });
    

    如您所见,这只是主页的一层,但这可以通过使用 JQM 历史实现轻松扩展以获取上一页:

    var activeId = $.mobile.navigate.history.activeIndex;
    var jqmHistory = $.mobile.navigate.history.stack; // array of pages
    

    并使用pagecontainer 更改为活动条目 - 1。


    最后一点,通过完全禁用内置的 JQM Ajax 导航系统也可以很好地工作:

    /* Completely disable navigation for mobile app */
    $.mobile.ajaxEnabled = false;
    $.mobile.loadingMessage = false;
    $.mobile.pushStateEnabled = false;
    $.mobile.hashListeningEnabled = false;
    $.mobile.changePage.defaults.changeHash = false;
    $.mobile.popup.prototype.options.history = false;
    

    (在浏览器中测试,在真实的 Android 和 iOS 设备上)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-05
      • 2013-02-16
      • 2013-11-09
      • 2012-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多