nik218
nik218

Reputation: 68

Change body background when hovering over a div nested inside

I'm trying to manipulate what is happening in the fiddle on this forum, but I am having some trouble and I'm not sure where I am going wrong.

I have created my own pen here with a stripped down version of what is on my site.

Essentially what I want to do is whenever you hover over the image or the gray box, the body background color will change. (Ideally a fade in/out type of interaction, but if the fade part can be accomplished via CSS, I can do that).

I tried to changed getElementById (from the example) to getElementsByClassName since I have multiple instances of the class, but that didn't seem to work. I had added back in getElementById and it works where applied (on the image) but I don't think that would be best practice since I will have multiple instances of the class.

Disclaimer: I don't know much about JS, so if there is a better way to do this, I'd be glad to try it out!

I only added the JS in the post here to keep things condensed. HTML and CSS in the codepen.

$(document).ready(function(){  
  window.onload = function(){
    var block1 = document.getElementById('hover-color1');
    var body = document.body;
    block1.onmouseover = function() {
        body.className = 'hover-color1';
    }
    block1.onmouseout = function() {
        body.className = '';
    }
  };
});

Upvotes: 0

Views: 957

Answers (2)

Ace
Ace

Reputation: 969

If you want to attach your mouse events to multiple items you can use querySelectorAll to get references to multiple nodes. They can be ids or classes the selectors are your choice. A data attribute could also be another choice which can be applied to any dom node as well. Regardless of your selectors you need to apply your onmouse events to each node, which is done by looping through the results of querySelectorAll

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

The Document method querySelectorAll() returns a static (not live) NodeList representing a list of the document's elements that match the specified group of selectors.

If you want to control a transition without css, you can manipulate a dom nodes style attribute. In this case we apply a transition of 1 second on background and change and the background to either the data attribute if it exists for data-hover-color or else red by default on hover.

const body = document.body;
const domNodes = document.querySelectorAll("[data-hover-changer]");

for (domNode of domNodes) {
  domNode.onmouseover = (event) => {
    body.style.transition = "background 1s ease";
    body.style.background = event.target.dataset.hoverColor || "red";
  }

  domNode.onmouseout = () => {
    body.style.background = "transparent";
  }
}
<div id="hoverId" data-hover-changer>Hover to change background to red</div>
<div class="hoverClass" data-hover-changer data-hover-color="yellow">Hover to change background to yellow</div>
<div class="hoverClass" data-hover-changer data-hover-color="green">Hover to change background to green</div>
<div>Hover will not work on me</div>

Upvotes: 1

dale landry
dale landry

Reputation: 8610

You are looking for a transition on the background color. Add the transition for background-color in your body CSS, then in your hover to change body, set the new background color and the transition will fire and make it animate from color one to the other color.

Javascript:

  1. get the class elements using a node selector to create a nodeList -> querySelectorAll returns a nodeList
  2. iterate over the list to get the event.target
  3. use a mouseover and mouseout event to add/remove the class using classList.add/remove
    const block1 = document.querySelectorAll('.hover-color1')
    block1.forEach(img => {
      img.addEventListener('mouseover', e => {
        document.body.classList.add('hover-color1')
      })
      img.addEventListener('mouseout', e => {
        document.body.classList.remove('hover-color1')
      })
    })

CSS: Add a transition to your CSS for the body on background and then on hover the background change will transition from the background-color set in body to the body.hoverElement background-color.

body {
  font-family: 'IBM Plex Sans', sans-serif;
  color: #1a1b1f;
  font-size: 16px;
  line-height: 28px;
  font-weight: 400;
  -webkit-transition: background-color 1s linear;
  -moz-transition: background-color 1s linear;
  -o-transition: background-color 1s linear;
  -ms-transition: background-color 1s linear;
  transition: background-color 1s linear;
}

body.hover-color1 {
  background-color: red;
}

