What could be causing this JavaScript/CSS animation to only function on the initial instance and not the subsequent ones?

I've been attempting to apply this transition effect to multiple circles, but only the first one triggers it no matter where they are positioned on the page.

javascript

let circles = document.querySelectorAll('.circle')

circles.forEach(circle => {
    circle.addEventListener('mouseenter', () => {
        if (!circle.classList.contains('hover')) {
            circle.classList.add('hover');
        }
    })

    circle.addEventListener('mouseleave', () => {
        if (circle.classList.contains('hover')) {
            circle.classList.remove('hover');
        }
    })
})

css

.circle {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100px;
    width: 100px;
    background: slateblue;
    border-radius: 100px;
    font-size: 1.5rem;
    color: #fff;
    cursor: pointer;
    transition: cubic-bezier(0.075, 0.82, 0.165, 1) 3s;
}

.hover {
  transform: scale(1.5);
}

html

<div class="circle">1</div>
<div class="circle">2</div>

edit Thank you all for your input, I realized I was overcomplicating things and found a simple solution.

Answer №1

The reason for this is that the code

let circle = document.querySelector('.circle')
will only select a single element.

You should instead use querySelectorAll and loop through the results.

const circles = document.querySelectorAll('.circle')

circles.forEach(circle => {
  circle.addEventListener('mouseenter', () => {
    if (!circle.classList.contains('hover')) {
      circle.classList.add('hover');
    }
  })

  circle.addEventListener('mouseleave', () => {
    if (circle.classList.contains('hover')) {
      circle.classList.remove('hover');
    }
  })
});
.circle {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100px;
  width: 100px;
  background: slateblue;
  border-radius: 100px;
  font-size: 1.5rem;
  color: #fff;
  cursor: pointer;
  transition: cubic-bezier(0.075, 0.82, 0.165, 1) 3s;
}

.hover {
  transform: scale(1.5);
}
<div class="circle">1</div>
<div class="circle">2</div>


Alternatively, you can achieve the same effect using just CSS. Simply replace .circle with .circle:hover in the CSS rule.

.circle {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100px;
  width: 100px;
  background: slateblue;
  border-radius: 100px;
  font-size: 1.5rem;
  color: #fff;
  cursor: pointer;
  transition: cubic-bezier(0.075, 0.82, 0.165, 1) 3s;
}

.circle:hover {
  transform: scale(1.5);
}
<div class="circle">1</div>
<div class="circle">2</div>

Answer №2

In my opinion, utilizing querySelectorAll instead of querySelector would be more beneficial as querySelector only retrieves the first matching element.

Answer №3

In response to your inquiry, the most effective approach would be utilizing querySelectorAll to target each circle individually and then adding event listeners accordingly. The querySelectorAll method generates an iterable collection of HTML elements.

https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll

let circles = document.querySelectorAll('.circle')
circles.forEach(circle => {
  circle.addEventListener('mouseenter', () => {
    if (!circle.classList.contains('hover')) {
      circle.classList.add('hover');
    }
  })

  circle.addEventListener('mouseleave', () => {
    if (circle.classList.contains('hover')) {
      circle.classList.remove('hover');
    }
  })
})

However, as highlighted by @Sebastian, it is recommended to utilize a CSS pseudo-class for hover effects:

.circle:hover {
  transform: scale(1.5);
}

This way eliminates the necessity for extensive JavaScript code.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to invoke a function and dynamically load a section of a view using AJAX?

I want to implement a feature where I can hide one div and load another div using an Ajax function. However, I am facing issues with redirecting to the function as intended. My goal is to load the div without having to refresh the page. <script type="t ...

Obtaining the clicked element within a functional component in React

I'm having trouble in React because I am unable to select the clicked element. The use of "this" in a functional component is not functioning as expected. function Test(data) { function getElement() { } return ( <div> ...

How can you effectively transfer arguments from one component to another using router.push() in Vue.js?

I need help with implementing a feature where upon clicking the edit button in a row, all the details from that particular row should be passed to a form component. I want to populate the form fields with default values from the parameters provided. Can ...

Transfer images from canvas.toDataURL to nodejs

I am attempting to transfer an image from the front-end script to my server. Here is the front-end script: var img_data = canvas.toDataURL('image/jpg'); // contains screenshot image // Place a POST request here to send the image to the server F ...

