Skip to main content
March 23, 2026Dan Rodney/10 min read

For Loops: Free JavaScript Tutorial

Master JavaScript For Loops and Interactive Web Components

What You'll Build

Interactive Product Chooser

Create a dynamic interface where users can click color swatches to change product images and visual states.

Efficient Event Handling

Use for loops to attach event listeners to multiple elements without repetitive code.

Dynamic Visual Feedback

Implement selected states and hover effects that respond to user interactions.

Topics Covered in This JavaScript Tutorial:

Master the fundamentals of JavaScript iteration: creating for loops, implementing dynamic menu systems, leveraging the 'this' keyword for context-aware programming, and building interactive product selection interfaces that respond to user actions.

Exercise Preview

preview loops

Tutorial Structure

1

Basic For Loop

Learn the syntax and structure by creating a simple counting loop in the browser console

2

DOM Manipulation

Apply for loops to select multiple elements and attach event listeners programmatically

3

Dynamic Interaction

Use the 'this' keyword to create context-aware event handlers for each element

Exercise Overview

In this comprehensive exercise, you'll discover how for loops serve as one of JavaScript's most powerful tools for eliminating code repetition and creating dynamic, scalable applications. Whether you're building e-commerce interfaces, data visualization dashboards, or interactive web applications, mastering loops is essential for writing efficient, maintainable code that scales with your project's complexity.

Getting Started

Before diving into loop construction, let's establish our development environment and examine the foundational files that will support our learning objectives.

  1. Navigate to the Loops folder located in Desktop > Class Files > JavaScript Class. Open this entire folder in your code editor—modern editors like Visual Studio Code, WebStorm, or Sublime Text provide enhanced IntelliSense and debugging capabilities when working with project folders rather than individual files.
  2. Within your code editor, open index.html from the Loops folder. This file serves as our testing ground for fundamental loop concepts.
  3. Preview index.html in Chrome (recommended for its superior DevTools debugging capabilities).

    You'll notice this appears as a blank page—this is intentional. We're focusing on JavaScript logic rather than visual presentation, utilizing Chrome's Console for immediate feedback and debugging. This approach mirrors real-world development workflows where backend logic is often tested independently of UI components.

  4. Keep this browser tab open throughout the exercise for quick reloading and testing—rapid iteration is key to effective JavaScript development.

Development Environment Setup

This tutorial uses Visual Studio Code and Chrome DevTools. You'll work with two separate folders: 'Loops' for basic concepts and 'Product-Chooser-Loops' for the practical application.

Creating a for Loop

