jquery mobile listview使用ajax动态加载后,跳转到其他页面返回时数据没有保存如何解决?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jquery mobile listview使用ajax动态加载后,跳转到其他页面返回时数据没有保存如何解决?相关的知识,希望对你有一定的参考价值。

在页面A中使用ajax为listview动态生成数据,点击这些数据进入详细信息页面B,点击B的返回按钮后,A页面已经使用ajax加载的数据全部消失,如何在返回后保留动态生成的数据??

数据量不大,可以存放在localstorage,具体使用方法可以百度,很易用。

每次获取服务器信息后,将json转换为字符串存储到 local storage中,切换回来再次读取,异步去服务器获取最新更新,如有更新则替换,没更新则继续使用本地内容。追问

这个是做分页数据获取的,自动加载的机制,数据略大

追答

1、3M一下可以尝试 localstorage

2、加载后,跳转其他页,可以修改为在本页ajax加载,看哪边更重要呗。

参考技术A $('xxx').listview('refresh')

Jquery Mobile + Phonegap 提升 listview 性能

【中文标题】Jquery Mobile + Phonegap 提升 listview 性能【英文标题】:Jquery Mobile + Phonegap improve listview performance 【发布时间】:2015-02-26 11:16:29 【问题描述】:

在我的 JQM 1.4 + Phonegap 3.6 应用程序中,我使用 listview,如下代码所示。

HTML:

<div id="boardselection">           
  <ul id="modelsListview" data-role="listview"  data-icon="false">
  </ul>         
</div>

JS:

function resetModelsListView(prodata, firsttime, funfeatureOn, specificBrand, specificPro) 

console.log("on passe dans resetModelsListView");
//  funfeatureOn = 0;

//debug timer
var time = [];
var dummy;
var i;
var listviewdeferred = $.Deferred();
var optionspro = '';
var optionsbrand = '';
var optionsmodel = '';
var countpros = 0;
var countbrands = 0;
var countmodels = 0;
var chosenmodelListViewHandle = $('#modelsListview');
var chosenbrandSelect = $('#chosenbrand');
optionsmodel += '';
var alreadyusedbrands = [];
prodata.sort(SortByName);

// get previously selected model to reselect it later
//var previouslySelectedModelId =parseInt(chosenmodelSelect.find('li:selected').val());

if (!funfeatureOn) 
    prodata.sort(SortByModel);
 else 
    prodata.sort(SortByFUN);


//populate model list
//~ if (firsttime)
    //~ var perfIsChecked = true;
    //~ var smallwaveIsChecked = true;
    //~ var stepupIsChecked = true;
//~ else 
    var perfIsChecked = $('#checkboxperf').is(":checked");
    var smallwaveIsChecked = $('#checkboxsmallwave').is(":checked");
    var stepupIsChecked = $('#checkboxstepup').is(":checked");
//~ 

console.log("perfIsChecked, smallwaveIsChecked, stepupIsChecked =");
console.log(perfIsChecked);
console.log(smallwaveIsChecked);
console.log(stepupIsChecked);

//if none checked then no filter
if (!perfIsChecked && !smallwaveIsChecked && !stepupIsChecked) 
    perfIsChecked = true;
    smallwaveIsChecked = true;
    stepupIsChecked = true;


for (i = 1; i < prodata.length; ++i) 
    if (specificBrand && prodata[i]['brand'] != specificBrand) 
     else if (specificPro && prodata[i]['name'] != specificPro) 
     else 
        if (prodata[i]['fun'] == 0 && perfIsChecked) 
            optionsmodel += '<li><a class="optionfuninit" href="#" data-proid="' + prodata[i]['id'] + '"><div class="listviewtexts"><span class="listviewtextsmodel">' + prodata[i]['model'] + '</span> - <span class="listviewtextspro">as surfed by ' + prodata[i]['name'] + '</span></div></a></li>';
         else if (prodata[i]['fun'] == 1 && smallwaveIsChecked) 
            optionsmodel += '<li><a class="optionfuninit" href="#" data-proid="' + prodata[i]['id'] + '"><div class="listviewtexts"><span class="listviewtextsmodel">' + prodata[i]['model'] + '</span> - <span class="listviewtextspro">as surfed by ' + prodata[i]['name'] + '</span></div></a></li>';
         else if (prodata[i]['fun'] == 2 && stepupIsChecked) 
            optionsmodel += '<li><a class="optionstepupinit" href="#" data-proid="' + prodata[i]['id'] + '"><div class="listviewtexts"><span class="listviewtextsmodel">' + prodata[i]['model'] + '</span> - <span class="listviewtextspro">as surfed by ' + prodata[i]['name'] + '</span></div></a></li>';
         else if (prodata[i]['fun'] == 3 && smallwaveIsChecked) 
            optionsmodel += '<li><a class="optionkidsinit" href="#" data-proid="' + prodata[i]['id'] + '"><div class="listviewtexts"><span class="listviewtextsmodel">' + prodata[i]['model'] + '</span> - <span class="listviewtextspro">as surfed by ' + prodata[i]['name'] + '</span></div></a></li>';
        
        if (prodata[i]['model'] !== prodata[i - 1]['model'])  //eliminate name duplicates if prodata sorted by model
            countmodels = countmodels + 1;
        
    

