Search code examples
javascriptmousehover

Overriding hover effects in Web Forms with JavaScript


I am working with a web form where the (table header) elements in a grid change color when I hover over them. However, the hover color stays even after I move the mouse away. This behavior is caused by a method in an internal JavaScript library that adds a class (sf_th_hover) on hover and keeps it active. The hover effect occurs mostly, but not always. I cannot modify the library code directly, so I'm trying to override this behavior using custom JavaScript.

Attempt 1

I tried to remove the hover effect with this code but it was only run when the site was loaded.
document.addEventListener("DOMContentLoaded", function ()
{
    console.log("Fix für sf_th_hover aktiv!");

    function removeHoverEffect()
    {
        document.querySelectorAll(".sf_th_hover").forEach(header =>
        {
            header.addEventListener("mouseleave", function ()
            {
                this.classList.remove("sf_th_hover");
                console.log("sf_th_hover entfernt:", this);
            });
        });
    }

    removeHoverEffect();

    new MutationObserver(mutations =>
    {
        mutations.forEach(mutation =>
        {
            mutation.addedNodes.forEach(node => {
                if (node.nodeType === 1 && node.classList.contains("sf_th_hover"))
                {
                    console.log("Neues sf_th_hover gefunden:", node);
                    node.addEventListener("mouseleave", function ()
                    {
                        this.classList.remove("sf_th_hover");
                        console.log("sf_th_hover entfernt (durch MutationObserver):", this);
                    });
                }
            });
        });
    }).observe(document.body, { childList: true, subtree: true });
});

These logs (for example sf_th_hover entfernt) were never reached.

Attempt 2

I tried to remove the class.
$(document).on("mouseenter", "th", function () {
    $(this).removeClass("sf_th_hover");
    console.log("Fix: sf_th_hover wurde entfernt!");
});

$(document).off("mousemove", "th");

But an error occured:

Uncaught TypeError: $(...).on is not a function

which refers to the line $(document).on("mouseenter", "th", function () {.

I cannot include jQuery, as it breaks the page.

I'm not familiar with JavaScript. I appreciate the help.


The code in the grid is this:
original events

_mouseMove = function () {
var _e = $(this);
if (this.tagName != 'th') $(this).parents('th:first');
_e.toggleClass('sf_th_hover');
                },

And the problem is that it shouldn't use toggle as far as I understand the situation.


Solution

  • I worked out a solution. This javascript works. The hover color only disappears when the mouse leaves the grid header. There is a 200ms delay to avoid flickering.

    When a column is clicked, it remains highlighted as expected. I kept the sorting functionality.

    document.addEventListener("DOMContentLoaded", function ()
    {
        //console.log("Fix für sf_th_hover aktiv!");
    
        document.addEventListener("mouseenter", function (event)
        {
            //if (event.target.classList.contains("sf_th_hover"))
            //{
            //    console.log("Hover detected:", event.target);
            //}
        }, true); // Use capture phase to detect early
    
        document.addEventListener("mouseleave", function (event)
        {
            if (event.target.classList.contains("sf_th_hover"))
            {
                setTimeout(() =>
                {
                    if (!event.target.matches(":hover")) // Only remove if not hovered anymore
                    {
                        event.target.classList.remove("sf_th_hover");
                        //console.log("sf_th_hover removed on mouse leave:", event.target);
                    }
                }, 200); // Delay to prevent flickering
            }
        }, true); // Use capture phase
    });