Restoring a div innerHTML does not restore the style.display properly

My first time posting here - I sincerely apologize for the messy formatting - I promise to get that figured out for next time!

The DOM contains a div element that looks like this:

<div id="maincontent"></div>

Its contents get setup as the program executes.

Later in the program, the div element’s innerHTML is stored in a variable as a string:

docContentStored = document.getElementById("maincontent").innerHTML;
console.log("docContentStored type: ", typeof docContentStored);  
console.log("docContentStored:  ", docContentStored);
/* RESULT:

docContentStored type:  string
docContentStored:   <ol><li><button type="button" class="collapsible" style="display: block; background: rgb(50, 50, 50); color: rgb(0, 255, 25);"><p class="labelbuttons">Chapter One</p></button><div class="panelcontent" style="background: rgb(0, 0, 0); color: rgb(0, 255, 255); display: none;"><p>This little piggy went to market.</p><p>This little piggy stayed home.</p><p>This little piggy ate roast beef.</p><p>This little piggy ate none.</p><p>This little piggy cried wee-wee-wee-wee-wee-wee all the way home!</p></div></li><li><button type="button" class="collapsible active" style="display: block; background: rgb(50, 50, 50); color: rgb(0, 255, 25);"><p class="labelbuttons">Chapter Two</p></button><div class="panelcontent" style="background: rgb(0, 0, 0); color: rgb(0, 255, 255); display: block;"><p>One for the money.</p><p>Two to let go.</p><p>Three to get ready.</p><p>Four to GO!</p></div></li><li><button type="button" class="collapsible" style="display: block; background: rgb(50, 50, 50); color: rgb(0, 255, 25);"><p class="labelbuttons">Chapter Three</p></button><div class="panelcontent" style="background: rgb(0, 0, 0); color: rgb(0, 255, 255); display: none;"><p>And, there you have it.</p><p>The END.</p></div></li></ol>
*/

The list items contain a button element followed by a div element (class panelcontent).
The second list item contains a panelcontent div item where the style attribute includes “display: block”.

However, when I try to restore it, for some reason, that second list item panelcontent comes out with “display: none” and I have verified that the variable still shows “display: block”.

console.log("restored docContentStored:  ", docContentStored);
document.getElementById("maincontent").innerHTML = docContentStored;
console.log("received docContentStored: ", document.getElementById("maincontent"));
/* RESULT:

restored docContentStored:   <ol><li><button type="button" class="collapsible" style="display: block; background: rgb(50, 50, 50); color: rgb(0, 255, 25);"><p class="labelbuttons">Chapter One</p></button><div class="panelcontent" style="background: rgb(0, 0, 0); color: rgb(0, 255, 255); display: none;"><p>This little piggy went to market.</p><p>This little piggy stayed home.</p><p>This little piggy ate roast beef.</p><p>This little piggy ate none.</p><p>This little piggy cried wee-wee-wee-wee-wee-wee all the way home!</p></div></li><li><button type="button" class="collapsible active" style="display: block; background: rgb(50, 50, 50); color: rgb(0, 255, 25);"><p class="labelbuttons">Chapter Two</p></button><div class="panelcontent" style="background: rgb(0, 0, 0); color: rgb(0, 255, 255); display: block;"><p>One for the money.</p><p>Two to let go.</p><p>Three to get ready.</p><p>Four to GO!</p></div></li><li><button type="button" class="collapsible" style="display: block; background: rgb(50, 50, 50); color: rgb(0, 255, 25);"><p class="labelbuttons">Chapter Three</p></button><div class="panelcontent" style="background: rgb(0, 0, 0); color: rgb(0, 255, 255); display: none;"><p>And, there you have it.</p><p>The END.</p></div></li></ol>
		
received docContentStored:  
		<div id="maincontent">
			<ol>
				<li>
					<button type="button" class="collapsible active" style="display: block; background: rgb(50, 50, 50); color: rgb(0, 255, 25);">
						<p class="labelbuttons">Chapter One</p>
					</button>
					<div class="panelcontent" style="background: rgb(0, 0, 0); color: rgb(0, 255, 255); display: none;">
						<p>This little piggy went to market.</p>
						<p>This little piggy stayed home.</p>
						<p>This little piggy ate roast beef.</p>
						<p>This little piggy ate none.</p>
						<p>This little piggy cried wee-wee-wee-wee-wee-wee all the way home!</p>
					</div>
				</li>
				<li>
					<button type="button" class="collapsible active" style="display: block; background: rgb(50, 50, 50); color: rgb(0, 255, 25);">
						<p class="labelbuttons">Chapter Two</p>
					</button>
					<div class="panelcontent" style="background: rgb(0, 0, 0); color: rgb(0, 255, 255); display: none;">
						<p>One for the money.</p>
						<p>Two to let go.</p><p>Three to get ready.</p>
						<p>Four to GO!</p>
					</div>
				</li>
				<li>
					<button type="button" class="collapsible active" style="display: block; background: rgb(50, 50, 50); color: rgb(0, 255, 25);">
						<p class="labelbuttons">Chapter Three</p>
					</button>
					<div class="panelcontent" style="background: rgb(0, 0, 0); color: rgb(0, 255, 255); display: none;">
						<p>And, there you have it.</p>
						<p>The END.</p>
					</div>
				</li>
			</ol>
		</div>
*/