chosenmodelListViewHandle.html(optionsmodel);

if (chosenmodelListViewHandle.listview("option", "disabled")) 
    chosenmodelListViewHandle.listview("option", "disabled", false);

//~ if (resetModelsOnly) 
//~ if ( !isNaN(previouslySelectedModelId) ) 
//~ chosenmodelListViewHandle.find('li[href="' + previouslySelectedModelId + '"]').attr("selected", "selected").siblings('li').removeAttr('selected');
//~ 
//~ 

//~ highlightFunModels(funfeatureOn, 1);
//~ highlightStepupModels(funfeatureOn, 0);


chosenmodelListViewHandle.listview("refresh", true);
$("#chosenmodel-button").addClass("ui-icon-carat-d ui-btn-icon-right");

if (!funfeatureOn) 
 else 
    $('ul#chosenmodel-menu').find("a.ui-btn:contains(SMALL-WAVE)").addClass("optionfun");
    $('ul#chosenmodel-menu').find("a.ui-btn:contains(STEP-UP)").addClass("optionstepup");

prodata.sort(SortById); //we need this otherwise prodata is not usable by the $('#chosenpro').trigger

$("#chosenmodel-button span").attr( 'data-i18n': 'select.3' );
$("#boardselection").i18n();
listviewdeferred.resolve();
return listviewdeferred;

这会动态显示一长串图像和文本,具体取决于是否选中了过滤器(复选框),而且这个列表生成起来很长,而且在 iOS 中滚动特别困难.... 性能很差。

你能帮我找出提高性能的方法吗?

【问题讨论】:

你可以只加载前 10 个项目,然后要么有一个 MORE 按钮不断添加到列表中,要么实现一些分页,这样一次只加载 10 个项目,你有 NEXT 和 PREVIOUS 按钮. 10 是任意的,您的页面大小可能会更大或更小,具体取决于您的项目中最适合的内容。 嗨@ezanker,感谢您的评论。我希望不给用户增加更多按钮的负担,所以我想找到一个不涉及添加按钮的解决方案。有没有办法检测列表上的滑动并加载更多项目? 见奥马尔的文章:jqmtricks.wordpress.com/2014/07/15/infinite-scrolling 【参考方案1】:

接受的答案不正确。 您的代码很慢,但不是因为 jQuery Mobile。 看看 jsFiddle 中的循环:jsfiddle.net/L3gr46s8/4

for (i = 0; i <= 50; i++) 
    $('ul[data-role="listview"]').append('<li><a href="#">' + 'list item ' + i + '</a></li>');
    $('ul[data-role="listview"]').listview('refresh');

这四行代码中有几个非常重要的问题。

首先,您的代码执行两次 DOM 遍历来定位页面上的 ul。您可以在循环之前执行$('ul[data-role="listview"]') 并将结果存储在变量中:

var listView = $('ul[data-role="listview"]');

其次,您的代码将列表项直接插入 DOM,并指示 jQuery Mobile 立即使用 .listview('refresh'); 应用标记增强功能。 这非常昂贵!尤其是在功率不足的移动设备上。根据浏览器和页面布局,这两行可能会在循环的每次迭代中触发整个页面的重新绘制。

您应该将内容呈现为 DocumentFragment(在内存中),在一个操作中将其全部插入 DOM,并在最后告诉 JQM 增强标记一次。即使只是简单地将$('ul[data-role="listview"]').listview('refresh'); 移出循环也会是一个巨大的改进。

这里有一些关于在将内容插入 DOM 之前先在内存中呈现内容的重要性的额外阅读:

How expensive is it to dynamically insert DIVs using JavaScript?

John Resig - DOM DocumentFragments

【讨论】:

【参考方案2】:

