Jquery mobile обновляет динамически загруженную страницу

У меня есть страница1, которая является index.html, это автономный веб-сайт включает в себя заголовок и скрипты ect. У меня есть кнопка на этой странице, которая при нажатии будет загружать страницу2 через ajax и вставить page2 в page1. Страница2 - это только div data-role = "page" и html внутри нее, а не автономная страница. Тем не менее, url изменяется на page2.html, а затем, если я "обновляю" страницу, она не загружает полную страницу, потому что page2 не является полной страницей, ее нужно вводить только на страницу1.

Я попробовал установить data-url = "index.html & dashboard" (панель управления является основным идентификатором на стр. 2), и в этом случае URL-адрес выглядит корректно, так как он все еще является index.html & dashboard, так что обновление страницы перезагружает страницу1 даже если вы были на стр. 2. Но теперь jquery выйдет из игры и сидит на экране загрузки навсегда, потому что он не может найти "панель мониторинга", потому что этот контент был добавлен только после нажатия пользователем кнопки.

Как мне обойти это?

Спасибо.

page1 index.html

<!DOCTYPE HTML>
<html>
<head>
<title>title</title>
<script><script type="text/javascript" charset="utf-8" src="cordova-1.7.0.js"></script>
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="js/jquery.mobile.js"></script>
<script type="text/javascript" charset="utf-8" src="js/global.js"></script>
<script type="text/javascript" charset="utf-8" src="js/login.js"></script>

<link rel="stylesheet" type="text/css" href="css/jquery.mobile.css" />
<link rel="stylesheet" type="text/css" href="css/style.css" />

<script type="text/javascript" charset="utf-8" src="cordova-1.7.0.js"></script>
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
<script type="text/javascript" charset="utf-8" src="js/jquery.mobile.js"></script>
<script type="text/javascript" charset="utf-8" src="js/login.js"></script>

<link rel="stylesheet" type="text/css" href="css/jquery.mobile.css" />
<link rel="stylesheet" type="text/css" href="css/style.css" />

</head>
<body>
    <div data-role="page" data-theme="b">

        <div data-role="header" data-theme="b">
            <h1>Login</h1>
        </div>
        <!-- /header -->

        <div data-role="content">
            <div class="row">
                <label for="login_name">Login Name:</label> <input
                    class="ui-input-text" type="text" name="login_name" id="login_name" />
            </div>
            <div class="row">
                <label for="basic">Password:</label> <input class="ui-input-text"
                    type="password" name="password" id="password" />
            </div>
            <div class="row">
                <input type="checkbox" name="remember" id="remember" class="custom"
                    data-mini="true" /> <label for="remember">Remember Me</label>
            </div>
            <div class="row">
                <input type="submit" id="submit" name="submit" value="Submit" />
            </div>
        </div>
        <!-- /content -->

    </div>
    <!-- /page -->
</body>
</html>

page2 dashboard.html

<div id="dashboard" data-role="page" data-theme="b" data-url="index.html&dashboard">

<div data-role="header" data-theme="b">
    <h1 id="page_title">Dashboard</h1>
</div>

login.js

$(function() {


$("#submit").click(function() {

    if ($("#login_name").val() == "") {
        alert("Please enter a login name");
        return false;
    }

    if ($("#password").val() == "") {
        alert("Please enter a password");
        return false;
    }

    $.post(URL + 'login', {
        'APIKEY' : APIKEY,
        'login' : $("#login_name").val(),
        'password' : $("#password").val()
    }, function(data) {
        if (data.error == "") {

            $.mobile.changePage("dashboard.html", { transition : "slide" });
        } else {
            alert(data.error);
        }

    }, "json");

});

});

Ответ 1

Краткий ответ

Короткий ответ заключается в том, что jQuery Mobile ожидает, что вы используете хеш для представления состояния одной страницы:

  • /index.html - Страница 1
  • /index.html#dashboard - панель инструментов.

Вместо этого вы загружаете совершенно новую страницу, когда вы должны просто называть JavaScript для динамического изменения содержимого на первой странице для представления второй страницы.

Если короткий ответ имеет смысл, отлично! Если нет, длинный ответ невероятно детализирован и описывает два способа решения этой проблемы.

