我正在使用这里的jQuery树https://github.com/pioz/jquery-tree#readme
问题是当我进行cookie保存时渲染树。当需要重新渲染它时,如果我不遵循特定的方式放置有序列表,代码就无法正常工作。
我想最好看看我提出的这个演示代码。
现在,第一棵树再次正确呈现,其中cookie显示之前打开的内容,但第二棵树没有。我认为这是因为在第二个问题上,我把没有分层的那个放在带有子级的那个上面(这个叫做“这就是差异”)。
有没有办法调整代码,这样无论我在任何子级别中有什么顺序,它都可以使用cookie正确呈现视图?
// Require jQuery
// Use jQuery.cookie if you want to restore the previous expansion of the tree
jQuery.fn.tree = function(options) {
// Setup default options
/** Avaiable options are:
* - open_char: defeault character to display on open node in tree
* - close_char: defeault character to display on close node in tree
* - default_expanded_paths_string: if no cookie found the tree will be expand with this paths string
**/
if(options === undefined || options === null)
options = {};
var open_char = options.open_char;
var close_char = options.close_char;
var default_expanded_paths_string = options.default_expanded_paths_string;
if(open_char === undefined || open_char === null)
open_char = '▼';
if(close_char === undefined || close_char === null)
close_char = '►';
if(default_expanded_paths_string === undefined || default_expanded_paths_string === null)
default_expanded_paths_string = '0';
// Get the expanded paths from the current state of tree
jQuery.fn.save_paths = function() {
var paths = [];
var path = [];
var open_nodes = jQuery(this).find('li span.open');
var last_depth = null;
for(var i = 0; i < open_nodes.length; i++) {
var depth = jQuery(open_nodes[i]).parents('ul').length-1;
if((last_depth == null && depth > 0) || (depth > last_depth && depth-last_depth > 1))
continue;
var pos = jQuery(open_nodes[i]).parent().prevAll().length;
if(last_depth == null) {
path = [pos];
} else if(depth < last_depth) {
paths.push(path.join('/'));
var diff = last_depth - depth;
path.splice(path.length-diff-1, diff+1);
path.push(pos);
} else if(depth == last_depth) {
paths.push(path.join('/'));
path.splice(path.length-1, 1);
path.push(pos);
} else if(depth > last_depth) {
path.push(pos);
}
last_depth = depth;
}
paths.push(path.join('/'));
try { jQuery.cookie(this.attr('class'), paths.join(',')); }
catch(e) {}
};
// This function expand the tree with 'path'
jQuery.fn.restore_paths = function() {
var paths_string = null;
try { paths_string = jQuery.cookie(this.attr('class')); }
catch(e) { paths_string = default_expanded_paths_string; }
if(paths_string === null || paths_string === undefined)
paths_string = default_expanded_paths_string;
var paths = paths_string.split(',');
for(var i = 0; i < paths.length; i++) {
var obj = jQuery(this);
var path = paths[i].split('/');
for(var j = 0; j < path.length; j++) {
obj = jQuery(obj.children('li').children('ul')[path[j]]);
obj.show();
obj.parent().children('span').attr('class', 'open');
obj.parent().children('span').html(open_char);
}
}
};
for(var i = 0; i < this.length; i++) {
if(this[i].tagName === 'UL') {
// Make a tree
jQuery(this[i]).find('li').has('ul').prepend('<span class="close" style="cursor:pointer;">' + close_char + '</span>');
jQuery(this[i]).find('ul').hide();
// Restore cookie expand path
jQuery(this[i]).restore_paths();
// Click event
jQuery(this[i]).find('span').live('click', {tree : this[i]}, function(e) {
if (jQuery(this).attr('class') == 'open') {
jQuery(this).parent().children('ul').hide('slow');
jQuery(this).attr('class', 'close');
jQuery(this).html(close_char);
} else if (jQuery(this).attr('class') == 'close') {
jQuery(this).parent().children('ul').show('slow');
jQuery(this).attr('class', 'open');
jQuery(this).html(open_char);
}
jQuery(e.data.tree).save_paths();
});
}
}
}
答案 0 :(得分:2)
问题出在jquery.tree.js的line 34中(jQuery.fn.save_paths()
内):
var pos = jQuery(open_nodes[i]).parent().prevAll().length;
open_nodes[i]
是开放/关闭span
,其父级是li
,因此prevAll()
计算前一个li
的数量。
但在line 68(jQuery.fn.restore_paths()
内)中进一步向下:
obj = jQuery(obj.children('li').children('ul')[path[j]]);
它使用save_paths()
中保存的位置来查找第n个ul
。
因此,在您的情况下,在展开第一个(仅限)ul
之后,save_paths()
会记住1
(因为li
之前有ul
}),但是当您重新加载页面时,restore_paths()
尝试展开“第二个”ul
(第一个是0
,第二个ul
是1
)。
无论如何,解决方案是改变第34行:
var pos = jQuery(open_nodes[i]).parent().prevAll().length;
到此:
var pos = jQuery(open_nodes[i]).parent().prevAll(':has(">ul")').length;
这将确保在计算当前li
的位置时跳过没有嵌套ul
的{{1}}。
我已经通过此修复程序向pioz提交了拉取请求。在此期间,您可以使用我的fork中的固定版本:https://github.com/jefferyto/jquery-tree/raw/counting-fix/jquery.tree.js。
您可以在此处看到它:http://jsbin.com/emaku4/28
更新: pioz提交了(不同的)修复程序。您可以在https://github.com/pioz/jquery-tree下载工作代码。谢谢pioz!
答案 1 :(得分:1)
看看这个:http://docs.jquery.com/Plugins/Treeview/treeview
为cookie设置persist选项,如下所示:
$(".selector").treeview({
persist: "cookie"
});
这是一种渲染树视图的简便方法。