Week 6: Sliders & Animated Menus

To Do This Week:

Assignments:

Work on your Clickable Page website.

Read (Optional!): Chapters from Eloquent JavaScript:


Slider/Menu Site (5%)

NOW DUE Thursday Oct 14th

No AI-generated code. You may use AI or web searches to look up documentation, syntax, or examples, but the code and design decisions for this project must be your own.

In class, we will build a simple slider template together and work through the JavaScript logic step by step. Your assignment is not to simply restyle that template. Use what you learned from the class example to design your own slider-based webpage with your own content, visual approach, and interface.

Your slider might present photography, artwork, products, places, characters, a sequence, a visual story, portfolio work, or another collection of content. Think about how the slider itself can become part of the design. The more you make the interface visually distinctive and appropriate to your content, the better.

JavaScript Goals

Be sure to include your detailed logic steps, commented out at the beginning of your script:

Your JavaScript should demonstrate that you understand how a slider works rather than simply reproducing code from the class example. You should be able to explain how your variables, indexes, functions, conditions, and event listeners work together.

Design & Content

Create your own visual design rather than reproducing the appearance of the generic class demo. Consider the relationship between the content, layout, typography, navigation, controls, and movement.

You might experiment with:

Do not feel that your project has to look like a conventional image gallery. The class example gives you the underlying logic. Your job is to explore what else you can make with it.

Minimum Requirements

Slider Design Inspiration

Before designing your slider, look at several examples. Pay attention to more than the animation: look at the size and position of images, typography, controls, captions, navigation, spacing, and how the slider fits into the overall page.

Look for ideas you can simplify and recreate using the JavaScript techniques we have covered rather than trying to reproduce a complex professional slider.

Module Notes

Slider Project

A slider has two basic parts: a list of slides and a number that keeps track of the current slide.

const slides = document.querySelectorAll(".slide");
let currentIndex = 0;

The selected .slide elements are numbered by index, starting at 0:

slides[0]   // first slide
slides[1]   // second slide
slides[2]   // third slide

Next increases currentIndex, Previous decreases it, and the slider updates to show that position.

Designing for the User

Before you write code, sketch your idea and answer these questions:

Content Ideas

Pick a subject with real images and a reason to be seen as a sequence. Suggestions:

Whatever you choose, gather real images first. Placeholder gray boxes make it impossible to judge the experience.

In-class Exercise:

Slider Starter (HTML + CSS provided — you write the JS)

The starter file uses Picsum Photos - as in Lorem Picsum - for easy access to images as you test your gallery/sliders.


The Core Slider Logic

This example uses Flexbox to place the slides in one horizontal row. JavaScript does not hide and show individual slides. Instead, it changes the position of the entire row with transform: translateX().

1. Set up state

State is just the variables that describe "where we are right now."

When JavaScript selects multiple elements with the same class, such as .slide, the results act like a list with numbered positions. These positions are called indexes, and the first item starts at index 0.

const slides = document.querySelectorAll(".slide");
const slidesContainer = document.querySelector(".slides");
let currentIndex = 0;

If there are three slides, their indexes are 0, 1, and 2. currentIndex keeps track of which slide should be visible.


2. Move the slide row to the current slide

The slides sit next to each other in one long Flexbox row. To show a different slide, move that entire row horizontally. Each slide is 100% of the slider width.

function showSlide() {
  slidesContainer.style.transform =
    `translateX(-${currentIndex * 100}%)`;
}

At index 0 the row moves 0%. At index 1 it moves -100%. At index 2 it moves -200%.

To reverse the direction: reverse the Flexbox row so the next slides sit to the left:

.slides {
  display: flex;
  flex-direction: row-reverse;
  transition: transform 0.5s ease;
}

Then remove the minus sign so the row moves to the right:

slidesContainer.style.transform =
  `translateX(${currentIndex * 100}%)`;

3. Next and Previous change the index

function nextSlide() {
  currentIndex++;
  if (currentIndex >= slides.length) {
    currentIndex = 0;
  }
  showSlide();
}

function prevSlide() {
  currentIndex--;
  if (currentIndex < 0) {
    currentIndex = slides.length - 1;
  }
  showSlide();
}

4. Set up the buttons for navigation

document.getElementById("nextBtn")
  .addEventListener("click", nextSlide);

document.getElementById("prevBtn")
  .addEventListener("click", prevSlide);

5. CSS creates the sliding animation

.slider {
  overflow: hidden;
}

.slides {
  display: flex;
  transition: transform 0.5s ease;
}

.slide {
  min-width: 100%;
}

display: flex places all slides side by side. overflow: hidden hides the slides outside the visible frame. JavaScript changes the transform, while the CSS transition makes that movement animate smoothly.


Slider Dots

