Modern JS and CSS are magical

This particular post goes over Javascript, but I'm also impressed with modern CSS.

Jeez. So easy. I grew up in the early web with Internet “Exploder” and Mozilla, Netscape etc, W3C setting standards for browser functionality, CSS, Mozilla trying their hardest to comply, and Microsoft and IE doing everything they can to stay as far away from them as they could, tell all developers that their way was the best way, to try to keep their monopoly.

Those days are over, and Microsoft lost. I never went back though, I knew good would prevail.

But nowadays, the Javascript that can run in the browser, with the DOM and with standard APIs, is the best it's ever been. We had some help with things like jQuery. But now I just write vanilla Javascript, and I've been able to do some pretty amazing things.

The problem is I can't really show it. But you can use your imagination from the code and from the very descriptive text I'm about to write :)

The use case: Imagine you have two columns of things. One column is very short, and the other is very long. And you want to keep the short column in view as you scroll the page. There are probably other ways to do this and maybe a library out there, but this is how I did it.

First, mark the column that you want to keep in view with a special class, like “scroll-lock”. Then, for each element with a “scroll-lock” class, create a new element with a “position-fixed” class, give it the width of the “scroll-lock” element, and give it a height of 100%, and give it an id of something like “scroll-lock-fixed-$idx” where idx is the index of the current “scroll-lock” element. I will only have one but I wanted to make it work if I had more than one. Insert that element as a sibling of the “scroll-lock” element, with scrollLock.parentNode.appendChild(fixed). Also give the parent element an id of something like “scroll-lock-unfixed-$idx”, to signal that this is where the content will go when it's not fixed.

Store these in a lookup like  lookup[contentId] = { top: y, fixedId: fixedId, unfixedId: unfixedId, fixed: false }

On window scroll, check through all of the lookup values, check the top against the window's “scrollY” property, and if it's in a position where it should swap to a fixed (or vice versa) and the .fixed property says it should swap, then just move it! This was so simple.

The fact that I assigned those IDs at runtime, but I'm still able to getElementById, I seem to think that that wouldn't work before? But maybe it would have. But also, there are a lot of events that are attached to the content, and moving it around back and forth (I've had spaz scrolling fits just to test), the event handlers stay put and work fine. Magic. Great job to everyone involved :) Javascript is decent. It's still weakly typed and runtime interpreted, so I don't prefer it, but for short useful scripts, it's good.

You can see the whole script at https://altarschedule.com/static/scroll-lock.js

Here's a sort of demo of it working, in static screenshots :) 

The left image shows the view at the top of the page, and the right image, scrolling hundreds of pixels, shows that the left column has stayed with the scroll, and the list has remained visible the whole time!

After trying it in production, I noticed an issue. So it's actually different from the screenshot. The height of the fixed div was set to 100%, and it was fixed. So the z-index puts it over the content. So, I start out with width as 0%, then when it gets added to the fixed div, I set it to 100%, and when it swaps back, set it back to 0%. All fixed :)  I'll probably make more updates because scrolling to the very bottom, the list in the left column doesn't stop scrolling at the bottom of the container. It goes through the bottom and off the page! Oh well. I'll look into it.

Happy coding!