Now we'll construct a for loop from the ground up, understanding each component's role in controlling program flow and execution.

  1. We've pre-configured a script tag for your convenience. Begin constructing your for loop by adding the fundamental structure:

    <script>
       for() {
    
       }
    </script>

    Understanding the anatomy: The parentheses () house three critical control statements that govern loop execution, while the curly braces {} contain the code block that executes on each iteration. This separation of control logic from execution logic is a hallmark of clean, readable programming.

  2. Let's implement a practical counting scenario from 0 to 10. First, initialize a counter variable to track iteration progress:

    for(let i = 0;) {
    
    }

    The variable name i follows decades of programming convention (derived from "index" or "iterator"). While you could use any variable name, adhering to established conventions improves code readability for team collaboration. Note that we're using let for block-scoped variable declaration—a modern JavaScript best practice that prevents common scoping errors.

  3. Every loop iteration requires a condition evaluation to determine whether execution should continue. This condition acts as our loop's safety mechanism, preventing infinite execution:

    for(let i = 0; i < 11;) {

    When this condition evaluates to true, the loop body executes. When false, the loop terminates and program flow continues to the next statement. This boolean logic forms the foundation of all conditional programming.

  4. Finally, implement the increment operation to modify our counter variable after each iteration:

    for(let i = 0; i < 11; i++) {

    The i++ operator is shorthand for incrementing by one. Alternative expressions include i = i + 1 or i += 1—all achieve identical results, but i++ represents the most concise and widely recognized approach in professional codebases.

  5. Now define the execution logic—what happens during each loop iteration:

    for(let i = 0; i < 11; i++) {
       console.log('The value of i is: ' + i);
    }

    The console.log() method outputs directly to the browser's developer console, providing immediate feedback for debugging and development purposes.

  6. Save your file and reload the Chrome browser tab.
  7. Access the Console using Cmd–Opt–J (Mac) or Ctrl–Shift–J (Windows). Familiarize yourself with these shortcuts—they're essential for efficient JavaScript debugging.
  8. Observe that the loop executed immediately upon page load, displaying the incremental values from 0 through 10. This demonstrates the loop's automatic execution flow and successful condition evaluation.
  9. Close this browser window as we transition to more advanced loop applications.

For Loop Components

Initialization

Set up a counter variable, typically 'i', with a starting value like 0.

Condition

Define when the loop should continue running, such as 'i < 11' for counting to 10.

Increment

Specify how the counter changes each iteration, commonly 'i++' to increase by 1.

Alternative Increment Syntax

Instead of 'i++', you can use 'i = i + 1' or 'i += 1' to achieve the same result, but 'i++' is the most concise and commonly used.

Using a for Loop in the Product Chooser

Having mastered basic loop construction, we'll now apply these concepts to a real-world scenario: creating an interactive product selection interface. This exercise demonstrates how loops enable scalable event handling across multiple DOM elements.

  1. Close any currently open files in your code editor to maintain workspace organization.
  2. Navigate to the Product-Chooser-Loops folder within Desktop > Class Files > JavaScript Class. Open this entire folder in your code editor for comprehensive project access.
  3. Open product.html from the Product-Chooser-Loops folder in your editor.
  4. Preview product.html in Chrome to understand the current functionality.

    This interface represents a partially completed product customization feature—currently, only the red button triggers image changes and visual feedback. In professional e-commerce development, such interactive features significantly impact user engagement and conversion rates. Our goal is to extend this functionality across all color options using efficient loop-based programming.

  5. Return to your code editor and modify the variable name to reflect its new plural nature:

    let colorButtons = document.getElementById('red');

    Proper variable naming is crucial for maintainable code—plural names immediately signal to other developers (and future you) that a variable contains multiple elements.

  6. Replace the single-element selection method with one that captures multiple elements:

    let colorButtons = document.querySelectorAll('red');

    The querySelectorAll() method represents modern DOM manipulation, accepting CSS selector syntax and returning a NodeList of all matching elements. This approach is more versatile than getElementById(), which targets only single elements with unique IDs.

  7. Target all buttons sharing the common swatch class:

    let colorButtons = document.querySelectorAll('.swatch');

    This CSS selector syntax (.swatch) targets every element with the "swatch" class, providing the scalability we need for multiple product options.

  8. Implement a loop structure to iterate through our button collection, applying event listeners to each element:

    }
       for(i = 0; i < colorButtons.length; i++) {
          colorButton.addEventListener('click', changeColor);
       }
    </script>

    The colorButtons.length property dynamically determines our loop's upper bound, making this code automatically adaptable if we add or remove color options later—a key principle in scalable application design.

  9. Update the event listener assignment to target the specific button in each iteration:

    for(i = 0; i < colorButtons.length; i++) {
       colorButtons[i].addEventListener('click', changeColor);
    }

    Array bracket notation [i] accesses the specific element at index i during each loop iteration, effectively attaching our event listener to every button in the collection.

  10. Save your file and reload the Chrome browser tab.

    • Test the yellow button—it now triggers image changes (though to the incorrect red image, which we'll resolve next).
    • Reload the page and test the blue button to confirm functionality.
    • We've successfully enabled all buttons to trigger changes, demonstrating the power of loop-based event handling. Our next steps involve implementing correct image mapping and visual state management.

getElementById vs querySelectorAll

FeaturegetElementByIdquerySelectorAll
Return TypeSingle ElementArray of Elements
Selector FormatElement IDCSS Selector
Use CaseTarget One ElementTarget Multiple Elements
Recommended: Use querySelectorAll when you need to apply the same functionality to multiple elements with shared characteristics.

Targeting the Current Element

To create a truly dynamic interface, we must identify which specific element triggered each event, then extract its unique properties to determine appropriate responses. This requires understanding JavaScript's context-sensitive this keyword.

  1. Within your changeColor() function, add diagnostic logging to examine the clicked element:

    function changeColor() {
       console.log(this);
       productPhoto.src = 'img/chair-red.jpg';
       colorButton.classList.add('selected');
    Understanding Array Indexing

    When using querySelectorAll, access specific elements with bracket notation like 'colorButtons[i]' where 'i' represents the current loop iteration.

    Debugging Steps

    0/3

The JavaScript Keyword This

The this keyword in JavaScript operates similarly to natural language but requires careful consideration of execution context. In the global scope, this references the window object, but within event handlers, this refers to the DOM element that triggered the event. This context-sensitive behavior enables elegant, reusable code patterns. For comprehensive coverage of this binding rules and advanced use cases, reference the MDN documentation on JavaScript's this keyword—understanding these concepts is essential for professional JavaScript development.

  • Temporarily disable the problematic line to prevent execution errors:

    function changeColor() {
       console.log(this);
       productPhoto.src = 'img/chair-red.jpg';
       // colorButton.classList.add('selected');

    Commenting out code during development is a standard debugging practice—it allows you to isolate and resolve issues incrementally.

  • Save the file and reload your browser page.
  • Open Chrome's Console using Cmd–Opt–J (Mac) or Ctrl–Shift–J (Windows).

    Click each button and observe the console output—you'll see the actual DOM element being logged for each click. This demonstrates how this provides access to the specific element that triggered each event. Notice that each button element contains an ID property corresponding to its color—this will be crucial for our image mapping logic.

  • Refine your logging to extract the specific ID attribute:

    console.log(this.id);

    Property access using dot notation is a fundamental JavaScript operation, allowing us to extract specific attributes from DOM elements.

  • Save and reload, then test each button in the console.

    The console now displays the color name for each clicked button, confirming our ability to programmatically access element-specific data.

  • Implement dynamic image path construction using the extracted color ID:

    function changeColor() {
       console.log(this.id);
       productPhoto.src = 'img/chair-' + this.id + '.jpg';

    String concatenation builds file paths dynamically, eliminating the need for separate functions or conditional statements for each color option. This approach scales effortlessly as you add new product variations.

  • Save and reload to test the functionality.

    Each button now correctly updates the product image to its corresponding color variant—a significant improvement in user experience and code efficiency.

  • Restore the visual feedback functionality using the context-aware this reference:

    function changeColor() {
       console.log(this.id);
       productPhoto.src = 'img/chair-' + this.id + '.jpg';
       this.classList.add('selected');
    }

    The classList.add() method provides a clean, modern approach to dynamic CSS class management, superior to direct className manipulation.

  • Save and reload for testing.

    • Click the blue button to verify correct image display and border application.

    • Click the yellow button and observe that while it functions correctly, the previous button retains its selected state.

      This reveals the need for state management—clearing previous selections before applying new ones. We'll implement a loop-based solution to reset all button states before applying the new selection.

  • Add a reset loop to clear all button selections before applying the new state:

    function changeColor() {
       console.log(this.id);
       productPhoto.src = 'img/chair-' + this.id + '.jpg';
    
       for(i = 0; i < colorButtons.length; i++) {
          colorButtons[i].classList.remove('selected');
       }
       this.classList.add('selected');
    }

    This pattern—clearing all states before setting a new one—is common in UI development and ensures consistent visual feedback regardless of previous user interactions.

  • Save and reload for comprehensive testing.

    All four buttons should now provide complete functionality: appropriate image updates, proper visual state management, and mutually exclusive selection behavior. This represents a fully functional product customization interface.

  • Remove the diagnostic logging statement:

    function changeColor() {
       productPhoto.src = 'img/chair-' + this.id + '.jpg';
    
       for(i = 0; i < colorButtons.length; i++) {
          colorButtons[i].classList.remove('selected');
       }
       this.classList.add('selected');
    }

    Production code should never include console logging statements—they can impact performance and expose implementation details to end users.

  • In JavaScript, we use the keyword this much the way we use the 'this' in everyday natural language.
    The 'this' keyword's value depends entirely on the context in which it's used - in event handlers, it refers to the HTML element that triggered the event.

    This Keyword Context

    Global Context

    Outside any function, 'this' refers to the global object (window in browsers).

    Event Handler Context

    Inside an event handler, 'this' refers to the HTML element that triggered the event.

    Practical Application

    Use 'this.id' to get the ID attribute of the clicked element dynamically.

    Optional Bonus: Changing the Click Event to Hover

    Modern web interfaces increasingly favor hover interactions for immediate feedback, creating more responsive and intuitive user experiences. This enhancement demonstrates the flexibility of event-driven programming.

    1. Modify the event type from click to hover detection:

      colorButtons[i].addEventListener('mouseover', changeColor);

      The mouseover event fires when users hover over elements, providing immediate visual feedback without requiring clicks. This pattern is particularly effective for product preview interfaces.

    2. Save and reload to experience the enhanced interaction model.

      Hovering over color swatches now triggers immediate product visualization changes. On touch devices without hover capabilities, tapping maintains full functionality, ensuring universal accessibility. This progressive enhancement approach demonstrates professional web development practices—improving the experience for capable devices while maintaining core functionality across all platforms.

    Click vs Hover Events

    FeatureClick EventHover Event
    Event Typeclickmouseover
    User ActionRequires Click/TapTriggers on Hover
    Mobile CompatibilityFull SupportFalls Back to Tap
    Recommended: Hover events provide immediate visual feedback on desktop while maintaining tap functionality on mobile devices.
    Clean Code Practice

    Always remove console.log statements from production code. They're valuable for debugging but should not remain in the final version users will interact with.

    Key Takeaways

    1For loops consist of three components: initialization (let i = 0), condition (i < length), and increment (i++)
    2Use querySelectorAll with CSS selectors to target multiple elements and return them as an array
    3The 'this' keyword in event handlers refers to the specific HTML element that triggered the event
    4Loop through arrays of DOM elements to apply the same event listener to multiple elements efficiently
    5Access array elements using bracket notation with the loop index: arrayName[i]
    6Remove classes from all elements before adding to the current one to maintain exclusive selected states
    7String concatenation with this.id enables dynamic image source changes based on element attributes
    8Hover events (mouseover) provide immediate feedback while maintaining mobile compatibility through tap fallback

    RELATED ARTICLES