Changing images upon hovering with preloading

I'm looking to enhance my logo listing with a hover effect that switches the logo from color to black and white. Here's the current markup I have:


                var sourceToggle = function () {
                    var $this = $(this);
                    var newSource = $this.data('hover');
                    $this.data('hover', $this.attr('src'));
                    $this.attr('src', newSource);
                }

                $(function() {
                    $('img[data-hover]').each(function() { 
                        new Image().src = $(this).data('hover'); 
                    }).hover(sourceToggle, sourceToggle);
                });
            

                <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
                <a href="url">
                    <img src="http://lorempixel.com/200/200/sports/1/" data-hover="http://lorempixel.com/g/200/200/sports/1/">
                </a>
            

This code is currently functional, but I'm wondering if there are ways to optimize it or make it shorter.

Additionally, I would like to explore options for preloading the hover image to prevent any flickering when it's not loading fast enough.

Answer №1

In my opinion, it would be beneficial to eliminate the 'hover' Javascript section and allow CSS to handle its functionality. Utilize JS solely for preparing the field and then let the browser take over.

Below is a code example (you can also view it on Fiddle):

  $(function () {
      $('img[data-hover]').each(function () {
          var thisImage = $(this);
          var hoverSrc = thisImage.data('hover');
          var hoverImage = $('<img class="bw_image" src="' + hoverSrc + '" />');
          thisImage.after(hoverImage);
      })
  });