So while the docContentStored variable still shows the panelcontent of the second with “display: block”, when assigned to the innerHTML of the maincontent div element, it comes out with “display: none” and I do not know why.
I have tried removing the linefeeds with .replace(/\r|\n|\r\n/, “”) and I have tried .trim(), but the result is the same.

The final result will have many tags and some will have the display set to none while others set to block and I need the restore of it to match what was backed up. How do I accomplish this?

have you tried assigning classes and having the styling in a separate css file?

The CSS is in a style tag in the same file. I have not tried putting it in a separate file. But in this case, the style has to be udpated through JS when a user clicks the item, which switches the display value between none and block so even if it were in a separate file, the display would still need to be in a style attribute.

no, it wouldn’t. if you have an hidden class that you add or remove, that can be the thing that hide or show your elements

Are you suggesting that I modify the display between none and block by adding/removing css class values instead of modifying the style attribute? (assuming this is what you mean, I will give this a try)

yes, that’s what I mean

Because the code for the actual app is a little long, I chose to make a test page for this concept. It seems to work with one minor nuance upon restoring the element from a variable.

The test page consists of 6 buttons:

Current Date: generates the display value, which is the current date and displays it
Show: displays the date value (by setting the CSS class)
Hide: hides the date value (by setting the CSS class)
Save: stores the innerHTML of the maincontents div element in a variable
Clear: clears the date value from the contents div
Recall: restores the innerHTML of the maincontents div element, which includes the content div element with the previously stored date

Upon restoring it (the Recall button), the hide and show buttons were not working until I added the last line of the recall function to reset the content variable (which points to the contents div in the DOM). I guess when you restore it, Javascript thinks it was overwritten and can no longer access it.

Otherwise, using the CSS classList as you suggested is working to hide and show the div contents and it can be saved, cleared and restored and all is working with the restored values, unlike the use of the style attribute, which I will be removing from all of my code.

Just for completeness, here is the test page where I tested this:

<!DOCTYPE html>

<html>
	<head>
			<title>Class Test Page</title>
	</head>

<style>
	.active {
		display: block;
	}
	.hidden {
		display: none;
	}
	.element {
		color: #00FFFF;
		background: #661111;
		font-size: 3em;
	}
</style>

<body>
	<h1>Test the display with block or none through the classList</h1>


	<button id="current" onClick="current()">Current Date</button>
	<button id="show" onClick="show()">show</button>
	<button id="hide" onClick="hide()">hide</button>
	<button id="save" onClick="save()">save</button>
	<button id="clear" onClick="clearval()">clear</button>
	<button id="recall" onClick="recall()">recall</button>


	<div id="maincontents">
		<div id="content" class="element"></div>
	</div>

</body>

<script>

	let content = document.getElementsByClassName("element");
	let saved = "";


	function current() {
		let d = new Date();
		content[0].innerHTML = "<p>" + d + "</p>";
		show();
		console.log("Date: ", d);
	}

	function show() {
		content[0].classList.add("active");
		content[0].classList.remove("hidden");
	}

	function hide() {
		content[0].classList.remove("active");
		content[0].classList.add("hidden");
	}

	function save() {
		saved = document.getElementById("maincontents").innerHTML;
		console.log("Saved: ", saved);
		console.log("Saved type: ", typeof saved);
	}

	function clearval() {
		content[0].innerHTML = "";
		hide();
	}

	function recall() {
		console.log("Recalling: ", saved);
		document.getElementById("maincontents").innerHTML = saved;
		console.log("Recalled: ", document.getElementById("maincontents"));
		
		// must refresh the content variable since it was overwritten, or else the hide() and show() won't work.
		content = document.getElementsByClassName("element");
		// the alternative to this refresh is for any functions that modify it, they must access it from the DOM instead of from a stored variable
	}


</script>

</html>

Note: I used getElementsByClassName instead of getElementById because in my app, there will be a list of items grouped by a CSS class but this could have been done with either.

Thank you.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.