如何最好地显示来自大型json对象的匹配
how do I best display matches from a large json object?
我正在将数据从json对象加载到页面上的表中。然后,我允许用户通过输入过滤数据,并只显示匹配项。我这样做的方法肯定不太好,但确实有效。
现在,我想对机场及其代码列表做同样的事情。问题是,机场列表要长得多,当加载带有数据的表以及在表中搜索用户输入时,页面会显著下降。
这是有效页面的信息,这样你就可以知道我在做什么。
当我有更大的数据集要搜索时,我可以做什么不同的事情来获得与这里相同的效果
页面显示数据:(例如键入"美国航空公司"或"aa")https://pnrbuilder.com/_popups/dataDecoder.php
json对象,包含航空公司信息:https://pnrbuilder.com/_java/airlineDecoder.js
将数据加载到页面并根据用户输入进行筛选的Srpt:https://pnrbuilder.com/_java/decodeData.js
以下是我代码中最重要的部分:
// This function is called by a for loop on dom ready
// It basically prints data stored in a json object to a table on the page
function fillInfo(line) {
var table = document.getElementById('decodeTable');
var row = document.createElement('tr');
table.appendChild(row);
var col1 = document.createElement('td');
row.appendChild(col1);
var curCode = document.createTextNode(arlnInfo.d[line].IATA);
col1.appendChild(curCode);
var col2 = document.createElement('td');
row.appendChild(col2);
var curArln = document.createTextNode(arlnInfo.d[line].Airline);
col2.appendChild(curArln);
var col3 = document.createElement('td');
row.appendChild(col3);
var curPre = document.createTextNode(arlnInfo.d[line].Prefix);
col3.appendChild(curPre);
var col4 = document.createElement('td');
row.appendChild(col4);
var curIcao = document.createTextNode(arlnInfo.d[line].ICAO);
col4.appendChild(curIcao);
var col5 = document.createElement('td');
row.appendChild(col5);
var curCnty = document.createTextNode(arlnInfo.d[line].Country);
col5.appendChild(curCnty);
}
// This function checks user input against data in the table
// If a match is found whitin a row, the row containing the match is shown
// If a match is not found that row is hidden
function filterTable(input) {
var decodeTable = document.getElementById('decodeTable');
var inputLength = input.length;
// THis first part makes sure that all rows of the generated table are hidden when no input is present
if (inputLength == 0) {
for (var r = 1; r < decodeTable.rows.length; r++) {
decodeTable.rows[r].style.display = "none";
}
}
// This part checks just the airline codes "column" of the table when input is only one or two characters
else if (inputLength < 3) {
for (var r = 1; r < decodeTable.rows.length; r++) {
var celVal = $(decodeTable.rows[r].cells[0])
.text()
.slice(0, inputLength)
.toLowerCase();
if (celVal == input) {
decodeTable.rows[r].style.display = "";
} else {
decodeTable.rows[r].style.display = "none";
}
}
}
// This part checks several "columns" of the table when input is more than two characters
else if (inputLength > 2) {
for (var r = 1; r < decodeTable.rows.length; r++) {
var celVal = $(decodeTable.rows[r].cells[2])
.text()
.slice(0, inputLength)
.toLowerCase();
var celVal2 = $(decodeTable.rows[r].cells[1])
.text();
if (celVal == input || celVal2 == input) {
decodeTable.rows[r].style.display = "";
} else if (celVal2.replace(/<[^>]+>/g, "")
.toLowerCase()
.indexOf(input) >= 0) {
decodeTable.rows[r].style.display = "";
} else {
decodeTable.rows[r].style.display = "none";
}
}
}
}
您可以应用的第一个小优化不是对每个按键都进行整个过滤,而是等到用户完成键入,所以延迟半秒调用:
var timeOut = 0;
$("#deCode").keyup(function () {
// cancel looking, the user typed another character
clearTimeout(timeOut);
// set a timeout, when user doesn't type another key
// within half a second the filter will run
var input = $("#deCode").val().toLowerCase().trim();
timeOut=setTimeout(function(){
filterTable(input)
},500);
});
下一步是与json数据而不是jquery对象进行比较,并在创建表后将json数据转换为小写,这样您就不必每次都为每一行检查LowerCase:
function filterTable(input) {
var decodeTable = document.getElementById('decodeTable');
var inputLength = input.length;
if (inputLength ==0) {
for (var r = 1; r < decodeTable.rows.length; r++) {
decodeTable.rows[r].style.display = "none";
}
}
else if (inputLength <3) {
for (var r = 0; r < arlnInfo.d.length; r++) {
if (arlnInfo.d[r].IATA.indexOf(input)===0) {
decodeTable.rows[r+1].style.display = "";
}
else {
decodeTable.rows[r+1].style.display = "none";
}
}
}
else if (inputLength > 2) {
for (var r = 0; r < arlnInfo.d.length; r++) {
if (arlnInfo.d[r].Prefix.indexOf(input)===0) {
decodeTable.rows[r].style.display = "";
}
else if (arlnInfo.d[r].Airline.indexOf(input) >= 0) {
decodeTable.rows[r + 1].style.display = "";
}
else {
decodeTable.rows[r + 1].style.display = "none";
}
}
}
}
JSON数据存在问题:"Prefix": 430
导致arlnInfo.d[r].Prefix.slice(0, inputLength)
抛出错误,因为数据不是字符串而是数字。如果你可以控制JSON,那么你应该将这些值转换为字符串("Prefix":"430"
),如果你没有,那么转换一次,然后使用JSON.stringify(arlnInfo);
重新创建airlineDecoder.js
要转换JSON,您可以将其复制并粘贴到chrome控制台中(按F12),然后运行它(按enter)。它会记录转换后的JSON,但您可能需要像netbeans这样的IDE来重新格式化它:
var i = 0;
for(i=0;i<arlnInfo.d.length;i++){
arlnInfo.d[i].Prefix=arlnInfo.d[i].Prefix+"";
}
console.log("var arlnInfo = " + JSON.stringify(arlnInfo));
您可以应用的最后一个优化是使用DocumentFragment,而不是直接将每一行添加到DOM中,在这里我们将JSON数据转换为小写,这样我们就不必对每次搜索都这样做:
var decodeTable = document.getElementById('decodeTable');
function createTable() {
var df = document.createDocumentFragment();
for (var i = 0; i < arlnInfo.d.length; i++) {
fillInfo(i, df);
arlnInfo.d[i].IATA = arlnInfo.d[i].IATA.toLowerCase()
arlnInfo.d[i].Prefix = arlnInfo.d[i].Prefix.toLowerCase();
arlnInfo.d[i].Airline = arlnInfo.d[i].Airline.toLowerCase();
}
decodeTable.appendChild(df);
}
createTable();
....
function fillInfo(line,df) {
var row = document.createElement('tr');
df.appendChild(row);
....
row.style.display = "none";
}
- jQuery匹配JSON对象的部分文本
- 如何在Javascript中将JSon对象转换为数组
- 我可以在json对象中添加一个函数吗
- 使用JS将数组转换为json对象
- 我应该如何将响应数据保存在对象(json)中以获得更好的操作和性能
- 用javascript从列表对象(JSON的)构建diffrent选项卡
- php请求带有多个对象json-jquery
- AngularJS,过滤器:如何将一个巨大的对象(JSON)变成一个数组
- 动态属性对象 - JSON
- JavaScript 对象 (JSON) 中的动态设置值
- 从数组查询获取对象 JSON 值时出错
- 使用jQuerygetJSON将多维对象JSON转换为HTML
- 需要从 Angular JS 应用程序中的另一个 JSON 对象数组填充 JSON 数组的每个对象 JSON 对象数组
- 嵌套对象JSON排序JavaScript
- PHP在MySQL中保存来自Javascript的对象"JSON.stringify"通过Ajax
- 将JavaScript对象/ JSON转换为PHP数组
- JSON对象.JSON对象内部
- 访问对象的对象- JSON API
- 数组到对象JSON
- Message":"传入的无效对象(JSON数据格式化问题)