skip to Main Content

I got this mouseover effect that you can see on this CodePen.

The cursor is always red, but I want it to change into a bigger (scaled) white cursor when it hovers one of the items.

<div class="custom-cursor"></div> (this is the cursor div, it’s always red and via JS I make this div follow my cursor around).

And then we have our elements:

<div class="row-02-rig-sin black-cursor">
...
</div>

This above is the <div> where I want the cursor to change shape and color. To do that, I made an eventListener so that I can track when the mouse goes over the class name of .black-cursor. Here is the JS code for that:

document.addEventListener("mouseover", function (e) {
  if (e.target.matches(".black-cursor")) {
    customCursor.classList.add("is-hovering");
  }
});

The code above "should" work (and it does partially) when you hover over the div, but the problem is that the e.target.matches() is not triggering when the cursor is hovering on an element that is inside the .black-cursor.

With simple CSS I change the cursor when it is hovering over .black-cursor since there is customCursor.classList.add("is-hovering"); when it returns true.

.custom-cursor.is-hovering {background-color:#fff;width:70px;height:70px;}

Try to play around in the CodePen, with the cursor place exactly ontop of the black horizontal bar. This is the only place that the e.target is equal to the correct element, so it triggers there, but nowhere else.

An easy fix would be to track if the e.target is a children of a .black-cursor parent. Or also, I could add the class name .black-cursor on each element so that I can ensure the cursor works. But I don’t like both of these solutions. The 1st one is time consuming for the end-user due to the calculations while mousemove and the 2nd solution is time consuming for the developer to add the same class name to all the elements.

Is there some other solution with priority on the performance? So no lags, no fps drops would appear. I’ve heard of a requestAnimationFrame here and there but I haven’t tried that yet since I dont know if it would help me.

2

Answers


  1. Chosen as BEST ANSWER

    CodePen is update with the correct code:

    This was replaced...

      document.addEventListener( 'mouseover', function( e ) {
        if ( e.target.matches('.black-cursor') ) {
          customCursor.classList.add( 'is-hovering' );
        }
      });
    
      document.addEventListener( 'mouseout', function( e ) {
        customCursor.classList.remove( 'is-hovering' );
      });
    

    ...with this:

      jQuery('.black-cursor').mouseover(function(){
        jQuery('.custom-cursor').addClass('is-hovering');
        return false;
      }).mouseout(function(){
        jQuery('.custom-cursor').removeClass('is-hovering');
      });
    

  2. You need to make your mouseout code smarter so it is not removing the class every time it is called.

    This solution is still not perfect, but should give you a starting point.

    jQuery(document).ready(function () {
        var customCursor = document.querySelector(".custom-cursor");
        document.addEventListener("mousemove", moveCursor);
        document.addEventListener("scroll", moveCursor);
        document.addEventListener("mouseover", function (e) {
            if (e.target.matches && e.target.matches(".black-cursor")) {
                customCursor.classList.add("is-hovering");
            }
        });
        document.addEventListener("mouseout", function (e) {
        if (e.target.closest(".black-cursor")) return;
            customCursor.classList.remove("is-hovering");
        });
        function moveCursor(e) {
            customCursor.style.top = e.clientY + "px";
            customCursor.style.left = e.clientX + "px";
        }
    });
    body{
        background-color:beige;
    }
    
    
    .custom-cursor {
        position: fixed;
        top: 0;
        left: 0;
        width: 20px;
        height: 20px;
        background-color: red;
        border-radius: 100%;
        pointer-events: none;
        z-index: 9999;
        transform: translate(-50%, -50%) scale(1);
        transition: transform 0.3s ease;
      }
      .custom-cursor.is-hovering {
        transform: translate(-50%, -50%) scale(4);
            background-color:white;
      }
    
    
    
    
    .row-02 {
        width: 600px;
        margin: 0 auto;
        display: flex;
        padding: 120px 0;
        justify-content: space-between;
    }
    .row-02-rig {
        display: flex;
        flex-direction: column;
        gap: 60px;
    }
    .row-02-rig-sin {
        display: flex;
        justify-content: space-between;
        position: relative;
    }
    .row-02-rig-sin::before {
        content: "";
        position: absolute;
        top: -20px;
        width: 100%;
        height: 2px;
        background-color: #000;
    }
    .row-02-rig-sin-lef {
        background-color:aqua;
        width:100px;
        display: flex;
    }
    .row-02-rig-sin-rig {
        width:500px;
        display: flex;
        flex-direction: column;
        gap: 20px;
    }
    .row-02-rig-sin-rig-top {
        width:500px;
        background-color:navy;
    }
    .row-02-rig-sin-rig-top a {
        color: #fff;
    }
    .row-02-rig-sin-rig-bot {
        width:500px;
        display: flex;
        background-color:blue;
    }
    .row-02-rig-sin-rig-bot-lef {
        width:100px;
        display: flex;
        flex-direction: column;
        background-color:pink;
        gap: 8px;
    }
    .row-02-rig-sin-rig-bot-rig {
        width:400px;
        display: flex;
        flex-direction: column;
        background-color:blueviolet;
        gap: 8px;
    }
    .row-02-rig-sin-rig-bot-rig-sin {
        font-weight: bold;
    }
    .row-02-rig-sin-rig-bot-rig-sin br {
        display: none;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="custom-cursor"></div>
    
    <div class="row-02">
        <div class="row-02-rig">
    
            <div class="row-02-rig-sin black-cursor">
                <div class="row-02-rig-sin-lef">.2018</div>
                <div class="row-02-rig-sin-rig">
                    <div class="row-02-rig-sin-rig-top"><a href="#">PROJECT TITLE HERE</a></div>
                    <div class="row-02-rig-sin-rig-bot">
                        <div class="row-02-rig-sin-rig-bot-lef">
                            <div class="row-02-rig-sin-rig-bot-lef-sin">Τοποθεσία</div>
                            <div class="row-02-rig-sin-rig-bot-lef-sin">Τομέας</div>
                            <div class="row-02-rig-sin-rig-bot-lef-sin">Προϊόντα</div>
                        </div>
                        <div class="row-02-rig-sin-rig-bot-rig">
                            <div class="row-02-rig-sin-rig-bot-rig-sin">ΒΙ.ΠΕ. Κιλκίς</div>
                            <div class="row-02-rig-sin-rig-bot-rig-sin">Έργα Υποδομής</div>
                            <div class="row-02-rig-sin-rig-bot-rig-sin">Τσιμεντόστυλοι</div>
                        </div>
                    </div>
                </div>
            </div>
            
            <div class="row-02-rig-sin black-cursor">
                <div class="row-02-rig-sin-lef">.2018</div>
                <div class="row-02-rig-sin-rig">
                    <div class="row-02-rig-sin-rig-top"><a href="#">PROJECT TITLE HERE</a></div>
                    <div class="row-02-rig-sin-rig-bot">
                        <div class="row-02-rig-sin-rig-bot-lef">
                            <div class="row-02-rig-sin-rig-bot-lef-sin">Τοποθεσία</div>
                            <div class="row-02-rig-sin-rig-bot-lef-sin">Τομέας</div>
                            <div class="row-02-rig-sin-rig-bot-lef-sin">Προϊόντα</div>
                        </div>
                        <div class="row-02-rig-sin-rig-bot-rig">
                            <div class="row-02-rig-sin-rig-bot-rig-sin">ΒΙ.ΠΕ. Κιλκίς</div>
                            <div class="row-02-rig-sin-rig-bot-rig-sin">Έργα Υποδομής</div>
                            <div class="row-02-rig-sin-rig-bot-rig-sin">Τσιμεντόστυλοι</div>
                        </div>
                    </div>
                </div>
            </div>
            
            <div class="row-02-rig-sin black-cursor">
                <div class="row-02-rig-sin-lef">.2018</div>
                <div class="row-02-rig-sin-rig">
                    <div class="row-02-rig-sin-rig-top"><a href="#">PROJECT TITLE HERE</a></div>
                    <div class="row-02-rig-sin-rig-bot">
                        <div class="row-02-rig-sin-rig-bot-lef">
                            <div class="row-02-rig-sin-rig-bot-lef-sin">Τοποθεσία</div>
                            <div class="row-02-rig-sin-rig-bot-lef-sin">Τομέας</div>
                            <div class="row-02-rig-sin-rig-bot-lef-sin">Προϊόντα</div>
                        </div>
                        <div class="row-02-rig-sin-rig-bot-rig">
                            <div class="row-02-rig-sin-rig-bot-rig-sin">ΒΙ.ΠΕ. Κιλκίς</div>
                            <div class="row-02-rig-sin-rig-bot-rig-sin">Έργα Υποδομής</div>
                            <div class="row-02-rig-sin-rig-bot-rig-sin">Τσιμεντόστυλοι</div>
                        </div>
                    </div>
                </div>
            </div>
            
        </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search