title: Add an element to the fully loaded DOM with Chrome extension
body: <p>I'm making a simple chrome extension that adds a form element to a page. I want to put the form in a specific place, right above some other elements that are loaded  by JS on the page. So, my plan was to wait until all of these elements had been loaded, then insert my form, but this works very inconsistently. </p>
  
  <p>The extension runs a content script, 'start.js' that adds the forms HTML and CSS to the page and appends another script, 'inject.js' to the document body. Here's the code:</p>
  
  <pre><code>addFormHTML();
  addFormStyle();
  addFormScript();
  
  function addFormHTML () {
      var form = document.createElement('form');
      var input = document.createElement('input');
      var btn = document.createElement('button');
      var searchIcon = document.createElement('i');
  
      form.setAttribute("class", "example");
      form.setAttribute("action", "/contact");
      form.setAttribute("method", "POST");
      btn.setAttribute("type", "submit");
      searchIcon.setAttribute("class", "fa fa-search");
      Object.assign(input, {
          type : "text",
          placeholder: "Search the stream",
          name : "search"
      });
  
      btn.appendChild(searchIcon);
      form.appendChild(input);
      form.appendChild(btn);
      document.body.appendChild(form);
  }
  function addFormStyle() {
      var styleLink = document.createElement("link");
      styleLink.setAttribute("rel", "stylesheet");
      styleLink.setAttribute("href", chrome.runtime.getURL('searchStyle.css'));
  
      var imgStyle = document.createElement("link");
      imgStyle.setAttribute("rel", "stylesheet");
      imgStyle.setAttribute("href", "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css");
  
      document.head.appendChild(styleLink);
      document.head.appendChild(imgStyle);
  }
  function addFormScript () {
      var inject = document.createElement('script');
      inject.src = chrome.runtime.getURL('inject.js');
      document.body.appendChild(inject);
      console.log(inject)
  
  }
  </code></pre>
  
  <p>inject.js listens for the window's 'load' event, then attempts to move the form element to the desired location. The problem is that even after all of this, it still says the element I want to insert the form before is null. Here is the code:</p>
  
  <pre><code>listenAndLoad();
  
  function listenAndLoad() { 
    window.addEventListener("load", function() {
      var form = document.getElementsByTagName("form")[0];
      var main = document.getElementById("ow43");
      main.insertBefore(form, main.children[1]);
    });
  }
  </code></pre>
  
  <p>And here is my manifest:</p>
  
  <pre><code>{
    "name": "Google Classroom Searchbar",
    "version": "1.0",
    "description": "A search bar for the google classroom assignments stream",
    "manifest_version": 2,
    "permissions": [
        "activeTab",
        "contextMenus",
        "tabs"
    ],
    "content_scripts": [
        {
          "run_at": "document_end",
          "matches": ["https://classroom.google.com/u/*/c/*"],
          "js": ["start.js"]
        }
    ],
    "web_accessible_resources": [
      "inject.js",
      "searchStyle.css"
    ]
  }
  </code></pre>
  
  <p>I have also tried simply running the inject.js code in start.js, but that does not work either. I'm using this on a google classroom page, on Chromium on Ubuntu.</p>