セットアップ:
階層データを表示するネストされた html テーブル構造があり、ユーザーは個々の行を非表示または表示できます。各行には、レベル番号とそのレベルのレコード タイプの主キーで構成される dom id があります。各レベルは異なるデータベーステーブルからのものであるため、両方が必要です。そのため、主キーだけではDOM内で一意ではありません。
example: id="level-1-row-216"
表示可能な要素のレベルと行を Cookie に保存しているため、ページをリロードすると、ユーザーが開いていたのと同じ行が自動的に表示されます。dom id の完全なマップは保存しません。冗長になりすぎるのが心配で、Cookie を 4Kb 未満に抑えたいからです。
そこで、dom id を次のようなコンパクトな json オブジェクトに変換します。各レベルに 1 つのプロパティがあり、各レベルの下に一意の主キーの配列があります。
{
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];
}
}