DEV Community

Discussion on: Windows 10 grid hover effect using HTML, CSS, and vanilla JS

Collapse
 
webreflection profile image
Andrea Giammarchi

interesting article, thanks, and just few quick notes:

nearBy.splice(0, nearBy.length)
could just be
nearBy.splice(0)

element.className
could rather be
element.classList.contains('win-btn')

last, but not least, it's not clear why some event is directly attached, and some is added via proper method ... anyway, thanks for the write up and the code 👋

Collapse
 
jashgopani profile image
Jash Gopani

Thanks, @webreflection for the splice suggestion. I will use that 😁.
I have almost completed the 3rd article of this series and I have already used the classList property there since I wanted to show both the approaches to the readers.

Coming to your query about direct event vs methods, the DOM element does not have a property called onmousemove . That's why I had to use addEventListener method for that particular event.

For reference, I have done console.dir() of a DOM element to check the same

console.dir

I Hope this helps 😉

Collapse
 
webreflection profile image
Andrea Giammarchi • Edited

'onmousemove' in HTMLElement.prototype in true, and every event should be added via addEventListener to avoid conflicts with other possible events.

b.onmouseleave should be b.addEventListener('mouseleave', ...) and the other too, or you can use handleEvent with an object right away.

As summary, this is how I would've written that:

const winBtn = {
  handleEvent(e) {
    this[`on${e.type}`](e);
  },
  onmouseleave({currentTarget}) {
    Object.assign(currentTarget.style, {
      background: "black",
      borderImage: null
    });
    currentTarget.border = "1px solid transparent";
  },
  onmouseenter() {
    clearNearBy();
  },
  onmousemove({currentTarget, clientX, clientY}) {
    currentTarget.border = "1px solid transparent";
    const {left, top} = currentTarget.getBoundingClientRect();
    const x = clientX - left; //x position within the element.
    const y = clientY - top; //y position within the element.
    Object.assign(currentTarget.style, {
      background:  `radial-gradient(circle at ${x}px ${y}px , rgba(255,255,255,0.25),rgba(255,255,255,0) )`,
      borderImage: `radial-gradient(20% 65% at ${x}px ${y}px ,rgba(255,255,255,0.7),rgba(255,255,255,0.7),rgba(255,255,255,0.1) ) 9 / 2px / 0px stretch `
    });
  }
};

document.querySelectorAll(".win-btn").forEach((b) => {
  for (const type of ['mouseleave', 'mouseenter', 'mousemove'])
    b.addEventListener(type, winBtn);
});
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
jashgopani profile image
Jash Gopani

Nice ✨

Thread Thread
 
webreflection profile image
Andrea Giammarchi

if you look closer, you also have one object as listener, with 4 methods, instead of N x 3 functions per each .win-btn on the page ... it's both a RAM and a CPU win ;-)

Thread Thread
 
jashgopani profile image
Jash Gopani • Edited

Do you always prefer this syntax over normal syntax? Since you have a ton of experience in JS, I would like to know what more improvisations can be made 😬. Please give your feedback on part 3 also

Thread Thread
 
webreflection profile image
Andrea Giammarchi

not sure this answers your question: webreflection.medium.com/dom-handl... 👋