2
\$\begingroup\$

I don't know JavaScript and it's safe to say this is my first code ever written in JS. I just needed to animate my GIFs when user hovers over them only. Googling separate concepts such as "string functions", "catch element mouse hover", "set element attribute", "get element attribute", "get elements by class", "var vs let" and so on, I came up with this:

    var contentClass = document.getElementsByClassName("gifclass");
     
    for(var i = 0; i < contentClass.length; i++)
    {
        let iElement = contentClass.item(i);
        
        iElement.addEventListener("mouseenter", function(event)
        {
            const srcAtt = iElement.getAttribute('src');
            let result = srcAtt.slice(0, srcAtt.length - 3);
            iElement.setAttribute("src", result + 'gif');

        }, false);
        
        iElement.addEventListener("mouseleave", function(event)
        {
            const srcAtt = iElement.getAttribute('src');
            let result = srcAtt.slice(0, srcAtt.length - 3);
            iElement.setAttribute("src", result + 'png');

        }, false);

    }
}

Prerequisites:

  • You need to have a static version of the GIF that ends in png (I did that with MS Paint).
  • It works so long as the GIFs are within the same class

Example:

 {
    var contentClass = document.getElementsByClassName("gifclass");
     
    for(var i = 0; i < contentClass.length; i++)
    {
        let iElement = contentClass.item(i);
        
        iElement.addEventListener("mouseenter", function( event )
        {
            const srcAtt = iElement.getAttribute('src');
            let result = srcAtt.slice(0, srcAtt.length - 3);
            iElement.setAttribute("src", result + 'gif');

        }, false);
        
        iElement.addEventListener("mouseleave", function( event )
        {
            const srcAtt = iElement.getAttribute('src');
            let result = srcAtt.slice(0, srcAtt.length - 3);
            iElement.setAttribute("src", result + 'png');

        }, false);

    }
}
Hover me: 
<img class="gifclass" src="https://gameeditor2.sirv.com/website/GIFs/game-mode.png" alt="" data-image-width="320" data-image-height="240">


All in all, my initial research on how to do that only pointed out examples where I had to do plenty of code for all of my 20+ GIFs and handle them separately.

It works, but considering that I don't know JS I was thinking it might be useful to share it for a review

\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

You can swap out document.getElementsByClassName() with document.querySelectorAll(). One reason is that you can use a selector and not just classes. The other reason is that it returns a NodeList, a different kind of array-like structure that conveniently has a forEach() method which can replace your loop.

You can also replace function declarations function() {} with the shorter arrow functions () => {}. There are technical differences between the two. But in this case, we're just after making the function a bit more concise.

Element attributes often map to DOM object properties (with some exceptions). Because of this, you can just access/assign the value to the HTML attribute directly like an object property, no need to getAttribute() or setAttribute().

You can use Regular Expressions and string.replace() to find the extension of the src. RegEx is a more advanced topic, but it gives you a lot of power when it comes to string matching. In this case, we're looking for the extension of the image and RegEx conveniently has the $ symbol which denotes the end of the string.

Lastly, if you decide to use different paths for your pngs and gifs (i.e. more than just an extension swap), then consider using data attributes to hold your paths. You can then rewrite your JS to swap the src to one of two data attributes, one holding the png path and the other the gif path.

That said, your code could be as short as:

document.querySelectorAll('img.gif-class').forEach(element => {
  element.addEventListener('mouseenter', event => {
    element.src = element.src.replace(/\.png$/, '.gif')
  })

  element.addEventListener('mouseleave', event => {
    element.src = element.src.replace(/\.gif$/, '.png')
  })
})
\$\endgroup\$
4
  • \$\begingroup\$ I did consider using replace with a regex, but ended up doing the sillier approach to avoid possible complications as I haven't touched any of that, haha \$\endgroup\$
    – Edenia
    Commented Jun 27, 2022 at 20:01
  • \$\begingroup\$ Just gotta find out now why it isn't worked when I replaced it with the new code. \$\endgroup\$
    – Edenia
    Commented Jun 27, 2022 at 20:04
  • 1
    \$\begingroup\$ remove the single quotes around the regex and it should work. ex element.src.replace(/\.png$/, '.gif') otherwise you are replacing the literal, and not the regex match \$\endgroup\$
    – munHunger
    Commented Jun 29, 2022 at 8:53
  • \$\begingroup\$ @munHunger Updated, thanks! \$\endgroup\$
    – Joseph
    Commented Jun 30, 2022 at 15:55

Not the answer you're looking for? Browse other questions tagged or ask your own question.