Длинный ответ

То, что вы по существу задаете, - это создание веб-сайта с несколькими страницами и доступ к обеим страницам с помощью URI, который идентифицирует ресурс.

Для решения этой проблемы можно использовать два метода.

Шаблоны нескольких страниц:

Для jQuery mobile это выполняется с помощью jQuery Mobile Multi-page Template.

Общая идея заключается в том, что обе ваши страницы находятся в одном документе HTML, например:

<head>

</head>

<!-- This is your FIRST page -->
<div data-role="page" id="one">

    <div data-role="header">
        <h1>Multi-page</h1>
    </div><!-- /header -->

    <div data-role="content" >  
        <h2>One</h2>

        <p>I have an id of "one" on my page container. I'm first in the source order so I'm shown when the page loads.</p>  

        <h3>Show internal pages:</h3>
        <p><a href="#two" data-role="button">Show page "two"</a></p>    
        <p><a href="#popup"data-role="button" data-rel="dialog" data-transition="pop">Show page "popup" (as a dialog)</a></p>
    </div><!-- /content -->

    <div data-role="footer" data-theme="d">
        <h4>Page Footer</h4>
    </div><!-- /footer -->
</div><!-- /page one -->

<!-- This is your SECOND page -->
<!-- Start of second page: #two -->
<div data-role="page" id="two" data-theme="a">

    <div data-role="header">
        <h1>Two</h1>
    </div><!-- /header -->

    <div data-role="content" data-theme="a">    
        <h2>Two</h2>
        <p>I have an id of "two" on my page container. I'm the second page container in this multi-page template.</p>   
        <p>Notice that the theme is different for this page because we've added a few <code>data-theme</code> swatch assigments here to show off how flexible it is. You can add any content or widget to these pages, but we're keeping these simple.</p>  
        <p><a href="#one" data-direction="reverse" data-role="button" data-theme="b">Back to page "one"</a></p> 

    </div><!-- /content -->

    <div data-role="footer">
        <h4>Page Footer</h4>
    </div><!-- /footer -->
</div><!-- /page two -->

</body>

Далее, что, по существу, делает jQuery Mobile, он использует CSS, чтобы скрыть элемент DIV с id = "two" и показывать только div с id = "one". Когда пользователь нажимает на гиперссылку с помощью "href=" # two ", есть прослушиватель, который перехватывает событие hashChange и запускает некоторый код JavaScript, который скрывает DIV с id =" один "и показывает DIV с id =" two ".

Это делает переходы страниц очень гладкими и быстрыми, без необходимости совершать поездку на сервер, чтобы получить разметку HTML.

Динамически посещаемый контент:

Если ваши данные более динамичны, то другой вариант заключается в использовании jQuery Mobile Dynamic Page Injection. Общая предпосылка этого процесса похожа на многостраничные шаблоны в том, что браузер прослушивает событие hashChange, за исключением, кроме изменения страниц, он также делает запрос AJAX на сервер для получения содержимого JSON.

<div id="home" data-role="page">
  <div data-role="header"><h1>Categories</h1></div>
  <div data-role="content">
    <h2>Select a Category Below:</h2>
    <ul data-role="listview" data-inset="true">
        <li><a href="#category-items?category=animals">Animals</a></li>
        <li><a href="#category-items?category=colors">Colors</a></li>
        <li><a href="#category-items?category=vehicles">Vehicles</a></li>
    </ul>
  </div>

</div>

При нажатии на категорию "Животные" id = "home" DIV скрыт. Вместо перезагрузки страницы в этом примере HTML динамически генерируется и заполняется результатами объекта JSON.

Вот код, который обрабатывает отображение правильного содержимого:

