admin管理员组

文章数量:1353593

How can you pass/access URL parameters (or simple data) between embedded JQuery Mobile pages?

I.e. I have a single HTML page (index.html) with two "pages" (page-id) in it "article-list" and "article-detail" and I want to pass an ID into the article-list page i.e. index.html#article-list?id=12345 and read it again.

We know the framework doesn't support it natively (.0.1/docs/pages/page-navmodel.html). There used to be a plugin called jqm.page.params but it hasn't had much love over the years and it does not work with JQuery 1.3.. Then there's jQuery Mobile router plugin but that seems confusing and overkill.

Any idea how to workaround this and pass data/arguments between embedded pages?

How can you pass/access URL parameters (or simple data) between embedded JQuery Mobile pages?

I.e. I have a single HTML page (index.html) with two "pages" (page-id) in it "article-list" and "article-detail" and I want to pass an ID into the article-list page i.e. index.html#article-list?id=12345 and read it again.

We know the framework doesn't support it natively (http://jquerymobile./demos/1.0.1/docs/pages/page-navmodel.html). There used to be a plugin called jqm.page.params but it hasn't had much love over the years and it does not work with JQuery 1.3.. Then there's jQuery Mobile router plugin but that seems confusing and overkill.

Any idea how to workaround this and pass data/arguments between embedded pages?

Share Improve this question asked Sep 12, 2013 at 13:56 Daniel IversenDaniel Iversen 4951 gold badge7 silver badges13 bronze badges 0
Add a ment  | 

5 Answers 5

Reset to default 5

Acording to help docs to jqm 1.3.2 (latest release - you have checked docs for older version) there still no way to pass query parameters to an embedded page.
But you can use one of the next three plugins for passing query params to internal pages:

  • A lightweight page params plugin (you have mentioned that is not worked in jqm 1.3)
  • A more fully featured jQuery Mobile router plugin for using with backbone.js or spine.js.
  • A very simple Routerlite plugin

Also you can pass parameters by using:

  • Html attributes
  • URL parameters
  • Local storage (permanent storage)
  • Session storage (date enable only during session)

Original answer about the first two methods can be found here. I modified a little bit examples (example with url params has not worked).

Attributes

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'));
});

Example also is on jsfiddle

Url params

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, ' '));
}

The same example on jsfiddle

Local storage:

Html:

<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);
});

Sources can be found on jsfiddle

Session storage

Just repace in example above localStorage on sessionStorage

There are a number of ways to do this, and it depends on your use case. If you need to be able to deep link to one page with the value, you'll need to use one of the query parameter hacks. However, if you have a highly dynamic app, don't need to be able to deep link to a selection, and just want to pass values from one page to the other, you can go other routes:

Use localStorage. When linking to or changing to the other page, set a localStorage value, and access it in javascript again once the other page is loaded.

Use a client-side binding framework Using something like knockoutjs, you can bind values which are kept synchronized across these same-file-pages because they're all a part of the same View context (the HTML file). A good example of this is when you have a page with a list, bound to an array of items, and when one is selected, the other page is loaded, and that page is all bound within the context of the selectedItem.

I suggest you use the method in @DextOr's answer at How can I get query string values in JavaScript?

The other answers have some other methods too

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, " "));
}

Thanks a lot for all the answers and ideas. As I said, I didn't want to use any larger routing frameworks just to solve this current (and probably temporary) limitation of JQM.

The idea about using plain JS to access url parameters sounds appealing but that doesn't work in certain binations of JQuery Mobile and JQuery (there are stack overflow articles about that too).

The localStorage suggestions (of which there are many) are good but nowhere are there practical simple examples.

Solution/example that hopefully others will find it useful also:

<html>
<head>
     <script src="//ajax.googleapis./ajax/libs/jquery/2.0.3/jquery.min.js"></script>
     <script src="//code.jquery./mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>
     <link rel="stylesheet" href="http://code.jquery./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>

I've recently created a solution for this for jQuery Mobile 1.4+. It's a simple 100-line plug-in. It's under the MIT license and you can find it here on GitHub.

本文标签: