设置:
我有一个嵌套的html表结构,显示分层数据,用户可以隐藏或显示各个行。每行都有一个dom id,它由级别号加上该级别上记录类型的主键组成。我必须同时拥有这两个级别,因为每个级别都来自不同的数据库表,所以主键在dom中不是唯一的。
example: id="level-1-row-216"
我将可见元素的级别和行存储在cookie中,这样当页面重新加载用户打开的相同行时,可以自动显示。我没有存储dom id的完整地图,因为我担心它变得过于冗长,我想把我的cookie保持在4Kb以下。
所以我将dom id转换为这样的紧凑json对象,每个级别有一个属性,每个级别下有一个唯一的主键数组:
{
1:[231,432,7656],
2:[234,121],
3:[234,2],
4:[222,423],
5:[222]
}
将此结构存储在cookie中,我将其提供给我的show函数,并在页面加载时恢复用户之前的披露状态。
需要改进的地方:
我正在寻找更好的选项,将我的id选择器地图缩小到这种紧凑的格式。这是我的功能:
function getVisibleIds(){
// example dom id: level-1-row-216-sub
var ids = $("tr#[id^=level]:visible").map(function() {
return this.id;
});
var levels = {};
for(var i in ids ) {
var id = ids[i];
if (typeof id == 'string'){
if (id.match(/^level/)){
// here we extract the number for level and row
var level = id.replace(/.*(level-)(\d*)(.*)/, '$2');
var row = id.replace(/.*(row-)(\d*)(.*)/, '$2');
// *** Improvement here? ***
// This works, but it seems klugy. In PHP it's one line (see below):
if(levels.hasOwnProperty(level)){
if($.inArray(parseInt(row, 10) ,levels[level]) == -1){
levels[level].push(parseInt(row, 10));
}
} else {
levels[level] = [parseInt(row, 10)];
}
}
}
}
return levels;
}
如果我在PHP中这样做,我会像这样构建紧凑数组,但我无法在javascript中找到它:
foreach($ids as $id) {
if (/* the criteria */){
$level = /* extract it from $id */;
$row = /* extract it from $id */;
$levels[$level][$row];
}
}
答案 0 :(得分:2)
所以你的函数中有一些重复/不需要的东西:
如果你这样做
var ids = $("tr#[id^=level]:visible").map(function() {
和这个
for(var i in ids ) {
您在匹配的ID上循环两次
isnt id总是这里的字符串???
if (typeof id == 'string'){
这不一定是必要的,因为你的jQuery-Selector:“tr#[id ^ = level]:visible” 你的匹配元素应始终以'level'开头
if (id.match(/^level/)){
总而言之,我认为这应该更短(无法测试,下次请提供一个jsfiddle,会更容易; - )
function getVisibleIds(){
// example dom id: level-1-row-216-sub
var level, parsed, levels = {};
$("tr#[id^=level]:visible").map(function() {
// here we extract the number for level and row
level = this.id.replace(/.*(level-)(\d*)(.*)/, '$2');
parsed = parseInt(this.id.replace(/.*(row-)(\d*)(.*)/, '$2'), 10);
// i like this more
if(!levels.hasOwnProperty(level)) { levels[level] = []; }
if($.inArray(parsed, levels[level]) === -1) {
levels[level].push(parsed);
}
});
return levels;
}
答案 1 :(得分:2)
我的尝试
function getVisibleIds() {
var parts, level, row, levels = {};
var ids = $("tr#[id^=level]:visible").each(function (index, el) {
parts = el.id.split("-"); // no regex :)
level = parts[1];
row = parts[3];
if (!levels[level]) { levels[level] = []; }
if ($.inArray(row, levels[level]) + 1) { levels[level].push(row); }
});
return levels;
}
答案 2 :(得分:1)
function getVisibleIds(){
// example dom id: level-1-row-216-sub
var levels = {};
var ids = $("tr#[id^=level]:visible")
.map(function() {
return this.id;
})
.each(function (index, id) {
if (!id || typeof id !== 'string') {
return;
}
if (id.match(/^level/) === false) {
return;
}
var level = id.replace(/.*(level-)(\d*)(.*)/, '$2');
var row = id.replace(/.*(row-)(\d*)(.*)/, '$2'),
primaryKey = parseInt(row, 10);
if (!levels[level]) {
levels[level] = [];
}
var arr = levels[level];
if (arr.indexOf(primaryKey) === -1) {
levels[level].push(primaryKey);
}
});
return levels;
}
要注意的关键点是,您可以使用. (dot notation)
或访问者[]
来访问对象的属性。