Search code examples
htmlcssmaterialize

Making Materialize CSS Tooltips stay when hovering over them


A piece I'm currently working on is calling for tooltips that display when you hover over part of an SVG element, disappear as normal on mouse-out but providing the mouse does not go over the tooltip itself. We are using Materialize CSS which does come with a tooltip component. A segment of my code is below.

<svg width="400" height="400">
    <rect x="190" y="255" width="70" height="25" class="fixture good tooltipped" id="ines" data-position="top" data-delay="50" data-tooltip="Carbonated Drinks<br><a href='#'>View More</a>"" data-html="true"/>
</svg>

As you can see, the reason I want this is so that the user can click the 'View more' link if they mouse onto the actual tooltip. Currently, however, the tooltips disappear even if you mouse onto them.

I know this can be done with other frameworks/libararies, but I have been unable to do this in Materialize CSS so far.

Does anyone know if this is possible as an extensive internet search has turned up nothing.


Solution

  • Materialize tooltip assign a "mouseleave.tooltip" event handler for each involved dom node.

    This event is triggered as soon as you will leave the dom element, and after 225 milliseconds (for details refer to source code) the tootip will be hidden.

    Moreover, the tooltip has the style pointer-events equal to none: no mouse event can be triggered, so your anchor will be never clickable.

    In order to overcome all these steps a possibility is:

    • save the jQuery mouseout event object
    • remove the previous object from the jQuery handlers so no mouseleave.tooltip can be triggered.
    • handle the jQuery hover event for each tooltip (having class: material-tooltip): this to save a property in order to test against the mouse position in or out the tooltip
    • on mouseenter for your element set the pointer-events to default auto
    • in the same way on mouseleave set a timeout less than 225 milliseconds in order to test if the mouse is over the tooltip: if not execute the standard jQuery materialize mouseleave.tooltip event
    • on mouseleave the tooltip do the same step in the previous point.

    The snippet (jsfiddle):

    $(function () {
    
        var x = jQuery._data( document.getElementById('ines'), "events" )['mouseout'][0];
        delete jQuery._data( document.getElementById('ines'), "events" )['mouseout'];
        $('.material-tooltip').hover(function(e) {
            $(this).attr('hover', 1);
        }, function(e) {
            $(this).attr('hover', 0);
            x.handler.apply( document.getElementById('ines'), x);
        });
        $('#ines').on('mouseenter', function(e) {
            $('.material-tooltip:visible').css('pointer-events', 'auto');
        }).on('mouseleave', function(e) {
            setTimeout(function() {
                var val = $('.material-tooltip:visible').attr('hover');
                if (val == undefined || val == 0) {
                    x.handler.apply( document.getElementById('ines'), x);
                }
            }, 150);
        })
    
    
    });
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/css/materialize.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.98.0/js/materialize.min.js"></script>
    
    
    <svg width="400" height="400">
        <rect x="190" y="155" width="70" height="25" class="fixture good tooltipped" id="ines" data-position="top"
              data-delay="50" data-tooltip="Carbonated Drinks<br><a href='#'>View More</a>"
              data-html="true"/>
    </svg>