.hovering {
    display: inline-block;
    position: relative;
}
.hovering img {
    display: block;
}
.bw_image {
    position: absolute;
    left: 0;
    top: 0;
    opacity: .01;
    transition: opacity ease-in-out .2s;
}
.bw_image:hover {
    opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<a class="hovering" href="url">
    <img src="http://lorempixel.com/200/200/sports/1/" data-hover="http://lorempixel.com/g/200/200/sports/1/" />
</a> 
<a class="hovering" href="url">
    <img src="http://lorempixel.com/200/200/sports/2/" data-hover="http://lorempixel.com/g/200/200/sports/2/" />
</a>
<a class="hovering" href="url">
    <img src="http://lorempixel.com/200/200/sports/3/" data-hover="http://lorempixel.com/g/200/200/sports/3/" />
</a>

Answer №2

If possible, I suggest using a pure CSS hover effect along with a background image.

To ensure your hover image loads quickly, you can create a sprite by combining all images into one and shifting the position on hover. Here is an example:

a {
  display: block;
  background: url('http://i61.tinypic.com/2cxbyaq.png') no-repeat;
  width: 200px;
  height: 200px;
}

a:hover {
  background-position: -200px 0;
}
<a href="url"></a>

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

The Angular directive ng-model is not able to return a value

I'm currently troubleshooting an issue with the filters in an older project. Here's the HTML snippet: <input type="text" class="form-control" ng-model="FilterEventsEdit" ng-change="FilterEvents()" ...

transferring uninterrupted text data from Java programming to HTML using an HTTP request

I am currently in the process of designing an application where I am executing HTTP POST requests using Angular. These requests are then received by Java code, which processes them and generates logs consisting of approximately 50-60 lines at a rate of one ...

Can you merge the values between two arrays of objects by counting them and combining them into a single array?

I'm faced with an array conundrum categories: [ { name: 'category1', items: 0, }, { name: 'category2', items: 0, }, { name: 'category3', items: 0, }, ] And then there's this separate ar ...

Struggling to display flex items in a full-width row on a new line

Here is a code snippet where I am trying to display "0 of 2 completed" on a new line at full width. I have used flexbox for this purpose, but I am facing challenges. Can you suggest a better approach to achieve this? .container { display: flex; widt ...

What is the best way to connect individual buttons to a dynamic div that displays different content depending on the button clicked?

Hey there! I'm diving into the world of JavaScript and HTML, and I need some guidance on creating a menu that can toggle visibility of specific content in div(s) depending on which button (picture1-12) is clicked. My idea is to have one div that can d ...

Running a Node.js worker on an Amazon ECS-hosted server: A step-by-step guide

Our team is currently running a node server on Amazon ECS that receives up to 100 hits per second. Due to the single-threaded nature of JavaScript, we are hesitant to block the event loop. As a solution, we are looking to implement a worker that can peri ...

Utilizing PHP and JavaScript to Transmit Multiple MySQL Result Sets from a Popup Window

I am attempting to transfer multiple sets of MySQL data through JavaScript from a popup page to the main page. Here is my progress so far: In my popup.php page: $sql = mysql_query("SELECT * from item where category like '$catego ...

Is Angular JS binding case-sensitive?

Currently, I have a dropdown menu displaying a list of countries from a JSON file. Beside it, there is a text field that correlates to the dropdown, showing the ISO 3166 alpha-2 data (e.g. CH for Switzerland). Users have the option to input the 2-characte ...

whole <li> tag with both <a href> and <span> elements to create a clickable link

[RESOLVED] Solution found: I finally realized that the closing </a> tag comes before the <span> tags in the initial HTML code provided in the question, which was causing the issue! Thank you to everyone for your assistance!! This just goes to s ...

Execution of Ajax call fails to occur synchronously

I have created a unique weather website that utilizes the flickr API as well as the yahoo API to gather weather data. However, I am facing an issue where the ajax call from the yahoo API does not retrieve the necessary data in time for the content of the p ...

click event on ion card

Attempting to handle a click event within an ion-card using Ionic 5.0.2 version has presented some challenges. Despite my efforts, I have not been successful in handling the event with the expected function. Here is a snippet of my code: Dynamic card list ...

Scrollbar not displaying on IE when set to overflow: auto

Greetings, all! I am facing yet another design challenge with Internet Explorer. I have a DIV with Overflow:auto on my website that works perfectly fine on Chrome. However, when it comes to IE, the scroll bar doesn't show up and all the images inside ...

Unable to execute the new firebase on node server

I'm currently watching this google talk. However, I am facing an issue trying to create a firebase object. Following my package.json file, I initiated with: npm install firebase --save Then proceeded with the following steps: let Firebase = requir ...

Achieving vertical alignment of button contents in Bootstrap 4

Incorporating bootstrap 4 and material icons into my app has presented a challenge. Specifically, the issue arises when I attempt to create a button that contains both text and an icon. .button-icon { vertical-align: middle; } <button class="button ...

Having trouble getting Lodash find to work properly with TypeScript overload signatures

I have been attempting to utilize _.find in TypeScript on an Object in order to retrieve a value from this object. The original code snippet looked like this: const iconDict = { dashboard: <DataVisualizer />, settings: <SettingsApp /> ...

Tips for enhancing the width of the extrude shape in the x and z axes using Three.js

After creating a shape using extrude geometry, I found that I needed to increase the thickness along the x and z axes. Although I used bevelThickness to increase the thickness along the y axis, I still need to adjust it further. For reference, please see ...

VueJS displaying broken PNG images after deploying production build

After running the command npm run build, a dist folder is generated containing static assets such as images. The website is using history mode on vue router. Here's the HTML for the first image: https://i.sstatic.net/ZVArw.png Here's a snapsho ...

Ending a session in Node.js with Express and Socket.io

I've been grappling with this issue for a few days now and I'm just not able to wrap my head around it. I need to end my session when I navigate away from the webpage, but the error message I keep receiving (which ultimately crashes the server) r ...

Combining multiple Float32Arrays to create a single Float32Array

I need help creating a function that can flatten multiple Float32Arrays into one large Float32Array const first = new Float32Array([1,2]); const second = new Float32Array([3,4,5]); const third = new Float32Array([6,7,8,9]); const chunks = [ ...

configure Jquery AJAX settings using a JavaScript object

While working with a jQuery AJAX call, I encountered an issue where defining the ajax properties 'from scratch' worked perfectly fine. However, when setting the same values in a JavaScript object and then using that object to define the ajax requ ...