0

Ive been trying to figure this out for months and searched all over and cant find any solution. I have an index.html that is loading a separate file(../html-block/artillery-nav.html) containing HTML for the Navbar. This is done using a javascript function declared in the . This works and loads the HTML into the document, but then want to perform some javascript on this new html (the navbar) such as adding an eventListener and toggling DOM element class on/off. When I try to do this I get an error.

Uncaught TypeError: togBtn is null

Its as if the new html doesnt exist. Does Anybody know why this doesnt work and how to get it working?

<!--****************************
 //
 //     index.html
 //
 ********************************-->
<head>    
    <script src="../Scripts/include-html-code.js" type="text/javascript"></script>
</head>
    
<body>
        <div INCLUDE-HTML="../html-block/artillery-nav.html">
            <script>
                includeHTML();
            </script>
        
            <script type="text/javascript">
            
                const togBtn = document.getElementById('menuBtn');
                togBtn.addEventListener(click,toggleHamBtn)

                function toggleHamBtn(){
                   togBtn.classList.toggle('open');
                }
            </script>
       </div>
    </body>
  </html>  
 <!--*******************************************
 //  this is the html loaded into index.html
 //     that Im trying to run javascript on 
 //
 //     ../html-block/artillery-nav.html
 //
 ********************************************--> 
          <div id="hamburgerTitleFlex">
             <div id="navbarTitle"></div>

             <button id="menuBtn" class="hamburger" type="button">
                 <span class="hamburger-top"></span>
                 <span class="hamburger-middle"></span>
                 <span class="hamburger-bottom"></span>
             </button>
             
         </div>

So in a nutshell, In the head section I include a Javascript file that contains one function, which is to load another file (containing the navbar) into the DOM and then using inline javascript in the main document flow that adds event listeners and functionality to a button.

The Javascript Code for loading the external html file works and is as follows;

function includeHTML() {
  var z, i, elmnt, file, xhttp;
  /* Loop through a collection of all HTML elements: */
  z = document.getElementsByTagName("*");
  for (i = 0; i < z.length; i++) {
    elmnt = z[i];
    /*search for elements with a certain atrribute:*/

    file = elmnt.getAttribute("INCLUDE-HTML");

    if (file) {
      /* Make an HTTP request using the attribute value as the file name: */
      xhttp = new XMLHttpRequest();
      xhttp.onreadystatechange = function () {
        if (this.readyState == 4) {
          if (this.status == 200) {
            elmnt.innerHTML = this.responseText;
          }
          if (this.status == 404) {
            elmnt.innerHTML = "Page not found.";
          }
          /* Remove the attribute, and call this function once more: */
          elmnt.removeAttribute("INCLUDE-HTML");
          includeHTML();
        }
      }
      xhttp.open("GET", file, true);
      xhttp.send();
      /* Exit the function: */
      return(true);
    }
  }
  return(true)
}

I also tried doing this with a promise but that didnt work either.The expected result is that the button 'idMenu' has the class 'open' toggled on/off . The 'open' class is defined in the file artillery-nav.html that is loaded.

         
<div class="positionCenterFixed" id="fixedNav" INCLUDE-HTML="../html-block/artillery-nav.html">
     <script type="text/javascript">
         let p = new Promise((resolve, reject) => {
             if (includeHTML()) {
                 console.log('*** In promise ***: menu loaded ')
                 resolve('success')
             } else {
                 reject('fail')
             }
         });

         p.then(() => {
              console.log('*** In Then *** : Promise Success');
              const togBtn = document.getElementById('menuBtn');
              togBtn.addEventListener(click, toggleHamBtn);

              function toggleHamBtn() {
                  togBtn.classList.toggle('open');
              }
        }).catch(()=> {
          console.log('*** In Catch *** : Promise Failed')
        })
        </script>

    </div>

Console Log outputs all conditions;

In promise ***: menu loaded

In Then *** : Promise Success

In Catch *** : Promise Failed

Lelio Faieta
  • 6,457
  • 7
  • 40
  • 74
Artillery
  • 11
  • 1
  • Regarding the linked duplicate, you have to [scroll down a few answers](https://stackoverflow.com/a/27373951/328193) to find a solution which isn't based on jQuery. Which personally I think should be moved to the top answer, but history being what it is certain frameworks were *very* popular for a *very* long time. But essentially what's happening is you're trying to add an event handler to an element that isn't on the page *yet*. You can use event delegation to add the handler to an ancestor element instead. – David Apr 14 '23 at 12:23
  • (And for any future questions you might want to ask: Please stop misusing the quote formatting. That is for when you actually quote someone or something - and _not_ just to make your post "look more interesting".) – CBroe Apr 14 '23 at 12:27
  • CBroe. Its not to make my post look more interesting. Its because Ive just spent three hours having stack overflow reject my question because it said it wasnt formatted properly. You may want to Lay off the adenol – Artillery Apr 14 '23 at 12:32

0 Answers0