Eu2019
Eu2019

Reputation: 81

are querySelectorAll and getBoundingClientRect compatible?

I'm a very unexperienced developer. and I'm struggling to find a solution. I have two buttons with the same class, and a div called cursorFollower that actually follows the actual pageX and pageY positioning. Last week, and thanks to some people help I managed to change the cursorFollower shape based on the button it was hovering. the thing is that I can't manage to make it work with all buttons with same class. Someone suggested me to change it from querySelector to querySelectorAll to select all elements with the same class, but how to know which one is hovering at a time? Also for some reason while working on codepen it keeps saying that getBoundingClientRect should be now within a function, it was getting the size and positioning of the button as individual variables. I've included everything within a function but nothing is happening. Can someone tell me what I'm doing wrong and suggest me what to do instead?

let cursor = document.querySelector('.cursorFollower');
let button = document.querySelector('.menutext');

let buttonWidth = button.getBoundingClientRect().width;
let buttonHeight = button.getBoundingClientRect().height;
let buttonX = button.getBoundingClientRect().left;
let buttonY = button.getBoundingClientRect().top;

var onContainer = false;

const handleCursor = (e) => {
    if (onContainer) {
      cursor.setAttribute(
        "style",
        `left: ${buttonX}px;top: ${buttonY}px;width: ${buttonWidth}px;height: ${buttonHeight}px; transform: rotate(0deg); border: 1px solid #84c4b5;`
      );
      button.setAttribute(
        "style",
        `color: #84C4B5;`
      );
    } else {
      cursor.setAttribute(
        "style",
        `left: width: 20px; height: 20px; transform: rotate(45deg); border: solid 1px #ffffff;`
      );
      cursor.style.left = e.pageX - 10 + 'px';
      cursor.style.top = e.pageY - 10 + 'px';  
      button.setAttribute(
        "style",
        `color: #ffffff;`
      );
    }
};


document.addEventListener("mousemove", handleCursor);

button.onmouseover = () => {
  onContainer = true;
};

button.onmouseleave = () => {
  onContainer = false;
};
*{
  margin: 0;
  padding: 0;
}

.container {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width:100%;
  height: 100vh;
  background-color: #0A193E;
  color: white;
  font-family: sans-serif;
  font-size: 20px;
}

.container2 {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width:100%;
  height: 100vh;
  background-color: green;
  color: white;
  font-family: sans-serif;
  font-size: 20px;
}

.menutext {
  padding: 10px 20px;
  cursor: none;
  transition: all 0.2s ease;
}

.cursorFollower {
  width: 20px;
  height: 20px;
  position: absolute;
  border: 2px solid white;
  transition: all 0.2s ease-out;
  pointer-events: none;
  transform: rotate(45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
  <p class="menutext">button1</p>
  <p class="menutext">button2</p>
</div>

<div class="container2">
  <p class="menutext">button3</p>
</div>

<div class="cursorFollower"></div>

Upvotes: 0

Views: 202

Answers (1)

Jamiec
Jamiec

Reputation: 136174

The easiest thing to do is do away with the button mouseover/out handler altogether, and handle this all within the handleCursor function. If the event target has the class menutext apply your effect, although note you'll need to offset the cursors y position by the window.scrollY value:

let cursor = document.querySelector('.cursorFollower');

const handleCursor = (e) => {
    var button = e.target;
    if (button.classList.contains("menutext")) {
      const boundingRect = button.getBoundingClientRect();
      let buttonWidth = boundingRect.width;
      let buttonHeight = boundingRect.height;
      let buttonX = boundingRect.left;
      let buttonY = window.scrollY + boundingRect.top;
      cursor.setAttribute(
        "style",
        `left: ${buttonX}px;top: ${buttonY}px;width: ${buttonWidth}px;height: ${buttonHeight}px; transform: rotate(0deg); border: 1px solid #84c4b5;`
      );
      button.setAttribute(
        "style",
        `color: #84C4B5;`
      );
    } else {
      cursor.setAttribute(
        "style",
        `left: width: 20px; height: 20px; transform: rotate(45deg); border: solid 1px #ffffff;`
      );
      cursor.style.left = e.pageX - 10 + 'px';
      cursor.style.top = e.pageY - 10 + 'px';  
      button.setAttribute(
        "style",
        `color: #ffffff;`
      );
    }
};


document.addEventListener("mousemove", handleCursor);
*{
  margin: 0;
  padding: 0;
}

.container {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width:100%;
  height: 100vh;
  background-color: #0A193E;
  color: white;
  font-family: sans-serif;
  font-size: 20px;
}

.container2 {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width:100%;
  height: 100vh;
  background-color: green;
  color: white;
  font-family: sans-serif;
  font-size: 20px;
}

.menutext {
  padding: 10px 20px;
  cursor: none;
  transition: all 0.2s ease;
}

.cursorFollower {
  width: 20px;
  height: 20px;
  position: absolute;
  border: 2px solid white;
  transition: all 0.2s ease-out;
  pointer-events: none;
  transform: rotate(45deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="container">
  <p class="menutext">button1</p>
  <p class="menutext">button2</p>
</div>

<div class="container2">
  <p class="menutext">button3</p>
</div>

<div class="cursorFollower"></div>

Upvotes: 1

Related Questions