ps0604 ps0604 - 5 months ago 34
jQuery Question

Context menu not showing submenu

In this plunk I have a menu that shows up when you click on the canvas. On hover over the "Aggregate" menu item, a second submenu shows up on the right.

The problem is that if you "mouse out" from "Aggregate" and then enter again, the position of the submenu is no longer where it is supposed to be. What's wrong with this code?

HTML

<div id="canvas" style="width:400px;height:400px;background-color:#ff33ff;"></div>

<div id="menu1" class="context-menu">
<ul>
<li>
<a href="javascript:void(0);">Display</a>
</li>
<li id="li1">
<a href="javascript:void(0);">Aggregate</a>
</li>
<li id="li2">
<a href="javascript:void(0);">Order by</a>
</li>
<li>
<a href="javascript:void(0);">Group by</a>
</li>
</ul>
</div>

<div id="menu2" class="context-menu">
<ul>
<li>
<a href="javascript:void(0);">Count</a>
</li>
<li>
<a href="javascript:void(0);">Sum</a>
</li>
<li>
<a href="javascript:void(0);">Average</a>
</li>
</ul>
</div>


Javascript

$('#canvas').click(function(e) {

var top = e.pageY;
var left = e.pageX;

$("#menu1").show();
$("#menu1").offset({ top: top, left: left });

$('#li1').mouseenter(function() {
$("#menu2").offset({ top: top+20, left: left+120 });
$("#menu2").show();
});

$('#li1').mouseleave(function() {
$("#menu2").hide();
});

$('#menu2').mouseenter(function() {
$("#menu2").show();
});

$('#menu2').mouseleave(function() {
$("#menu2").hide();
});

});


CSS

.context-menu {
border:1px solid rgba(0,0,0,.15);
background-color:#ffffff;
padding:6px 0 0 0;
display:none;
}
.context-menu ul {
padding:0;
list-style:none;
}
.context-menu li {
background-color:#ffffff;
}
.context-menu li:hover {
background-color:rgb(248,248,248);
}
.context-menu a {
color:#333;
text-decoration: none;
line-height:24px;
margin-left:20px;
}
#menu1{
position:absolute;
width:140px;
}
#menu2{
position:absolute;
width:100px;
}

Answer

Try replacing offset with css.

I think every time offset is called on mouseenter, it adds to the current position of that menu.

Using the css method will set the top and left positions instead of adding to the current position.