0

I have a use case where when a user hovers the mouse over an image it should disappear and sibling image should be displayed. When I tried to do with CSS I got a bad flicker effect. I thought I would try to do it using the HTML hidden attribute but I don't seem to be able to select the sibling of the

Can anyone take a look at this and tell me where I went wrong. Much appreciated. It seems to work with setting the hidden attribute but with removing it.

Sample Component Markup

<div class="slds-large-size_4-of-12 slds-align--absolute-center">
            <img  src="{!v.content.Public_Three_Up_Document2_URL__c}" onmouseenter="{!c.handleMouseOver}" onmouseout="{!c.handleMouseOut}"/>
            <img  src="{!v.content.Public_Hover_URL2__c}" hidden="true"/>
        </div>

Controller methods

 handleMouseOver: function (component, event, controller) {
        console.log('handle mouse over called')
        const primaryImg = event.target;
        const secondaryImage  = primaryImg.nextElementSibling;
        primaryImg.setAttribute('hidden', true);
        secondaryImage.setAttribute('hidden', false);
    },

    handleMouseOut:function (component, event, controller) {
      const primaryImg = event.target;
      const secondaryImg = primaryImg.nextElementSibling;
      primaryImg.setAttribute('hidden', false);
      secondaryImg.setAttribute('hidden', true)
    },

I have also tried to implement this using something like this and get a bad flicker effect.

handleMouseOver: function (component, event, controller) {
        console.log('handle mouse over called')
        const primaryImg = event.target;
        const secondaryImage  = primaryImg.nextElementSibling;
        $A.util.toggleClass(primaryImg, "hide");
        $A.util.toggleClass(secondaryImage, "hide");        
    },

    handleMouseOut:function (component, event, controller) {
      const primaryImg = event.target;
      const secondaryImg = primaryImg.nextElementSibling;
      $A.util.toggleClass(primaryImg, "hide");
      $A.util.toggleClass(secondaryImg, "hide");          
    },

1

Just use plain CSS:

<div class="toggleImage">
    <img  src="{!v.content.Public_Three_Up_Document2_URL__c}" />
    <img  src="{!v.content.Public_Hover_URL2__c}" />
</div>

.THIS .toggleImage img + img {
    display: none;
}
.THIS .toggleImage:hover img {
    display: none;
}
.THIS .toggleImage:hover img + img {
    display: inline-block;
}

You don't need any script at all, and this should be more efficient. If instead, you simply want to use a script after all, use the div as a wrapper instead.

Note that by setting onmouseout on the first img, the flickering comes from the fact that it will be triggered as soon as the mouse moves a single pixel, and on the next move of a pixel, the onmouseover will fire again.

Here's the script alternative:

<div class="slds-large-size_4-of-12 slds-align--absolute-center" onmouseenter="{!c.handleMouseOver}" onmouseout="{!c.handleMouseOut}">
    <img  src="{!v.content.Public_Three_Up_Document2_URL__c}" />
    <img class="slds-hide" src="{!v.content.Public_Hover_URL2__c}" />
</div>

handleMouseOver: function(component, event, helper) {
    var imgs = event.currentTarget.querySelectorAll('img');
    imgs[0].classList.add('slds-hide');
    imgs[1].classList.remove('slds-hide');
}
handleMouseOut: function(component, event, helper) {
    var imgs = event.currentTarget.querySelectorAll('img');
    imgs[0].classList.remove('slds-hide');
    imgs[1].classList.add('slds-hide');
}
| improve this answer | |
  • Thank, as always SFDXfox. When I used CSS I was also getting the flicker. But It was probably related to the same issues. – Brooks Johnson Dec 10 '19 at 21:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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