Search code examples
javascriptfirefoxiframefirefox-addonbrowser-extension

Search element on complete page including intern frames


I'm currently trying to program a browser extension for the intranet of the company I work in, for this I need to get different HTML element via JavaScript, and would like to have a general function for this, since many of these elements are in frames (not iframes!) which are in a frameset . I've been googling for a good 2 hours now and haven't found a working solution. Among other things, I have already tried it via window.frameElement.contentDocument, which works in the HTML inspector, but gives an error in the script that this element supposedly does not exist, besides, this function is not exactly generally applicable... Is there anyone here who has written such a function by chance? I need a plain JavaScript solution. All frames on the page are from the same domain.

This is what I had so far (not working):

function findInAll(selector) {
  let result = [];
  let search = getAllElements();

  result.push(document.querySelectorAll(selector));

  // loop through all search elements
  for (let i = 0; i < search.length; i++) {
    // if element matches selector
    if (search[i].elements[0].matches(selector)) {
      // push element to result
      result.push(search[i]);
    }
  }
  return result;
}

function getAllElements(parent = document) {
  let all = parent.getElementsByTagName("*");
  let elements = [];

  for (let i = 0; i < all.length; i++) {
    elements.push(all[i]);

    if (
      all[i].tagName == "IFRAME" ||
      all[i].tagName == "FRAME" ||
      all[i].tagName == "FRAMESET"
    ) {
      elements.push(getAllElements(all[i]));
    }
  }

  return elements;
}

Solution

  • I was thinking too complicated... Apparently I should also think again about my English skills that I have not come to this formulation of question, but now thanks to this answer I could write a own function:

    function findElement(selector, start = window) {
      var el = start.document.querySelectorAll(selector);
      let result = null;
    
      if (el.length > 0) {
        for (var i = 0; i < el.length; i++) {
          return el[i];
        }
      }
    
      for (var i = 0; i < start.frames.length; i++) {
        result = findElement(selector, start.frames[i].window);
    
        if(result != null) {
          break;
        }
      }
    
      return result;
    }
    
    function findElements(selector, start = window) {
      let result = [];
    
      var el = start.document.querySelectorAll(selector);
    
      if (el.length > 0) {
        for (var i = 0; i < el.length; i++) {
          result.push(el[i]);
        }
      }
    
      for (var i = 0; i < start.frames.length; i++) {
        let found = findElement(selector, start.frames[i].window);
    
        if (found.length > 0) {
          for (var j = 0; j < found.length; j++) {
            result.push(found[j]);
          }
        }
      }
    
      return result;
    }