2011-04-03 27 views
0

我使用jQuery的樹從這裏https://github.com/pioz/jquery-tree#readmejQuery的樹(皮奧斯):樹犯規與餅乾

問題是渲染樹的,當我做一個cookie保存正確呈現。當它重新呈現它時,如果我不遵循放置有序列表的特定方式,代碼將無法正常工作。

我想最好看看這個演示代碼。

http://jsbin.com/emaku4/23

  1. 整個樹是開放
  2. 點擊3級箭頭展開(兩樹)
  3. 執行刷新

現在,第一棵樹正確呈現再次用cookies顯示之前打開的內容,但是第二個樹沒有顯示。我認爲這是因爲在第二天,我把沒有sublevels的那個放在帶有sublevels的那個之上(這就是所謂的「差異」)。

有沒有辦法調整代碼,以便它可以使用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

而不是通過比較整個「class」屬性來檢查類,你應該使用「.hasClass()」。否則,如果您需要爲這些元素添加*另一個*類,那麼事情根本不會起作用。 – Pointy 2011-04-03 22:32:46

+0

此外,該jsbin頁面正常工作,據我所知。什麼是破碎的部分? – Pointy 2011-04-03 22:38:23

回答

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 s的數量。

但進一步下跌的line 68(內jQuery.fn.restore_paths()):

obj = jQuery(obj.children('li').children('ul')[path[j]]); 

它使用從save_paths()保存的位置找到的第n個ul

你的情況

所以,你展開第一個(也是唯一一個)ul後,save_paths()記得1(因爲1 liul之前),但是當你重新加載頁面,restore_paths()試圖擴大「第二」 ul (第一個是0,第二個ul1)。

嗯,我不認爲我解釋這很好......


總之,解決的辦法是線34從:

var pos = jQuery(open_nodes[i]).parent().prevAll().length; 

這樣:

var pos = jQuery(open_nodes[i]).parent().prevAll(':has(">ul")').length; 

這將確保它跳過li s表示沒有嵌套ul計算當前的ul的位置。


我已經使用此修復向pioz提交了一個請求。與此同時,您可以使用我的貨叉上的固定版本:https://github.com/jefferyto/jquery-tree/raw/counting-fix/jquery.tree.js

你可以看到它在這裏工作:http://jsbin.com/emaku4/28

更新:皮奧斯犯了(不同的)解決。您可以在https://github.com/pioz/jquery-tree下載工作代碼。感謝pioz!

+0

太棒了!男人非常感謝你們。 – 2011-05-07 06:12:53