// Load the data for a specific category, based on
// the URL passed in. Generate markup for the items in the
// category, inject it into an embedded page, and then make
// that page the current active page.
function showCategory( urlObj, options )
{
    var categoryName = urlObj.hash.replace( /.*category=/, "" ),

        // Get the object that represents the category we
        // are interested in. Note, that at this point we could
        // instead fire off an ajax request to fetch the data, but
        // for the purposes of this sample, it already in memory.
        category = categoryData[ categoryName ],

        // The pages we use to display our content are already in
        // the DOM. The id of the page we are going to write our
        // content into is specified in the hash before the '?'.
        pageSelector = urlObj.hash.replace( /\?.*$/, "" );

    if ( category ) {
        // Get the page we are going to dump our content into.
        var $page = $( pageSelector ),

            // Get the header for the page.
            $header = $page.children( ":jqmData(role=header)" ),

            // Get the content area element for the page.
            $content = $page.children( ":jqmData(role=content)" ),

            // The markup we are going to inject into the content
            // area of the page.
            markup = "<p>" + category.description + "</p><ul data-role='listview' data-inset='true'>",

            // The array of items for this category.
            cItems = category.items,

            // The number of items in the category.
            numItems = cItems.length;

        // Generate a list item for each item in the category
        // and add it to our markup.
        for ( var i = 0; i < numItems; i++ ) {
            markup += "<li>" + cItems[i].name + "</li>";
        }
        markup += "</ul>";

        // Find the h1 element in our header and inject the name of
        // the category into it.
        $header.find( "h1" ).html( category.name );

        // Inject the category items markup into the content element.
        $content.html( markup );

        // Pages are lazily enhanced. We call page() on the page
        // element to make sure it is always enhanced before we
        // attempt to enhance the listview markup we just injected.
        // Subsequent calls to page() are ignored since a page/widget
        // can only be enhanced once.
        $page.page();

        // Enhance the listview we just injected.
        $content.find( ":jqmData(role=listview)" ).listview();

        // We don't want the data-url of the page we just modified
        // to be the url that shows up in the browser location field,
        // so set the dataUrl option to the URL for the category
        // we just loaded.
        options.dataUrl = urlObj.href;

        // Now call changePage() and tell it to switch to
        // the page we just modified.
        $.mobile.changePage( $page, options );
    }
}

Обратите внимание, что при просмотре URL-адреса страницы категории и страницы "Животные" вы можете видеть, что документ HTML один и тот же. Разница заключается в хеш-значении.

http://jquerymobile.com/demos/1.1.0/docs/pages/dynamic-samples/sample-reuse-page.html

http://jquerymobile.com/demos/1.1.0/docs/pages/dynamic-samples/sample-reuse-page.html#category-items?category=animals

Когда страница загружается, значение хэша используется для представления состояния страницы. Поскольку браузер в основном не имеет состояния, хеш - это один трюк, доступный нам, чтобы помочь определить, какое состояние страница должна отображаться пользователю.

Просто сравните вызов метода changePage с URL-адресом, который используется в меню на странице категории:

<li><a href="#category-items?category=animals">Animals</a></li>
<li><a href="#category-items?category=colors">Colors</a></li>
<li><a href="#category-items?category=vehicles">Vehicles</a></li>

Обратите внимание, что единственное, что меняется, когда пользователь нажимает ссылку, - это hashvalue, страница никогда не перезагружается. Но в вашем примере вы загружаете совершенно новую страницу:

// this is a new page, not a hash
$.mobile.changePage("dashboard.html", { transition : "slide" });

Логически говоря, вам нужно переосмыслить свою стратегию, как вы представляете свои страницы. Чтобы максимально использовать jQuery Mobile, подумайте о своей первой HTML-странице как о фрейме для всего вашего CSS, JavaScript и статического контента.

Затем все ресурсы, которые вы запрашиваете, должны быть идентифицированы по URL-адресу с той же страницей, за которой следует hashvalue.

Например, если ваша статическая страница "index.html", ваша панель может быть "index.html # dashboard". Вы также можете включить HTML-панель панели управления в id = "dashboard" DIV и динамически заполнить ее данными с сервера или загрузить HTML и данные через AJAX.

Второй момент заключается в том, что любому, кто напрямую обращается к вашей панели мониторинга, нужно будет посетить "/index.html#dashboard", который загрузит вашу исходную страницу, запустит какой-то JavaScript, который будет проверять хэш, распознает, что он содержит "панель мониторинга", и затем перейдите на страницу панели инструментов, потянув назад динамические данные.

Дополнительную информацию см. в динамической документации страницы jQuery.