使用JavaScript获取所有对象(DOM或其​​他) [英] Get all the objects (DOM or otherwise) using JavaScript

查看:53
本文介绍了使用JavaScript获取所有对象(DOM或其​​他)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短版本:

  • 如何获取所有对象(包括它们的后代)的列表 对象)(而不是第一深度的对象)上?
    • 预期的子问题:如何跟踪 在我走动物体时被访问的物体?
    • How can I get a list of all the objects (including their descendant objects) on the page (not just the first-depth objects)?
      • Anticipated subproblem: How can I track the visited objects as I walk the objects?

      谢谢.





      长版(带有背景!):

      使用in关键字,我们可以获得对象的所有属性. (并且使用hasOwnProperty方法允许我们仅过滤掉属于该对象的属性,而不是继承的属性.)

      Using the in keyword we can get all the properties of an object. (And using the hasOwnProperty method allows us to filter out only the properties that belong to that object and not the inherited ones.)

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

      这是一个很好的起点,但是我想获取所有对象.可以想象遍历所有属性并累积对象,然后递归遍历那些属性.但是,如果有一个对象引用循环(例如在window.window中引用了自身的对象),最好不要被该循环所困.因此,需要一种在递归过程中跟踪所有访问的对象"的方法.

      That is a good starting point, but I would like to get all the objects. One could imagine iterating through all the properties and accumulating the objects, then recursively iterating through those. However, if there was an object reference loop, like an object referred to itself, such as in window.window, it would be good not to get trapped by that. So one needs a way to track all the 'visited objects' during the recursion.

      要跟踪访问的对象,实际上需要根据对象的内部对象键来构成对象的哈希集.我通过制作一个visitedObjects对象并将其键设置为要添加的对象来进行尝试,该值无关紧要.

      To track the visited object, one really needs a hashset of objects, based on their internal object key. I tried that by making a visitedObjects object and setting it's keys as the object to be added, and the value didn't matter.

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

      但这对我不起作用. (似乎将对象转换为键的字符串,而不是使用其内部参考键)

      But that didn't work for me. (It seems to turn the objects into strings for keys, instead of using their internal reference keys)

      因此,我决定使用一个数组并添加一个indexOf方法.

      So instead I decided to use an array and add an indexOf method.

      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; 
      }
      

      但是那也不起作用(最终,我得到即使对象不为null我也无法执行for(var prop in obj)!调试器说obj不支持该属性.)

      But that didn't work either (eventually I got that I couldn't do for(var prop in obj) even though the object wasn't null! The debugger said that obj did not support that property.)

      无论如何,这是我的儿童车代码:

      In any case, here is my buggy code:

      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中,它对我不起作用.虽然在chrome中可以正常工作.

      Update Actually, the dictionary may be the better way to go. It just wasn't working for me in IE. works fine in chrome though.

      推荐答案

      我的快速尝试:

      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
      

      这篇关于使用JavaScript获取所有对象(DOM或其​​他)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