jQuery Mobile的后退按钮似乎在页面之间传递缓存数据

时间:2014-01-19 00:40:44

标签: javascript jquery jquery-mobile event-handling

我变得非常渴望一个似乎与jQuery中的事件机制相关的问题,这可能是我无法正确理解的。我希望有人能给我一个提示我做错了什么。

我有一个jQuery Mobile 2页文件:  #info-page:显示类别  #details-page:显示在#info-page

中单击的项目的详细信息

如果用户点击信息页面中的项目,我将点击的项目的数据附加到数据页面“$(”#the_details_page_id“)。data(”name_of_date“,thedata)”。在详细信息页面的“pagebeforeshow”部分,我再次检索了这些数据,并在其基础上创建了新内容。到目前为止,非常好。

但如果我使用“后退”按钮,那一切都会出错:

在我的小例子中,我这样做:

  1. 点击信息页面中的“类别1”
  2. 详细信息页面打开,并通过警告通知“选择了”类别1“
  3. 点击某个项目:提醒信息正确显示“类别1”
  4. 点击“返回”按钮以及信息页面再次出现
  5. 点击信息页面中的“类别2”
  6. 详细信息页面打开,并通过警告通知“选择了”类别2“
  7. 点击一个项目:它显示“类别1”(而不是“类别2”
  8. 我真的很困惑。如果我离开 stopImmediatePropagation 调用,我可以看到最后一步中的警报信息被调用两次 - 一次是“类别1”,然后是“类别2”。有没有人知道我在做什么这么完全错了?

    感谢您的帮助。

    史蒂夫

    <body>
    <script>
    
    var sample = [{
        "id": 2,
        "name": "Category 1",
        "details" : [
                    { "id" : 1, "name": "A Detail"},
                    { "id" : 2, "name": "Other Detail"}
                    ]
        }, {
        "id": 2,
        "name": "Category 2",
        "details" : [ { "id" : 4, "name": "Also a detail"} ]
        }
    ];
    
    // Kategorie-Seite
    $(document).on("pageinit", "#info-page", function () {
          var li = "";
          $.each(sample, function (i, name) {
              li += '<li><a href="#" id="' + i + '" class="info-go">' + name.name + '</a></li>';
          });
    
          $("#kategorie-list").append(li).promise().done(function () {
                $(this).on("click", "a", function (e) {  
                  var category = sample[this.id];
                  $("#details-page").data("selected_category", category);
                  $.mobile.changePage("#details-page");
                  e.stopImmediatePropagation();
                  e.preventDefault();
              });
              $(this).listview("refresh");
          });
       });
    
    // Details-Seite
    $(document).on("pagebeforeshow", "#details-page", function () {
      var category = $(this).data("selected_category");
      alert ("selected category: " + category["name"] ); // correct!!
    
      var details = category["details"];
      var li = ""; // init
      $.each(details, function( index, value ) {    
          li += '<li><a href="#" id="' + details[index]["id"] + '" class="info-go">' + value["name"] + '</a></li>';
      });
    
      $("#tables-list").empty().append(li).promise().done(function () {
          $(this).on("click", ".info-go", function (e) {
              e.stopImmediatePropagation();
              e.preventDefault();
    
            alert ("Category in loop:" + category["name"]);  // wrong!
    
          });
          $(this).listview("refresh");
      });
    });
    
    
    </script>
    <!--first page -->
    <div data-role="page" id="info-page">
        <div data-role="content">
            <ul data-role="listview" id="kategorie-list" data-divider-theme="a" data-inset="true">
                <li data-role="list-divider" data-theme="b" data-role="heading">Kategorien</li>
            </ul>
        </div>
    </div>
    <!--second page -->
    <div data-role="page" id="details-page">
        <div data-role="header" data-theme="b"><a href="#" data-rel="back" data-role="button">Zurück</a>
             <h1>Details</h1>
        </div>
        <div data-role="content">
            <ul data-role="listview" id="tables-list" data-divider-theme="a" data-inset="true">
                <li data-role="list-divider" data-theme="b" data-role="heading">Details</li>
            </ul>
        </div>
    </div>
    
    </body>
    

1 个答案:

答案 0 :(得分:1)

这里的问题是#tables-list元素将附加两个点击处理程序,一个在第一个详细信息页面显示期间,第二个在第二个详细信息页面显示之后。

由于这两个处理程序,您会看到两个警报,第一个处理程序在创建时仍然引用了变量作用域。在您的情况下,第一个处理程序的变量类别包含有关“类别1”的信息。有关可用闭包的更多信息here

最快的解决方法是使用off方法删除旧的事件处理程序。

$(this).off("click").on("click", ".info-go", function (e) {