简而言之,jQuery Mobile 很慢。

我的应用程序中有一个动态列表视图,并且在使用 jQuery Mobile 时也遇到了性能问题。我得出的结论是,问题出在渲染中,是由 jQuery Mobile 引起的。我实现了自己的样式,渲染时间从 170 毫秒降低到了 25 毫秒。

这是我的一些备份(3 篇文章):http://apachecordova.blogspot.fi/search/label/jQuery%20Mobile


编辑: 作为对您在 cmets 中的问题的回答,我认为如果我在这里发布我的代码不会有帮助。关键是你只写你需要的代码。我的列表视图可能与您的完全不同。

为了(再次)证明我的观点,我制作了两个列表视图。第一个是基本的 jQM 列表视图。另一个使用自定义 CSS 进行样式设置,它与我在应用程序中使用的非常接近。两者都有一个按钮可以呈现列表视图。幕后发生的事情非常不同: jQM: 如您所见,有很多东西(您可能不需要)正在进行

自定义 CSS: 为所有元素附加一个事件监听器,以使比较更公平

这些配置文件是用 Chrome 开发者工具记录的,区别很明显:173 毫秒 vs 12 毫秒。这个自定义 CSS 花了我大约 5 分钟的时间来写:

#custom-listview 
    list-style-type: none;
    padding: 0px;
    margin: 0px;

#custom-listview li 
    display: block;
    position: relative;
    overflow: visible;

#custom-listview a 
    display: block;
    position: relative;
    text-overflow: ellipsis;
    text-decoration: none;
    color: white;
    padding: .7em 1em;
    font-size: 16px;
    background-color: #333;
    border: solid 1px #1f1f1f;
    overflow: hidden;
    white-space: nowrap;
    font-family: sans-serif;

我必须在此处添加一些代码,因为如果没有以下代码,我将无法链接到 Fiddle:

    jQM Custom CSS

我并不是说 jQuery Mobile 很糟糕。这对很多事情都有好处。但是如果你有复杂的结构和/或大量的数据,性能可能会成为一个问题,尤其是在 PhoneGap 应用程序中。这就是我的小经验得出的结论。

【讨论】:

啊哈 ;) 我喜欢你的第一句话!这就是为什么我将很快迁移到 Ionic。你的回答很有趣,我会读你的文章,我真的很愿意尝试这个。您认为您可以将自定义列表视图的代码发送给我,而不是使用 JQM 吗?谢谢。 嗨@balzafin,我采纳了你的建议并编写了我自己的列表以避免JQM 标记。在我的应用程序中确实感觉更快。但我认为还有另一个问题:我的列表显示图像并且滚动效果不是很好。也许是因为所有图像的总和太重了。 可能是。如果可以,请在没有图像、Lorem ipsum 或其他文本的情况下对其进行测试。至少你会发现这是不是这个原因。如果是这样,我能想到的唯一选项是分页或无限滚动,正如 ezanker 建议的那样。我并没有真正使用图片那么多,但也许你也可以尝试一些image optimization。 突然想到,如果滚动感觉很粘,您可以尝试 Velocity 滚动:-webkit-overflow-scrolling: touch;。我用谷歌搜索了它,还找到了其他一些tips。在您的情况下最重要的是:始终预加载您的图像并隐藏大屏幕外的图像。因此,将它们全部加载,但以某种方式隐藏当前不在用户视图中的那些。可能值得一试。 @balzafin 你的代码很慢,但不是因为 jQuery Mobile。 看看你的 jsFiddle 中的循环:jsfiddle.net/L3gr46s8/4 你执行 两个 b> DOM 遍历以定位页面上的ul。接下来,将列表项直接插入 DOM(根据浏览器触发整页重排)。最后,您告诉 jQuery Mobile 在插入 每个 项后应用标记增强.listview('refresh');。您应该将内容呈现为 DocumentFragment(在内存中),在一个操作中将其全部插入 DOM,然后告诉 JQM 在最后增强标记 once

以上是关于jquery mobile listview使用ajax动态加载后,跳转到其他页面返回时数据没有保存如何解决?的主要内容,如果未能解决你的问题,请参考以下文章

Jquery Mobile + Phonegap 提升 listview 性能

使用本地 JSON 数据填充 jQuery Mobile ListView

使用本地 JSON 数据填充 jQuery Mobile ListView

jQuery Mobile:listview('refresh') 应该进入哪个事件?

ajax后刷新jQuery mobile listview

jQuery Mobile:$(...).listview 不是函数