Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to abort fading out of jqueryui menu?

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.


JsFiddle example (MVCE)

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)!

like image 566
Basile Starynkevitch Avatar asked Jan 15 '16 19:01

Basile Starynkevitch


2 Answers

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.

like image 110
Kiran Shakya Avatar answered Oct 09 '22 08:10

Kiran Shakya


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

like image 22
T J Avatar answered Oct 09 '22 08:10

T J