2014-04-18 34 views
0

我正在尋找更好的方式來生成父子關係圖;基於特定的id模式。性能:生成扁平的父母子女名單ID

它更快的要求void 0 === cache[parent][child];預期的結果:

{ 
     uuid_1: {uuid_2: {}} 
     uuid_2: {uuid_3: {}, uuid_4: {}} 
     uuid_3: {} 
     uuid_4: {} 
    } 

的HTML結構:

<html id="uuid-1"> 
     <body id="uuid-2"> 
      <somewhere> 
       <whatever id="uuid-3" /> 
      </somewhere> 
      <foo id="uuid-4" /> 
     </body> 
    </html> 

_fetch()

<1> // register as init 
     <2> // register as child of 1 
      <3> 
       <4 /> // register as child of 2 
      </3> 
      <5 /> // register as child of 2 
     </2> 
    </1> 

解析〜1300元(大菜單結構)找到我〜50點的UUID。

嘗試1使用jQuery:

_fetch: function(element, factoryName) 
{ 
    var a = {}, l = 0, t = this, f = function(el, n) 
    { 
     if(!a[n]) a[n] = {}; 

     var e = $(el), test = $('[id^="uuid-"]', e); 

     if(!test.length) 
      return; 

     e.children().each(function() 
     { 
      var u = $(this), id = u.attr('id'), q; 

      // anonymous element: no class defined 
      if(!(id && 'uuid-' === id.slice(0x00, 0x05))) 
      { 
       f(this, n); // continue with current name 
       return; 
      } 

      l++; 
      q = $.T.util.uuidFromId(id); 
      $.T.__dict[q] = '#' + id; 

      a[n][q] = {}; 
      // comment in/out 
      f(this, q); 
     }); 

    } 

    f(element, factoryName); 
    return a; 
} 

嘗試2黃JS:

..., g = function(n, p) 
    { 
     var r = []; 
     for(var d = (p || document).getElementsByTagName('*'), i = 0, l = d.length; i < l; i++) 
      d[i].getAttribute(n) && r.push(d[i]); 
     return r; 
    }, 
f = function(el, n) 
{ 
    var z = el.children.length, y = 0; 
    if(!a[n]) a[n] = {}; 

    if(z && g('id', el)) for(; y < z; y++) 
    { 
     var u = el.children[y], id = u.getAttribute('id'), q; 

     if(!(id && 'uuid-' === id.slice(0x00, 0x05))) 
     { 
      f(u, n); 
      continue; 
     } 

     l++; 
     $.T.__dict[q = $.T.util.uuidFromId(id)] = '#' + id; 
     a[n][q] = {}; 

     // it's irrelevant to fetch the full html or a sequence by constructor 
     //f(u, q); 
    } 
} 

我的問題是: 如何收集DOM元素作爲平面表示在一個更快的方法;像上面的映射一樣?我目前的解決方案非常滯後。

OT:基於 語境X-對話框上圖:

<baz><alice><bob><bobchild/></bob></alice><foo /> 

    alice._init: 
     before init children of bob 
     tell foo 'go away' 
     before init bob    // context: no bob 
     after init children of alice //   && alice without children 
      after init baz   //   && baz not ready -> no hello 
       tell baz 'hello' 
+0

是您的第一個代碼塊,所需的結果?你只是想從你的HTML中產生最快的方式? – jfriend00

+0

另外,你真的想在算法中的''元素中包含一個id嗎?而且,爲什麼你的數據結構中的那個項目沒有顯示所有其他項目作爲後代? – jfriend00

+0

是的:第一個代碼塊是我想要的結果;第二塊我的HTML;第三塊是'_fetch()'如何看HTML。 *後代對象*是原型引導加載程序/引導程序。 – somia

回答

1

我還不太清楚,我知道你想要做什麼,但這裏是我知道走DOM樹的最快方法和積累父/子信息像你這樣做來構建數據結構您已表示自己想與落得:

var treeWalkFast = (function() { 
    // create closure for constants 
    var skipTags = {"SCRIPT": true, "IFRAME": true, "OBJECT": true, 
     "EMBED": true, "STYLE": true, "LINK": true, "META": true}; 

    return function(parent, fn, allNodes) { 
     var parents = []; 
     var uuidParents = []; 
     parents.push(parent); 
     uuidParents.push(parent); 
     var node = parent.firstChild, nextNode, lastParent; 
     while (node && node != parent) { 
      if (allNodes || node.nodeType === 1) { 
       if (fn(node, parents, uuidParents) === false) { 
        return(false); 
       } 
      } 
      // if it's an element && 
      // has children && 
      // has a tagname && is not in the skipTags list 
      // then, we can enumerate children 
      if (node.nodeType === 1 && node.firstChild && !(node.tagName && skipTags[node.tagName])) { 
       // going down one level, add this item to the parent array 
       parents.push(node); 
       if (node.id && node.id.substr(0, 5) === "uuid-") { 
        uuidParents.push(node); 
       } 
       node = node.firstChild; 
      } else if (node.nextSibling) { 
       // node had no children so going to next sibling 
       node = node.nextSibling; 
      } else { 
       // no child and no nextsibling 
       // find parent that has a nextSibling 
       while ((node = node.parentNode) != parent) { 
        lastParent = parents.pop(); 
        if (lastParent === uuidParents[uuidParents.length - 1]) { 
         uuidParents.pop(); 
        } 
        if (node.nextSibling) { 
         node = node.nextSibling; 
         break; 
        } 
       } 
      } 
     } 
    } 
})(); 

var objects = {uuid_1: {}}; 
treeWalkFast(document.documentElement, function(node, parents, uuidParents) { 
    if (node.id && node.id.substr(0, 5) === "uuid-") { 
     var uuidParent = uuidParents[uuidParents.length - 1]; 
     if (!objects[uuidParent.id]) { 
      objects[uuidParent.id] = {}; 
     } 
     objects[uuidParent.id][node.id] = {}; 
     objects[node.id] = {}; 
    } 
}); 

工作演示在這裏:http://jsfiddle.net/jfriend00/yzaJ6/

這是我爲this answer編寫的treeWalkFast()函數的改編版本。