Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loop through array using wheel event a increments

Tags:

javascript

I want to change the colour of a <main> element using the wheel event. If the event.deltaY is negative i.e scrolling up I want to loop through the array backwards, so, if index = 2 it would go blue, purple, black, white and then to the end, so blue. And if the event.deltaY is positive i.e scrolling down, I want to loop through the array forwards, if index = 3, it would go blue, orange, white, black, etc. It should keep looping infinitely and either way whenever there is a scroll. Currently, I'm having trouble setting the index to loop at either end. Any help would be greatly appreciated.

const container = document.querySelector('main')
const classes = ['white', 'black', 'purple', 'blue', 'orange']

let index = 0

const throttle = (func, limit) => {
    let inThrottle
    return function() {
        const args = arguments
        const context = this
        if (!inThrottle) {
            func.apply(context, args)
            inThrottle = true
            setTimeout(() => inThrottle = false, limit)
        }
    }
}

function changeColour(event) {
    if (event.deltaY < 0) {
        ++index
        if (index === index.length - 1) {
            index = 0
        }
        console.log(index);
        container.classList = classes[index]
    }
    if (event.deltaY > 0) {
        --index
        console.log(index);
        if (index === 0) {
            index = index.length - 1
        }
        container.classList = classes[index]
    }
}

container.addEventListener('wheel', throttle(changeColour, 1250)) 
main {
  height: 50px;
  width: 50px;
  border: 1px solid;
}

main.white {
    background-color: #FFFFFF;
}

main.black {
    background-color: #101010;
}

main.purple {
    background-color: #8E002E;
}

main.blue {
    background-color: #002091;
}

main.orange {
    background-color: #C05026;
}
<main>
</main>
like image 773
CalAlt Avatar asked Sep 18 '25 21:09

CalAlt


2 Answers

Issues

  1. index = index.length - 1 index = classes.length -1
  2. container.classList = classes[index] container.classList.add(classes[index])

  3. There is no statement to remove any of the other classes.

  4. Event listeners and on-event properties do not use the parentheses of a function because it will be misinterpreted as a direct call to the function to run. Callback functions are the opposite in that they wait to be called on. If an extra parameter is needed by the callback function you'll need to wrap the callback function with an anonymous function, here's the proper syntax:

    • on-event property:
      document.querySelector('main').onwheel = scrollClass;
    • event listener:
      document.querySelector('main').addEventListener('wheel', scrollClass)

    • on-event property passing extra parameters:

      document.querySelector('main').onwheel = function(event) {
        const colors = ['gold', 'black', 'tomato', 'cyan', 'fuchsia'];
        scrollClass(event, colors);
      }
      
    • event listener passing extra parameters:

      document.querySelector('main').addEventListener('wheel', function(event) {
        const colors = ['gold', 'black', 'tomato', 'cyan', 'fuchsia'];
        scrollClass(event, colors);
      }
      

Details commented in demo

<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8'>
  <title>Wheel Event Demo</title>
  <style>
     :root {
      font: 400 16px/1.2 Consolas;
    }
    
    html,
    body {
      width: 100%;
      height: 100%;
    }
    
    body {
      overflow-y: scroll;
      overflow-x: hidden;
      padding: 5px 0 20px;
    }
    
    main {
      height: 50vh;
      width: 50vw;
      margin: 10px auto;
      border: 1px solid #000;
    }
    
    main.gold {
      background-color: #FFCC33;
      transition: 0.5s;
    }
    
    main.black {
      background-color: #101010;
      transition: 0.5s;
    }
    
    main.tomato {
      background-color: #FF6347;
      transition: 0.5s;
    }
    
    main.cyan {
      background-color: #E0FFFF;
      transition: 0.5s;
    }
    
    main.fuchsia {
      background-color: #FD3F92;
      transition: 0.5s;
    }
  </style>
</head>

<body>
  <main></main>
  <script>
    // Reference the main tag
    const container = document.querySelector('main');
    // Declare index
    let index = 0;

    /** scrollClass(event, array)
    //@ Params: event [Event Object]: Default object needed for event properties
    //          array [Array].......: An array of strings representing classNames 
    //A Pass Event Object and array of classes
    //B Reference the tag bound to the wheel event (ie 'main')
    //C1 if the change of wheel deltaY (vertical) is less than 0 -- increment index
    //C2 else if the deltaY is greater than 0 - decrement index
    //C3 else it will just be index (no change)
    //D1 if index is greater than the last index of array -- reset index to 0
    //D2 else if index is less than zero -- reset index yo the last index of array
    //D3 else index is unchanged.
    //E Remove all classes of the currentTarget ('main')
    //F Find the string located at the calculated index of the array and add it as a 
        className to currentTarget
    */
    function scrollClass(event, array) { //A
      const node = event.currentTarget; //B
      index = event.deltaY < 0 ? ++index : event.deltaY > 0 ? --index : index; //C1-3
      index = index > array.length - 1 ? 0 : index < 0 ? array.length - 1 : index; //D1-3
      node.className = ''; //E
      node.classList.add(array[index]); //F
    }

    /*
    Register wheel event to main
    When an event handler (ie scrollClass()) has more than the Event Object to pass 
    as a parameter, you need to wrap the event handler in an anonymous function. 
    Also, it's less error prone if the parameter is declared within the
    anonymous function.
    */
    container.addEventListener('wheel', function(event) {
      const colors = ['gold', 'black', 'tomato', 'cyan', 'fuchsia'];
      scrollClass(event, colors);
    });
  </script>
</body>

</html>
like image 99
zer00ne Avatar answered Sep 21 '25 12:09

zer00ne


Modified code to include the corrections

const container = document.querySelector('main')
const classes = ['white', 'black', 'purple', 'blue', 'orange']

let index = 0

const throttle = (func, limit) => {
    let inThrottle
    return function() {
        const args = arguments
        const context = this
        if (!inThrottle) {
            func.apply(context, args)
            inThrottle = true
            setTimeout(() => inThrottle = false, limit)
        }
    }
}

function changeColour(event) {
    if (event.deltaY < 0) {
        ++index
        if (index >= classes.length) { // 👈 Here
            index = 0
        }
        console.log(index);
        container.classList = classes[index]
    }
    if (event.deltaY > 0) {
        --index
        console.log(index);
        if (index <= -1) { // 👈 Here
            index = classes.length - 1 // 👈 Here
        }
        container.classList = classes[index]
    }
}

container.addEventListener('wheel', throttle(changeColour, 1250)) 
main {
  height: 50px;
  width: 50px;
  border: 1px solid;
}

main.white {
    background-color: #FFFFFF;
}

main.black {
    background-color: #101010;
}

main.purple {
    background-color: #8E002E;
}

main.blue {
    background-color: #002091;
}

main.orange {
    background-color: #C05026;
}
<main>
</main>
like image 44
Morphyish Avatar answered Sep 21 '25 12:09

Morphyish