2011-12-07 39 views
3

短的版本:獲取的所有對象(DOM或其​​他方式)

  • 我怎樣才能在網頁上的所有對象(包括他們的後代 對象)的列表(而不僅僅是第一個深度物體)?
    • 預計子問題:我如何跟蹤 訪問的對象,因爲我走的對象?

在此先感謝。



長版(帶背景!!):

使用in關鍵字,我們可以得到一個對象的所有屬性。 (和使用hasOwnProperty方法使我們能夠篩選出只屬於該對象,而不是繼承那些屬性。)

for (var prop in obj) { 
    if (typeof(obj[prop]) == 'object' && obj.hasOwnProperty(prop)) { 
      showObjectsOfInternal(obj[prop], visitedObjects); // recursion. 
    } 
} 

這是一個很好的起點,但我想獲得的所有對象。人們可以想象遍歷所有的屬性並累積對象,然後遞歸地遍歷這些對象。但是,如果有一個對象引用循環,就像在window.window中引用的對象一樣,最好不要被這個對象困住。所以需要一種方法來跟蹤遞歸過程中的所有「訪問對象」。

要跟蹤訪問對象,根據其內部對象鍵,確實需要對象的哈希集。我試圖通過製作一個visitedObjects對象並將其設置爲要添加的對象的鍵,並且該值不重要。

if(visitedObjects[obj] == 1){return;} 
visitedObjects[obj] = 1; 

但這並不適用於我。 (它似乎將對象轉換爲鍵的字符串,而不是使用它們的內部參考鍵)

所以相反,我決定使用數組並添加indexOf方法。

Array.prototype.indexOf = function(obj){ 
    for(var i = 0; i < this.length; i++) 
    { 
     if(this[i] == obj) // reference comparison for non-primitive objects. 
     { 
     return i; 
     } 
    } 
    return -1; 
} 

但是,這並沒有工作,要麼(最終我得到了,我不能這樣做for(var prop in obj)即使對象是不是空!調試器說,OBJ不支持該屬性。)

在任何情況下,這裏是我的缺陷代碼:

function showObjectsOf(obj) { 
    var objHolder = new Array(); 
    var ancestorNames = new Array(); 
    ancestorNames.push('obj'); 
    showObjectsOfInternal(obj, objHolder, ancestorNames); 
} 
function showObjectsOfInternal(obj, visitedObjects, ancestorNames) { 
    if (visitedObjects.indexOf(obj) != -1) { 
     return; 
    } 
    visitedObjects.push(obj); 
    alert(getAncestorString(ancestorNames)); 
    for (var prop in obj) { 
     if (typeof (obj[prop]) == 'object') { 
      ancestorNames.push(prop); 
      showObjectsOfInternal(obj[prop], visitedObjects, ancestorNames); 
      ancestorNames.remove(prop); 
     } 
    } 
} 
function getAncestorString(ancestorNames) { 
    return ancestorNames.join('.'); 
} 

Array.prototype.indexOf = function(obj) { 
    for (var i = 0; i < this.length; i++) { 
     if (this[i] == obj) { 
      return i; 
     } 
    } 
    return -1; 
} 
Array.prototype.remove = function(obj){ 
    var ind = this.indexOf(obj); 
    if(ind != -1) 
    { 
     this.splice(ind,1); 
    } 
} 
window.onload = function() { showObjectsOf(window); }; 

更新 事實上,詞典可能是更好的路要走。在IE中它不適合我。雖然在鉻合金工作正常。

+0

定義 「頁面上的」。你的意思是DOM元素?你是指全局對象下的整個對象樹嗎? –

+1

另外,您可能想要處理所有這些對象? –

+0

@ŠimeVidas:我想我是指全局對象下的整個對象樹。我猜想任何給定對象下的整個對象樹都是我想要的作爲子問題。 – user420667

回答

8

我快速的嘗試:

var objs = []; // we'll store the object references in this array 

function walkTheObject(obj) { 
    var keys = Object.keys(obj); // get all own property names of the object 

    keys.forEach(function (key) { 
     var value = obj[ key ]; // get property value 

     // if the property value is an object... 
     if (value && typeof value === 'object') { 

      // if we don't have this reference... 
      if (objs.indexOf(value) < 0) { 
       objs.push(value); // store the reference 
       walkTheObject(value); // traverse all its own properties 
      } 

     } 
    }); 
} 

walkTheObject(this); // start with the global object 
+0

這樣做。謝謝。我必須開始使用forEach並建立更多。 – user420667

+0

正是我在找的東西。完善。 – Bangkokian

相關問題