如何在JQuery Mobile(JQM)嵌入/内部页面之间最轻松地传递URL参数/数据?

3
您如何在嵌入的JQuery Mobile页面之间传递/访问URL参数(或简单数据)?例如,我有一个包含两个“页面”(page-id)的单个HTML页面(index.html),“article-list”和“article-detail”,我想将ID传递到article-list页面,即index.html#article-list?id=12345,并再次读取它。
我们知道该框架不支持原生传递参数(http://jquerymobile.com/demos/1.0.1/docs/pages/page-navmodel.html)。曾经有一个名为jqm.page.params的插件,但多年来一直没有得到很好的支持,并且不适用于JQuery 1.3。然后有jQuery Mobile路由器插件,但似乎过于复杂。
有什么方法可以解决这个问题并在嵌入的页面之间传递数据/参数吗?
5个回答

5
根据帮助文档,对于jqm 1.3.2(最新版本 - 您已经查看了旧版本的文档),仍然没有一种方法可以将查询参数传递给嵌入页面。
但是,您可以使用下面三个插件之一来传递查询参数到内部页面:

您还可以通过以下方式传递参数:

  • HTML属性
  • URL参数
  • 本地存储(永久存储)
  • 会话存储(仅在会话期间启用)

有关前两种方法的原始答案,请单击此处。我稍微修改了一下示例(使用url参数的示例无效)。

属性

HTML:

<div data-role="page" id="article-list">
    <div data-role="content">
        <ul data-role="listview" data-theme="c">
           <li><a data-parm="123" href="#article-detail">123</a></li>
           <li><a data-parm="321" href="#article-detail">321</a></li>
        </ul>
    </div>
</div>
<div data-role="page" id="article-detail">
    <div data-role="content">
        <div id="paramId" data-extParam=""></div>
    </div>
</div>

JS:

$("a").on("click", function (event) {    
   var parm = $(this).attr("data-parm");
   $('#paramId').attr( 'data-extParam',parm);    
});    
$("#article-detail").on("pageshow", function onPageShow(e,data){
     alert($('#paramId').attr( 'data-extParam'));
});

示例也在jsfiddle上。

URL参数

HTML

<div data-role="page" id="home">
    <div data-role="content">
        <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="f">
            <li data-role="list-divider">Home Page</li>
            <li><a href="?cid=1234#page2" rel="external">Page 2</a></li>
        </ul>                
    </div>
</div>
<div data-role="page" id="page2">
    <div data-role="content">
        <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="f">
            <li data-role="list-divider">Page 2</li>
            <li><a href="?cid=4321#home">Home Page</a></li>
        </ul>
    </div>
</div>

Js:

$("#page2").on("pageshow", function onPageShow(e,data){

    alert('Page 2 - CID: ' + getParameterByName('cid'));
});

function getParameterByName(name) {
    var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
    return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}

本地存储:

HTML:

jsfiddle 上有相同的示例

<div data-role="page" id="home">
    <div data-role="content">
        <a href="#page2" data-role="button" id="buttonPage">Page2</a>
    </div>
</div>
<div data-role="page" id="page2">
    <div data-role="content"></div>
</div>

JS:

$("#page2").on("pageshow", function onPageShow(e,data){
    alert(localStorage.getItem("localId"));
});

$('#buttonPage').click(function(e) {
    localStorage.setItem("localId", 111);
});

源代码可以在jsfiddle上找到。

会话存储

只需将上面的示例中的localStorage替换为sessionStorage即可。


URL参数似乎不起作用,但最终我使用了SessionStorage。我认为这是一个“可以”的解决方案,但很遗憾我们必须自然而然地诉诸于此,我也不确定它如何影响移动设备的非常快速的性能。我已经展示了一个使用本地(或者说在我的情况下是Session)存储的示例,在其中数据嵌入链接中(这可能是大多数用例,因为我们正在谈论URL参数)。感谢您提供的所有详细信息。 - Daniel Iversen

2
有许多方法可以实现这一点,具体取决于您的用例。如果您需要能够深度链接到一个带有值的页面,则需要使用其中一种查询参数技巧。但是,如果您有一个高度动态的应用程序,不需要能够深度链接到选择,并且只想将值从一个页面传递到另一个页面,则可以选择其他路线:
使用localStorage。当链接到或更改到另一页时,请设置localStorage值,并在加载其他页面后再次在javascript中访问它。
使用客户端绑定框架。使用类似于knockoutjs的东西,您可以绑定值,这些值在同一文件页面中保持同步,因为它们都是同一个视图上下文(HTML文件)的一部分。一个很好的例子是当您有一个页面与列表绑定到项目数组时,当选中一个项目时,加载另一个页面,并且该页面都在所选项目的上下文中绑定。

谢谢,最终我使用了LocalStorage。 - Daniel Iversen

0

我建议您使用@DextOr在如何在JavaScript中获取查询字符串值?中提供的方法。

其他答案也有一些其他的方法。

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

这是一个很好的想法,但是在某些最近的JQM+JQ版本中它不起作用(例如JQM 1.3.2+ JQ 2.0.3)...真遗憾! - Daniel Iversen

0
非常感谢所有的答案和想法。正如我所说,我不想使用任何更大的路由框架来解决JQM当前(并且可能是暂时的)的限制。
使用纯JS访问URL参数的想法听起来很吸引人,但在某些JQuery Mobile和JQuery的组合中却不起作用(关于这个问题也有一些Stack Overflow文章)。
LocalStorage建议(有很多)都很好,但没有实际的简单示例。 解决方案/示例,希望其他人也会发现它有用:
<html>
<head>
     <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
     <script src="//code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>
     <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.2/jquery.mobile-1.3.2.min.css"/>
</head>
<body>
    <div data-role="page" id="listPage">
        <div data-role="content">   
            <ul id="swipeMe" data-role="listview" data-inset="true" data-filter="false">
                <li data-icon="arrow-r"><a href="#viewDetails" id="1">Page 1</a></li>
                <li data-icon="arrow-r"><a href="#viewDetails" id="2">Page 2</a></li>
                <li data-icon="arrow-r"><a href="#viewDetails" id="3">Page 3</a></li>
            </ul>
        </div><!-- /content -->
    </div><!-- /main page -->

    <div data-role="page" id="viewDetails">
        <div data-role="header">
            <div class="ui-grid-b">
                     <div class="ui-block-a"><a href="#listPage" data-role="button" data-mini="true" data-theme="a">Back</a></div>
            </div>
        </div>
        <div data-role="content">   
            details here..
        </div><!-- /content -->
    </div><!-- /detail page -->

    <script type="text/javascript">

        $("#viewDetails").on("pageshow", function(e, data){
            var selectedId = sessionStorage.getItem("selectedId");
            sessionStorage.removeItem("selectedId"); 
            alert(selectedId);
        });

        $("#listPage").on("pageshow", function(e, data){
            $('#swipeMe').children().each(function(){
                var anchor = $(this).find('a');
                if(anchor){
                    anchor.click(function(){
                        sessionStorage.setItem("selectedId", anchor.attr('id'));
                    });
                }
            });
        });

    </script>

</body>


0

我最近为 jQuery Mobile 1.4+ 创建了一个解决方案。 它是一个简单的 100 行插件。 它在 MIT 许可下发布,您可以在 GitHub 这里 找到它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接