Tim Angus
Tim Angus

Reputation: 1103

Ignore mouseleave events when absolute positioned elements are covering

I have a table that has a bunch of rows that I need to be both editable and deletable. I've made a <div> which contains a couple of buttons that I want to show up in the relevant position when the rows are hovered. This is all fine. I also want the buttons to disappear when the mouse leaves the table itself. OK, I'll use the mouseleave event, I thought. Unfortunately this is fired when the mouse enters the buttons <div> too, leading to a feedback loop where the buttons constantly show and hide.

This is quite difficult to describe, but hopefully this is illustrative: https://jsfiddle.net/8d726rqt/

I did try to find an answer already, and there are many where the shown and hidden items are children of the parent element, but that's not the case for me, so these solutions don't work. Furthermore, it's often suggested to use pointer-events: none. This does work, but then the buttons don't receive click events, defeating the point.

Upvotes: 3

Views: 1395

Answers (3)

joohong89
joohong89

Reputation: 1271

#edit-control is not inside #top-level-table. Therefore when #edit-control appears and mouse is over it, it triggers the mouseleave event. Then button disappears and mouse enter table again. Thus button appears again. And it becomes a loop, where button keeps showing hiding.

I suggest adding mouseleave event to the wrapper div of #edit-control and #top-level-table.

$(function()
  {
  $('.list-row').mouseover(function()
                           {
    var offset = $(this).offset();
    $('#edit-controls').css({
      'top': offset.top + 10,
      'left': offset.left + 10
    }).fadeIn();
    //console.log('fadein');
  });
  
  //change to this element with mouseleave event
  $('#table-wrapper').mouseleave(function()
                                   {
   // console.log('fadeout');
    $('#edit-controls').fadeOut();
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
        <script crossorigin="anonymous" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
        <script crossorigin="anonymous" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
    </head>
    <body>
        <div class="container">
            <div class="table-responsive" id="table-wrapper">
                <table id="top-level-table" class="table table-striped table-bordered">
                    <thead>
                        <tr>
                            <th>Table</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="list-row">
                            <td>Content<br><br>Things</td>
                        </tr>
                        <tr class="list-row">
                            <td>Content<br><br>Things</td>
                        </tr>
                        <tr class="list-row">
                            <td>Content<br><br>Things</td>
                        </tr>
                        <tr class="list-row">
                            <td>Content<br><br>Things</td>
                        </tr>
                    </tbody>
                </table>
                <div id="edit-controls" style="display:none; position:absolute; z-index:1" >
                    <button type="button" class="btn btn-primary">Edit</button>
                    <button type="button" class="btn btn-danger">Delete</button>
                </div>
            </div>
        </div>
    </body>
</html>

Upvotes: 3

Alex Stulov
Alex Stulov

Reputation: 110

If buttons block placed some other place, than table you might use this solution:

<html>
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script crossorigin="anonymous" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script crossorigin="anonymous" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</head>
<body>
    <div class="container">
        <div class="table-responsive">
            <table id="top-level-table" class="table table-striped table-bordered">
                <thead>
                    <tr>
                        <th>Table</th>
                    </tr>
                </thead>
                <tbody>
                    <tr class="list-row">
                        <td>Content<br><br>Things</td>
                    </tr>
                    <tr class="list-row">
                        <td>Content<br><br>Things</td>
                    </tr>
                    <tr class="list-row">
                        <td>Content<br><br>Things</td>
                    </tr>
                    <tr class="list-row">
                        <td>Content<br><br>Things</td>
                    </tr>
                </tbody>
            </table>
            <div id="edit-controls" style="display:none; position:absolute; z-index:1">
                <button id="edit" type="button" class="btn btn-primary">Edit</button>
                <button id="delete" type="button" class="btn btn-danger">Delete</button>
            </div>
        </div>
    </div>
</body>

$(function()
  {
  $('.list-row').mouseover(function()
                           {
    var offset = $(this).offset();
    $('#edit-controls').css({
      'top': offset.top + 10,
      'left': offset.left + 10
    }).fadeIn();
    console.log('fadein');
  });

  $('#top-level-table').mouseleave(function(event)
                                   {
    if (event.relatedTarget.id !== 'edit' &&
    event.relatedTarget.id !== 'delete' &&
        event.relatedTarget.id !== 'edit-controlls')        {
        $('#edit-controls').fadeOut();
    }
  });
});

here is jsfiddle: https://jsfiddle.net/kinos/pbg8dhvr/13/

Upvotes: 1

cradapyx
cradapyx

Reputation: 283

On the div property:

<div onMouseLeave={(e) => e.preventDefault()}>
....
</div>

Upvotes: 0

Related Questions