$(document).ready(function() {
  window.onload = function() {
    const block1 = document.querySelectorAll('.hover-color1')
    block1.forEach(img => {
      img.addEventListener('mouseover', e => {
        document.body.classList.add('hover-color1')
      })
      img.addEventListener('mouseout', e => {
        document.body.classList.remove('hover-color1')
      })
    })
  }
})
.w-layout-grid {
  display: grid;
  grid-auto-columns: 1fr;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto;
  grid-row-gap: 16px;
  grid-column-gap: 16px;
}

body {
  font-family: 'IBM Plex Sans', sans-serif;
  color: #1a1b1f;
  font-size: 16px;
  line-height: 28px;
  font-weight: 400;
  -webkit-transition: background-color .5s linear;
  -moz-transition: background-color .5s linear;
  -o-transition: background-color .5s linear;
  -ms-transition: background-color .5s linear;
  transition: background-color .5s linear;
}

body.hover-color1 {
  background-color: red;
}

.section {
  position: relative;
  z-index: 10;
  width: 100%;
  height: auto;
  margin-right: 0px;
  margin-left: 0px;
  padding-right: 30px;
  padding-left: 30px;
}

img {
  display: block;
  max-width: 1200px;
}

.container {
  width: 100%;
  max-width: 1140px;
  margin-right: auto;
  margin-left: auto;
}

.paragraph {
  margin-bottom: 20px;
  border-top: 1px none #525254;
  font-family: 'IBM Plex Sans', sans-serif;
  color: #525254;
  font-size: 16px;
  line-height: 1.5em;
  letter-spacing: 0.3px;
}

.relative-block {
  position: relative;
}

.heading-3.display-mono {
  font-family: 'IBM Plex Mono', sans-serif;
  color: #1a1b1f;
  font-size: 32px;
  letter-spacing: 1.1px;
}

.heading-4.display-h6 {
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 20px;
  line-height: 1.5em;
  font-weight: 400;
}

.link {
  display: inline-block;
  font-family: 'IBM Plex Mono', sans-serif;
  line-height: 1.5em;
  text-decoration: none;
}

.portfolio-block-left {
  position: relative;
  max-width: 1440px;
  margin: 50px auto;
}

.portfolio-grid-left {
  position: relative;
  grid-column-gap: 25px;
  grid-row-gap: 25px;
  -ms-grid-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
  -ms-grid-rows: auto auto auto auto;
  grid-template-rows: auto auto auto auto;
}

.portfolio-image.fade-in-1st {
  position: relative;
  z-index: 1;
}

.portfolio-title {
  position: relative;
  z-index: 2;
  max-width: 570px;
  margin-right: 0px;
  margin-left: 0px;
  padding: 25px;
  background-color: #ccc;
}

.portfolio-block-right {
  position: relative;
  max-width: 1440px;
  margin: 50px auto;
}

.portfolio-grid-right {
  position: relative;
  grid-column-gap: 25px;
  grid-row-gap: 25px;
  grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
  grid-template-rows: auto auto auto auto;
}

.max-1440 {
  width: 100%;
  max-width: 1440px;
  margin-right: auto;
  margin-left: auto;
}

#w-node-link-block-825bf526 {
  grid-column-end: 7;
  grid-column-start: 1;
  grid-row-end: 4;
  grid-row-start: 1;
}

#w-node-eb6e1164-1454-9dc3-9597-76f59d0186bb-825bf526 {
  grid-column-end: 8;
  grid-column-start: 4;
  grid-row-end: 5;
  grid-row-start: 3;
  align-self: end;
  justify-self: end;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="padding-50px section">
  <div class="portfolio-block-left">
    <div class="w-layout-grid portfolio-grid-left">
      <a id="w-node-link-block-825bf526" href="#" class="portfolio-image fade-in-1st w-inline-block">
        <img class="hover-color1" src="https://source.unsplash.com/random/1200x400" alt=""></a>
      <div id="w-node-eb6e1164-1454-9dc3-9597-76f59d0186bb-825bf526" class="portfolio-title hover-color1">
        <h3 class="heading-3 display-mono">Title</h3>
        <h4 class="heading-4 display-h6">Secondary Title</h4><a href="#" class="link">View Project</a>
      </div>
    </div>
  </div>
</div>

Upvotes: 1

Related Questions