React Button Axios: A Primer for Complete Beginners

For the past few weeks, I've been using create-react-app and trying to modify the App.js file to include a button that executes an axios HTTP request when clicked. However, during my attempts, I keep running into errors like "unexpected token" in hand ...

Elements powered by jQuery failing to load upon dynamic webpage(s) loading via ajax

Dynamic loading of jQuery elements, such as Ibuttons, seems to be causing issues when implemented with an ajax dynamic content loader. The entirety of my website is rendered through Ajax just like this: <html> <header> {jQuery} </header> ...

The best method for quickly loading a webpage that is over 20MB in size

My website is a single-page calendar featuring a full year's worth of images. With 344 requests and a total load size of 20MB, the page consists of a simple PHP script without a database. The requests include a CSS file (15KB), 4 JS files (20KB), two ...

What is the best way to choose all the options in a drop-down menu using Selenium Webdriver?

Currently, I am working with Selenium WebDriver and utilizing Java. In my application, there is a dropdown menu named Product containing multiple values (for example: 60). When running the code, I first deselect all options and then select the specific opt ...

Guide to displaying Symfony/Bootstrap checkbox errors outside of the form_widget

Finding a solution for this issue has proven to be more challenging than expected! ...

Are there any customizable actions available for the `yarn remove [package]` command, such as post-installation hooks?

I must execute a script following the completion of the following commands: yarn add [package] yarn remove [package] yarn upgrade [package] yarn install postinstall gets triggered after yarn add, yarn upgrade, and yarn install. However, it doesn't s ...

Storing POST Request Data in Express

I want to use a single API endpoint for both GET and POST requests. My goal is as follows: Send multiple POST requests to /api/users with data like: {'id': 2, is_valid: 'true'} Retrieve this data by fetching the same API URL later on ...

Using Javascript to navigate links in a list using keyboard arrow keys

When links are not wrapped in other elements, I am able to change focus easily. Here is how it works: HTML <a id="first" href="#" class='move'>Link</a> <a href="#" class='move'>Link</a> <a href="#" class=&a ...

The feature of sorting appears to be malfunctioning within jQuery DataTables

I am having trouble implementing sorting in my data. Can you please help me understand why it is not working? What changes do I need to make so that the data can be displayed in order? <%@ page language="java" contentType="text/html; charset=ISO ...

Angular 5 Tutorial: Defining the "of" Method in HTTP Services

Currently, I'm studying the Angular 5 HTTP tutorial. Everything was going smoothly until I encountered a strange issue in my Ionic project where it started throwing an error stating that "of is not defined". /** * Handle Http operation that failed. * ...

I am looking to create a button with a transparent border within a white background container

I am trying to achieve a button border effect similar to the one in the image provided. I want to create a div with a white background color, and inside that div, I need to add a button with a 15px margin or padding while making it transparent. <div cl ...

What are the common practices for UI bindings in JavaScript and AJAX applications?

Background Information Currently, I am in the process of developing a traditional web application with most forms operating through AJAX. I am facing challenges in connecting the user interface to the model. As of now, I have to explicitly: Specify the ...

What is the process for fading out using jQuery?

There's a javascript function that I've been working with: function hideElement(id) { var x = document.getElementById("desc_div" + id).style.display = "none"; } I'm looking to replace the display = "none" with a fadeOut effect using jQ ...

Upon submission of the form, trigger an email to be sent and simultaneously open a

I need my form to simultaneously open a window and send the form data via email when submitted. <form action="" method="post" id="form" onsubmit="paymentfunc();return false;"> Submit button: <input type="submit" value="Purchase" class="btn" id= ...

Transforming an array of JavaScript objects into arrays of key-value pairs based on a specific property with ES6 syntax

Consider an array of objects like this: myArray = [ {name: 'First', parent: 1, delta: 2}, {name: 'Second', parent: 1, delta: 1}, {name: 'Third', parent: 2, delta: 1} ]; The goal is to transform this array into an objec ...

Unable to retrieve a substring value in Angular using Typescript

html <p> <input type="text" maxlength="40" (input)="recipientReference = deleteSpacing(recipientReference)" [(ngModel)]="recipientReference" style="width: 30vw; padding: 5px;border: 1px solid;border ...