JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://raw.github.com/vitch/jScrollPane/master/script/jquery.jscrollpane.min.js"></script>
<div class="wrapper">
<p>Enter the first red rectangle and wait: the cloned menu is shown correctly</p>
<p>Exit the first red rectangle: the cloned menu removed correctly</p>
<p>Swipe on the first red rectangle (as you were playing to Fruit Ninja): the cloned menu creation is fired, but the mouseleave event.</p>
<div class="scroll-pane">
<div class="content">
<div class="row">
<ul class="row-ul">
<li class="row-li">
<ul class="menu">
<li>Test</li>
<li>Test</li>
<li>Test</li>
</ul>
</li>
</ul>
</div>
<div class="row">
<ul class="row-ul">
<li class="row-li">
<ul class="menu">
<li>Test</li>
<li>Test</li>
<li>Test</li>
</ul>
</li>
</ul>
</div>
<div class="row">
<ul class="row-ul">
<li class="row-li">
<ul class="menu">
<li>Test</li>
<li>Test</li>
<li>Test</li>
</ul>
</li>
</ul>
</div>
<div class="row">
<ul class="row-ul">
<li class="row-li">
<ul class="menu">
<li>Test</li>
<li>Test</li>
<li>Test</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
CSS
.wrapper {
text-align:center;
}
p {
text-align: left;
}
.scroll-pane {
max-height:200px;
overflow:auto;
width:300px;
margin:100px auto;
}
.row {
height:80px;
background:#dfdfdf;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
.row-ul {
display:block;
width:100px;
height:30px;
background: red;
}
.row-li{
display:none;
position:relative;
}
.row-ul.cloned {
display:block;
background:blue;
}
.row-ul:hover li{
display:block;
}
.menu {
display:block;
height:60px;
top:-60px;
left:0;
position:absolute;
}
/*
* CSS Styles that are needed by jScrollPane for it to operate correctly.
*
* Include this stylesheet in your site or copy and paste the styles below into your stylesheet - jScrollPane
* may not operate correctly without them.
*/
.jspContainer
{
overflow: hidden;
position: relative;
}
.jspPane
{
position: absolute;
}
.jspVerticalBar
{
position: absolute;
top: 0;
right: 0;
width: 16px;
height: 100%;
background: red;
}
.jspHorizontalBar
{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 16px;
background: red;
}
.jspVerticalBar *,
.jspHorizontalBar *
{
margin: 0;
padding: 0;
}
.jspCap
{
display: none;
}
.jspHorizontalBar .jspCap
{
float: left;
}
.jspTrack
{
background: #dde;
position: relative;
}
.jspDrag
{
background: #bbd;
position: relative;
top: 0;
left: 0;
cursor: pointer;
}
.jspHorizontalBar .jspTrack,
.jspHorizontalBar .jspDrag
{
float: left;
height: 100%;
}
.jspArrow
{
background: #50506d;
text-indent: -20000px;
display: block;
cursor: pointer;
}
.jspArrow.jspDisabled
{
cursor: default;
background: #80808d;
}
.jspVerticalBar .jspArrow
{
height: 16px;
}
.jspHorizontalBar .jspArrow
{
width: 16px;
float: left;
height: 100%;
}
.jspVerticalBar .jspArrow:focus
{
...
JavaScript
$(document).ready(function(){
$('.scroll-pane').jScrollPane();
});
$(document).on('mouseenter', '.scroll-pane .row-ul', function(){
var ul_clone = $(this).clone().addClass('cloned');
var ul_box = $(this).closest('.scroll-pane').parent();
var ul_clone_offset = $(this).offset();
var ul_box_offset = $(ul_box).offset();
var ul_clone_top = ul_clone_offset.top - ul_box_offset.top;
var ul_clone_left = ul_clone_offset.left - ul_box_offset.left;
$(ul_box).css('position','relative');
$(ul_clone).css('position','absolute').css('top', ul_clone_top).css('left', ul_clone_left).hide();
if($('.row-ul.cloned').length === 0) {
$(ul_clone).appendTo(ul_box).trigger('mouseenter');
$(this).hide();
$(ul_clone).stop().fadeIn('fast');
}
});
$(document).on('mouseleave', '.row-ul.cloned', function(){
$('.row-ul.cloned').stop().fadeOut('fast', function(){
$(this).remove();
});
$('ul').show();
alert("";
});