Learning JavaScript before it learns you

Hole shite, it werks! Thank you very, very much!
Now I will need to test if this will work for multiple containers, but this is big step forward.

<script>
	// OVERLAY TOGGLE
	function toggleOverlay(overlay) {
	// toggle overlay on div with "overlay" class
		overlay.currentTarget.nextElementSibling.classList.toggle("overlay-show");
	// RESPONSIVE IMAGE LAYOUT
		// get all text wrappers - there is multiple of them on the page, so this might be restructured 
		const textWrapper = Array.from(document.getElementsByClassName('text-box'));
		// I don't know if this should be done with applying the function for each or it would be better to pick one item from an array, as there will be only one text box visible simultaneously.
		textWrapper.forEach(toggleHeight);
		// toggle a class that will be used for text-box height measurement
		function toggleHeight(text) {
			text.classList.toggle("read-height");
		}
		start();
	}
	// IMAGE RESIZE
	window.onresize = start;
	function start() {
		// get text-box element with a 'read-height' class
		let textBox = document.querySelector('.read-height');
		// get text-box height
		let textHeight = document.querySelector('.read-height').offsetHeight;
		// calculate image-box height
		let imageHeight = window.innerHeight - textHeight;
		// get image-box element
		// again I'm not sure if 'forEach' is better here and not picking one element from ana array - I include code for the second option in comments below
		//~ let imageBox = document.getElementsByClassName('overlay-img-box');
		let imageBox = Array.from(document.getElementsByClassName('image-box'));

		if (textBox === null) {
			return	
		} else {
			//~ for (var i = 0; i < imageBox.length; i++) {
			//~ imageBox[i].style.height = imageHeight + "px";
			//~ }
			imageBox.forEach(resize)
			function resize(element) {
				element.style.height = imageHeight + "px";
			}
		}
	}
</script>

I figured it out and even simplified the code a little.
This code can work on arbitrary number of containers as long as they have individual buttons for opening an overlay and share DOM structure.

This is a partial solution for a problem with responsive layout driven by text amount discussed here:

	// OVERLAY TOGGLE
	function toggleOverlay(overlay) {
	// toggle overlay on div with "overlay" class
		overlay.currentTarget.nextElementSibling.classList.toggle("over-show");
		// RESPONSIVE IMAGE LAYOUT
		// get text wrapper and toggle a temporary class
		overlay.currentTarget.nextElementSibling.firstElementChild.classList.toggle("read-height");
		// call image resize function
		resize();
	}
	// RESIZE IMAGE
	window.onresize = resize;
	function resize() {
		// get text div
		let textBox = document.querySelector('.read-height');
		// get text div height
		let textHeight = document.querySelector('.read-height').offsetHeight;
		// calculate overlay image height
		let imageHeight = window.innerHeight - textHeight;
		// get image div
		let imageBox = document.querySelector('.over-show').lastElementChild;
		// resize image div
		if (textBox === null) {
			return	
		} else {
			imageBox.style.height = imageHeight + "px";
		}
	}
2 Likes

I have another problem to solve.
I made a function that is performing a basic toggle with if else but now I want to add another if else inside one of the main branches. But I can’t get imageShow function to work. The console is not returning anything when running this code and I don’t know what is wrong here.

I know that this is probably not very optimal way to do it, but the main function is doing a lot of other work in real code and restructuring it would be a major work for me considering that it is attached to over 150 DOM elements across entire page. I know how to make it working, but splitting the toggle would require duplicating a lot of code.

<style>
.hide {
	display: none;
}
.show {
	display: block;
}
</style>
<div id="image" class="hide">IMAGE UNHIDE</div>

<div class="wrapper">
	<div class="button" onclick="toggleOverlay(event)">CLICK RED</div>
	<div class="hide red">RED</div>
</div>
<div class="wrapper">
	<div class="button" onclick="toggleOverlay(event)">CLICK BLUE</div>
	<div class="hide blue">BLUE</div>
</div>

<script>
	const img = document.getElementById("image");

	function toggleOverlay(item) {

		let overlay = item.currentTarget.nextElementSibling;

		if (overlay.classList.contains("hide")){

			overlay.classList.remove("hide");
			overlay.classList.add("show");

			function imageShow() {
				if (overlay.classList.contains("red")) {
					return
				} else {
					img.classList.remove("hide");
					img.classList.add("show");
				}
			}

		}

		else if (overlay.classList.contains("show")){

			overlay.classList.remove("show");
			overlay.classList.add("hide");

			img.classList.add("hide");
		}
	}
</script>

You never call imageShow function. Any particular reason it’s a function to begin with? Anyways imageShow(); somewhere below the function deffinition. The place where you put it it’s only gonna be available inside the if and below the function deffinition.

Also console.log is your friend in times of need. ^^

Happily I was able to figure it out. It was the same mistake I made previously lol. But, thanks nonetheless!

Why is “.show” not the default behavior? Why use a separate class for that?

It would be easier to just toggle the .hide class.

So, I don’t know if you really don’t but looking at some code above it seems to me you might not know that you can negate conditions with !.

You don’t have to do that whole if(…) return; else thing.

if (!overlay.classList.contains("red")) {
.
.
}

or

if (overlay.classList.contains("red") === false) {
.
.
}

or

if (overlay.classList.contains("red") !== true) {
.
.
}

I had that impression when looking at it before but thought… Nonono, it can’t be. Maybe it can. :joy:

1 Like

You are right.

Well, lets say I didn’t exactly RTFM lol. I’m just learning stuff along the way. It’s easier that way, because I can have effects with absolutely minimum effort.

I’m 100% sure this thread is making so much people cringe, but I don’t care, I don’t care.

1 Like

Hey man its fine. As you progress through your journey you’ll realize that the way you think about solving problems will start to change.

A fair warning: there is no going back. The effects are permanent :smiley:

1 Like

Cut to me looking at the honeycomb structure inside a beehive thinking “hey, it’s recursive…”