Получить все объекты (DOM или иным образом), используя JavaScript - PullRequest
5 голосов
/ 07 декабря 2011

Краткая версия:

  • Как получить список всех объектов (включая объекты-потомки) на странице (не только объекты первой глубины)?
  • Ожидаемая подзадача : Как я могу отслеживать посещенные объекты во время прогулки по ним?

Заранее спасибо.



Длинная версия (с фоном !!):

Используя ключевое слово 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.хотя в хроме отлично работает.

1 Ответ

11 голосов
/ 07 декабря 2011

Моя быстрая попытка:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...