Reputation: 101
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
Upvotes: 0
Views: 12