我正在尝试使用应用程序缓存和本地存储等技术编写一个可以在线和离线工作的应用程序。我正在使用 jQuery mobile 和 jqm 自动完成解决方案,可以在这里找到http://andymatthews.net/code/autocomplete/
这个想法是,如果应用程序在线,那么我将通过 ajax 调用一个远程访问函数,该函数将设置数据。发出的 ajax 调用会带回事件、国家和医院的数据。一旦返回数据,我将在 localStorage 中设置数据。
如果数据已经存在于 localStorage 中,那么我可以在离线时继续,因为我不必依赖 ajax 调用。
在 iPad/移动设备上运行时,我遇到了此代码的性能问题。就医院数据而言。有大量的医院数据被返回,请参阅下面的医院数据 JSON 示例。它在桌面上可能有点慢,但几乎没有那么糟糕。
任何人都可以看到我下面的代码的任何改进以提高性能。
JSON 医院数据示例
{ "hospitals" : {
"1" : { "country" : "AD",
"label" : "CAIXA ANDORRANA SEGURETAT SOCIAL"
},
"10" : { "country" : "AE",
"label" : "Advance Intl Pharmaceuticals"
},
"100" : { "country" : "AT",
"label" : "BIO-KLIMA"
},
"1000" : { "country" : "BE",
"label" : "Seulin Nicolas SPRL"
},
"10000" : { "country" : "ES",
"label" : "Dental 3"
},
"10001" : { "country" : "ES",
"label" : "PROTESIS DENTAL MACHUCA PULIDO"
},
"10002" : { "country" : "ES",
"label" : "JUST IMPLANTS, S.L."
},
"10003" : { "country" : "ES",
"label" : "CTRO DENTAL AGRIC ONUBENSE DR.DAMIA"
},
"10004" : { "country" : "ES",
"label" : "HTAL. VIRGEN DE ALTAGRACIA"
},
"10005" : { "country" : "ES",
"label" : "HOSPITAL INFANTA CRISTINA"
}....
/*global document,localStorage,alert,navigator: false, console: false, $: false */
$(document).ready(function () {
//ECMAScript 5 - It catches some common coding bloopers, throwing exceptions. http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
//It prevents, or throws errors, when relatively "unsafe" actions are taken (such as gaining access to the global object).
//It prevents, or throws errors, when relatively "unsafe" actions are taken (such as gaining access to the global object).
"use strict";
//initialise online/offline workflow variables
var continueWorkingOnline, continueWorkingOffline, availableEvents, availableHospitals, availableCountries, availableCities;
continueWorkingOnline = navigator.onLine;
var getLocalItems = function () {
var localItems = [];
availableEvents = localStorage.getItem('eventData');
availableHospitals = localStorage.getItem('hospitalData');
availableCountries = localStorage.getItem('countryData');
if (availableEvents) {
//only create the array if availableEvents exists
localItems[0] = [];
localItems[0].push(availableEvents);
}
if (availableCountries) {
//only create the array if availableCountries exists
localItems[1] = [];
localItems[1].push(availableCountries);
}
if (availableHospitals) {
//only create the array if availableHospitals exists
localItems[2] = [];
localItems[2].push(availableHospitals);
}
if (availableCities) {
//only create the array if availableHospitals exists
localItems[3] = [];
localItems[3].push(availableCities);
}
return localItems;
};
//Check to see if there are 3 local items. Events, Countries, Cities. If true we know we can still run page off line
continueWorkingOffline = getLocalItems().length === 3 ? true: false;
//Does what is says on the tin
var populateEventsDropDown = function (data) {
var eventsDropDown = $('#eventSelection');
var item = data.events;
$.each(item, function (i) {
eventsDropDown.append($('<option></option>').val(item[i].id).html(item[i].name));
});
};
//Called once getData's success call back is fired
var setFormData = function setData(data, storageName) {
//localStorage.setItem(storageName, data);
localStorage.setItem(storageName, data);
};
//This function is only called if continueWorkingOnline === true
var getRemoteFormData = function getData(ajaxURL, storageName) {
$.ajax({
url: ajaxURL,
type: "POST",
data: '',
success: function (data) {
setFormData(data, storageName);
}
});
};
//Function for autoComplete on Hospital data
var autoCompleteDataHospitals = function (sourceData) {
var domID = '#hospitalSearchField';
var country = $('#hiddenCountryID').val();
var items = $.map(sourceData, function (obj) {
if (obj.country === country) {
return obj;
}
});
$(domID).autocomplete({
target: $('#hospitalSuggestions'),
source: items,
callback: function (e) {
var $a = $(e.currentTarget);
$(domID).val($a.data('autocomplete').label);
$(domID).autocomplete('clear');
}
});
};
//Function for autoComplete on Country data
var autoCompleteDataCountries = function (sourceData) {
var domID = '#countrySearchField';
var domHiddenID = '#hiddenCountryID';
var items = $.map(sourceData, function (obj) {
return obj;
});
$(domID).autocomplete({
target: $('#countrySuggestions'),
source: items,
callback: function (e) {
var $a = $(e.currentTarget);
$(domID).val($a.data('autocomplete').label);
$(domID).autocomplete('clear');
$(domHiddenID).val($a.data('autocomplete').value);
//enable field to enter Hospital
$('#hospitalSearchField').textinput('enable');
//Call to autoComplete function for Hospitals
autoCompleteDataHospitals(availableHospitals.hospitals);
}
});
};
if (continueWorkingOnline === false && continueWorkingOffline === false) {
alert("For best results this form should be initiated online. You can still use this but auto complete features will be disabled");
}
if (continueWorkingOnline === true && continueWorkingOffline === false) {
getRemoteFormData('templates/cfc/Events.cfc?method=getEventsArray', 'eventData');
getRemoteFormData('templates/cfc/Countries.cfc?method=getCountriesArray', 'countryData');
getRemoteFormData('templates/cfc/Hospitals.cfc?method=getHospitalsArray', 'hospitalData');
$(document).ajaxStop(function () {
//set the variables once localStorage has been set
availableEvents = JSON.parse(localStorage.getItem("eventData"));
availableHospitals = JSON.parse(localStorage.getItem('hospitalData'));
availableCountries = JSON.parse(localStorage.getItem('countryData'));
//Inserts data into the events drop down
populateEventsDropDown(availableEvents);
autoCompleteDataCountries(availableCountries.countries);
});
}
if (continueWorkingOnline === true && continueWorkingOffline === true) {
//get the localStorage which we know exists because of continueWorkingOffline is true
availableEvents = JSON.parse(localStorage.getItem('eventData'));
availableHospitals = JSON.parse(localStorage.getItem('hospitalData'));
availableCountries = JSON.parse(localStorage.getItem('countryData'));
//Inserts data into the events drop down
populateEventsDropDown(availableEvents);
autoCompleteDataCountries(availableCountries.countries);
}
});