jQuery hover with hidden content

I have the following code…

jQuery(function($) {
  var timer;
  $('.action-viewer').hide();
  $('.task').on('mouseover', function() {
    li = $(this);
    timer = setTimeout(function() {
      li.find('.action-viewer').show();
    }, 400);
  }).on('mouseout', function() {
    clearTimeout(timer);
    $(this).find('.action-viewer').hide();
  });
});
body {
  padding: 15px
}
* {
  padding: 0;
  margin: 0;
}
.task-list {
  list-style: none
}
.task {
  padding: 10px;
  border-top: 1px solid #EFEFEF
}
.action-viewer {
  border-top: 1px solid #CCC
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="task-list">
  <li class="task">This is task number 01
  <div class="action-viewer"><a href="#">Action</a>
  </div>
  </li>
  <li class="task">This is task number 02
  <div class="action-viewer"><a href="#">Action</a>
  </div>
  </li>
  <li class="task">This is task number 03
  <div class="action-viewer"><a href="#">Action</a>
  </div>
  </li>
  <li class="task">This is task number 04
  <div class="action-viewer"><a href="#">Action</a>
  </div>
  </li>
  <li class="task">This is task number 05
  <div class="action-viewer"><a href="#">Action</a>
  </div>
  </li>
<ul>

What is supposed to happen is when you hover over a task, the actions panel will show and the user can click the link. However as I move the mouse towards the link it disappears. This works without the timer, but I need the delay.


solution

You could use the mouseleave event rather than the mouseout event.

In doing so, the event isn’t fired when leaving the element and hovering over the child.

Here is the updated example:

jQuery(function($) {
  var timer;
  $('.action-viewer').hide();
  $('.task').on('mouseover', function() {
    var self = this;
    timer = setTimeout(function() {
      $(self).find('.action-viewer').show();
    }, 400);
  }).on('mouseleave', function() {
    clearTimeout(timer);
    $(this).find('.action-viewer').hide();
  });
});
body {
  padding: 15px
}
* {
  padding: 0;
  margin: 0;
}
.task-list {
  list-style: none
}
.task {
  padding: 10px;
  border-top: 1px solid #EFEFEF
}
.action-viewer {
  border-top: 1px solid #CCC
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="task-list">
  <li class="task">This is task number 01
  <div class="action-viewer"><a href="#">Action</a>
  </div>
  </li>
  <li class="task">This is task number 02
  <div class="action-viewer"><a href="#">Action</a>
  </div>
  </li>
  <li class="task">This is task number 03
  <div class="action-viewer"><a href="#">Action</a>
  </div>
  </li>
  <li class="task">This is task number 04
  <div class="action-viewer"><a href="#">Action</a>
  </div>
  </li>
  <li class="task">This is task number 05
  <div class="action-viewer"><a href="#">Action</a>
  </div>
  </li>
<ul>