Slider dots are small circular controls that show how many slides are in a slider and which slide is currently active. Each dot usually represents one slide.

The dots can be made from small button elements. CSS gives each button an equal width and height, then uses border-radius: 50% to make it circular.

<div class="dots">
  <button class="dot active"></button>
  <button class="dot"></button>
  <button class="dot"></button>
</div>
.dot {
  width: 12px;
  height: 12px;
  border: none;
  border-radius: 50%;
  background: #999;
}

.dot.active {
  background: #222;
}

JavaScript can then move the active class from one dot to another as the slider changes. The same dots can also be made clickable so that each one jumps directly to its corresponding slide.

Thursday Workshop : DOM Element Properties and Methods

W3Schools Resource: HTML DOM Event Properties

W3Schools Resource: HTML Dom Elements and Methods

HTML elements, the `document`, and the `console` are all objects in JavaScript. Objects can have properties, which store information or values about the object, and methods, which are actions attached to the object. Once JavaScript has selected an object, like an HTML element, you can get information about it using properties and make it do something using methods.


.offsetWidth & .offsetHeight

offsetWidth gives you the current rendered width of an element in pixels, and offsetHeight gives you its current rendered height. These are useful when you want JavaScript to make calculations based on the actual size of something on the page.

The word offset refers to the element’s actual box in the page layout, so these values include its content, padding, and border rather than just the CSS width or height setting.

const width = main.offsetWidth;
const height = main.offsetHeight;

Unlike a CSS rule such as width: 90%, offsetWidth gives JavaScript the resulting pixel measurement after the browser has laid out the page.

In the Clickable Page demo, offsetWidth is used to calculate where the green panel should move:

const mainCenter = main.offsetWidth / 2;

const panelCenter =
    container.offsetWidth - panel2.offsetWidth / 2;

const distance = mainCenter - panelCenter;

panel2.style.transform =
    "translateX(" + distance + "px)";

This lets the movement depend on the actual size of the page instead of using a fixed number of pixels.


.insertAdjacentHTML()

insertAdjacentHTML() inserts new HTML next to or inside an existing element. It is useful when you want to add several HTML elements at once without first creating each one with createElement().

main.insertAdjacentHTML(
    "beforeend",
    "<h2>New Section</h2><p>Some new content.</p>"
);

The first argument tells JavaScript where to insert the new HTML. Common choices are "beforeend" to add it inside the element at the end, and "afterbegin" to add it inside at the beginning.


.classList.toggle()

classList gives JavaScript access to an element's CSS classes. The toggle() method adds a class if it is missing and removes it if it is already there.

document.body.classList.toggle("dark");

You can also add or remove classes directly:

element.classList.add("active");
element.classList.remove("active");

This is useful when you want JavaScript to trigger CSS styles or animations.


.appendChild()

appendChild() places one HTML element inside another element. It adds it at the end of the existing content.

const p = document.createElement("p");

p.textContent = "Here is some new text.";

main.appendChild(p);

This is useful when a click should add new text, an image, a button, or another element to the page.


.remove()

The remove() method removes an element from the page.

const panel = document.getElementById("panel1");

panel.remove();

For example, clicking an object could make it disappear:

panel1.addEventListener("click", function () {
    panel1.remove();
});

.classList.contains()

classList.contains() checks whether an element currently has a particular CSS class. It returns either true or false.

if (panel1.classList.contains("open")) {
    console.log("The panel is open");
}

This is useful when JavaScript needs to make a decision based on the current state of an element.


.setAttribute()

setAttribute() changes or adds an HTML attribute to an element.

const image = document.querySelector("img");

image.setAttribute("src", "new-image.jpg");
image.setAttribute("alt", "A new image");

This is useful for changing things such as image sources, links, IDs, titles, or other HTML attributes after a click.


.scrollTop

scrollTop tells you how far an element has been scrolled vertically, in pixels. You can also change it to move the scroll position.

console.log(main.scrollTop);

main.scrollTop = 0;

This can be useful if part of the page has its own scrollbar and you want a click to return that area to the top or move it to a new position.

button.addEventListener("click", function () {
    main.scrollTop = 200;
});

scrollTop is also how an infinite scroll knows when to add more content. By checking scrollTop every time the area scrolls (event "scroll"), you can tell when the viewer is getting close to the bottom. Add scrollTop to clientHeight (the height of the visible area) and compare the result to scrollHeight (the height of all the content, including the hidden part). When the two are nearly equal, the viewer has reached the end, so you can create new elements and add them to the bottom with appendChild(). The content gets taller, and the viewer can keep scrolling.

let nextLoad = 500;

main.addEventListener("scroll", function () {
    if (main.scrollTop > nextLoad) {
        const item = document.createElement("div");
        item.textContent = "New content";
        main.appendChild(item);

        nextLoad = nextLoad + 500;
    }
});