I want to stop the fading out of a JQueryUI menu.
Same context: FireFox 43, Linux/Debian/Sid, Jquery2.2, JqueryUI1.11.4, as for this question; the alpha-stage MELT monitor, GPL free software on Linux/Debian with recent Firefox 38 or 43 on Linux; this is commit b505eccc1... on github
(JsFiddle MVCE example at end of question)
In my file webroot/nanoedit.js
I hve a global variable mom_menucmdel
which hold a JqueryUI menu (a dropdown menu). The mom_removecmdmenu
function is clearing that global and removing that menu from the DOM.
I want this menu to fade out and be removed in a bit more than 9 seconds, if the user don't do any interaction. But if the user is moving the mouse inside the menu, I want the fading to abort. So I coded:
var curmenu = mom_menucmdel;
curmenu.mousemove
(function(ev)
{ console.log("momdelayrepl movefinishing ev=", ev, " curmenu=", curmenu);
curmenu.finish();
});
setTimeout(function()
{
console.log("mom_cmdkeypress-delayedreplmenudestroy curmenu=",
curmenu);
curmenu.delay(100).fadeOut(800+75*dollvalseq.length,
function () {
console.log ("momdelayrepl finalfaderemove curmenu=", curmenu);
mom_removecmdmenu();
});
}, 9500);
near line 427 of that nanoedit.js
; my understanding is that finish
would abort animations. But it does not work. The fading remains, and the menu disappears, even after mouse movements.
If you are brave enough to compile the MELT monitor, browse http://localhost.localdomain:8086/nanoedit.html, type $ e in the textearea, then the esc key.
See this JsFiddle which is a simplified variant of above; run it twice. First, click on the button and wait 10 seconds at least. The menu is fading out and disappears. Then, run it again, click on the button, and move the mouse inside the menu (perhaps even selecting some item), the menu still disappears in about 10 seconds but I want it to stay, perhaps indefinitely (in my nanoedit.js
code the select
function would remove it, in this JsFiddle I don't care)!
var mymenu;
var mybutton;
var count = 0;
var menuTO;
function remove_menu() {
if (!mymenu) return;
console.log("removing mymenu=", mymenu);
mymenu.remove();
}
function fadeOutMenu() {
console.log("fading mymenu=", mymenu);
mymenu.delay(100).fadeOut(900, remove_menu);
}
$(document).ready(function() {
mybutton = $("#mybutton_id");
mybutton.on("click", function() {
count++;
var menuid = "menuid_" + count;
$("#mymenudiv_id").append("<ul class='menucl' id='" + menuid + "'</ul>");
mymenu = $("#" + menuid);
mymenu.append("<li>first</li><li>counting " + count + "</li><li>last</li>")
mymenu.menu({
select: function(ev, ui) {
console.log("selected ui=", ui);
$("#message_id").html("<b>selected</b> <i>" + ui.item.text() + "</i> menu#" + count);
}
});
mymenu.mousemove(function(ev) {
console.log("mousemove ev=", ev);
clearTimeout(menuTO);
menuTO = setTimeout(fadeOutMenu,
9000);
//mymenu.finish();
})
menuTO = setTimeout(fadeOutMenu,
9000);
})
})
ul.menucl {
background-color: lightpink;
color: navy;
font-size: 80%;
display: inline-block;
}
p.explaincl {
font-size: 75%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<p>
See <a href='http://stackoverflow.com/q/34818540/841108'>this SO question</a>
</p>
<h2> my menu </h2>
<p class='explaincl'>
First, try clicking the button, and do nothing more: the menu disappears in 10 sec. Then, try again, click the button, move the mouse inside the menu, it is still disappearing but I want it to stay!</p>
<button id='mybutton_id'>click me</button>
<div id='mymenudiv_id'>
Here
</div>
<p id='message_id'>
</p>
I have stored Timeout id in a variable menuTO. Then on every mousemove I reset Timeout so that the menu won't fade out if mouse is moving inside the menu.
Also keep in mind if your cursor is inside menu but is not moving, then it will obviously fade out in next 9 to 10 seconds.
The accepted answer will unnecessarily create and clear huge lot of timeouts when the mouse moves around.
You can use the built in menu event focus and blur to better handle this as shown below:
mymenu.menu({
focus: function(e, ui) {
clearTimeout($(this).data('timeout'));
}
});
mymenu.on('menublur', function(e, ui) {
var timeout = setTimeout(function() {
console.log("fading mymenu");
}, 5000);
$(this).data('timeout', timeout);
});
mymenu.trigger('menublur'); // start the timeout for the first time
menublur
is an internal (documented) jquery ui event which is triggered when a menu item lose focus.
Note that we should bind the event you want to trigger manually using on()
method, outside the options object.
Updated Fiddle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With