javascript - How to make sure event won't trigger again if it hasn't stopped yet? -


so, here's thing. there's menu bar on side of website. when click on it, menu holder rolls in side (the menu opened), when click on bar again, menu holder rolls , hides menu. pretty simple far. on tat bar, there icon text 'menu'. when open menu, icon changes , text changes 'close'. when close menu, returns normal. still not big deal.

this how looks like:

closed menu

opened menu (the 'zatvoriŤ' caption means 'close' don't worry that)

now let's fancy. need effect, text transition make cool , smooth. when menu closed, there's no caption. there's menu icon. text show when user hovers on bar. user hovers on bar, 'menu' caption appear letter letter. means, first letter appear 'm', second 'e'... 'n'... 'u'. whole caption appear in few hundred milliseconds, maybe half second. when user hovers away, caption disappear letter latter. 'men' ... 'me' ... 'm'... ' '. got point. 'close' caption works same way. when user clicks on bar (of course needs hover on bar first, there's 'menu' caption already) 'menu' caption disappears letter letter , 'close' caption appear letter letter. when user closes menu, 'close' caption disappears same way. pretty nice thing.

now root of whole problem. works user acts normally. user keep hovering on , away bar fast, it'll trigger event while event running (my best guess problem is). same goes if keeps clicking on bar - 'close' caption mess instead of 'menu' caption. then, instead of letters of captions couple of 'undefined' appear. caption 'meundefinedundefinedundefined....' or 'mmmmenundefinedundefined...' or similar. thought @ first was, off-by-one error, because got captions saved in arrays of letters , it's showing 'undefined', right? patched make sure no 'undefined' appear - if user tries brake it, events quit triggering. can hover on bar , nothing happen. it'll normal when opens menu (and closes it). that's not how should work , need fix it.

so need (i think) make sure event wont trigger if 1 in progress (somehow). tried javascript function delay() or settimeout()... tried make functions out of effects - unsuccessfully. spent time on , i'm out of ideas , skills needed make work properly. able check code me , give suggestion or maybe patch it?

here's code:

html:

<div id="navigation_bar"> <!-- navigation bar icon , caption holder text -->     <img id="menu_icon" src="<?= $base_url ?>public/web/images/menu.png">     <p class="zatvorit">zatvoriŤ</p>     <p class="menu">menu</p>     <p class="caption_holder"><!-- here magic happen --></p>   </div> <div id="navigation_holder"> <!-- not important part, menu holder , menu -->      <p class="close_nav_mobile">         <img src="<?= base_url() ?>public/web/images/close_menu.png">     </p>      <ul id="menu_item_list" class="">         <li role="presentation"><a class="menu_1" href="<?= $base_url ?>nasa-ponuka">naŠa ponuka</a></li>         <li role="presentation"><a class="menu_2" href="<?= $base_url ?>referencie">referencie</a></li>         <li role="presentation"><a class="menu_3" href="<?= $base_url ?>kontakt">kontakt</a></li>         <li id="order_link" class="menu_order_link order_form_open" role="presentation"><a href="#"><b>objednÁvka</b></a></li>         <li id="registration_link" class="menu_reg_form_link reg_form_open" role="presentation"><a href="#">registrÁcia</a></li>     </ul>         <a href="#"><img id="fb_icon" src="<?= $base_url ?>public/web/images/fb_icon.png"></a> </div> 

javascript & jquery (magic stuff)

<script type="text/javascript">     menuon = false; //is true when menu opened      //this makes array of letters 'menu' caption     captionmenu = $( "p.menu" ).text();     var lettersmenu = [];     lengthmenu = captionmenu.length;     (var = 0; <= lengthmenu - 1; i++) {         lettersmenu[i] = captionmenu.charat(i);     };      //this makes array of letters 'close' (acutally 'zatvoriŤ') caption     captionclose = $( "p.zatvorit" ).text();     var lettersclose = [];     lengthclose = captionclose.length;     (var = 0; <= lengthclose - 1; i++) {         lettersclose[i] = captionclose.charat(i);     };      //some variables able check what's going on     length = 0; //length of caption we're working     captionmenuon = false; //true when 'menu' caption visible     captioncloseon = false; //true when 'zatboriŤ' caption visible     j = 0; // how many letters have appeared     k = lengthmenu-1; //example of "how not name variables" should solve off-by-one error      //now 'menu' caption appear letter letter     $(document).on("mouseenter", "#navigation_bar", function(){         if(!menuon && j==0) { //of course won't possible if menu opened , there letters left             j = 0;             length = lengthmenu; //we're working 'menu'             interval = 150 / length; //counts interval depending on caption lenght             (var = 0; <= length - 1; i++) { //looping letters                 $('p.caption_holder').delay(interval).queue(function (next) {                     $(this).append( '<span class="caption_parcial_' + j + '">' + lettersmenu[j] + '</span>' );                     j++; //a letter has appeared                     if (j == length-1) { //if letters have appeared                         captionmenuon = true; //now see me                     }                     next();                 });             }             k = lengthmenu - 1; //we should have 4 letters there somewhere         }     });      //now 'menu' caption disappear letter letter inverse event above     $(document).on("mouseleave", "#navigation_bar", function(){         if(!menuon && k==lengthmenu-1) { //so menu needs closed , 'menu' caption should visible             length = lengthmenu; //we're working 'menu' again             interval = 150 / length;             k = length;             (var = 0; <= length - 1; i++) {                 $('.caption_holder').delay(interval / 2).queue(function (next) {                     k--; //a letter has disappeared                     $('.caption_parcial_' + k).remove();                     if (k == 0) { //if have no letters left                         captionmenuon = false; //now don't (see me)                     }                     next();                 });             }             j = 0; //we have 0 letters visible         }     });      //--------------------------------------this part opens , closes menu , resets 'j' variable in case messed captions     $(document).on("click", "#navigation_bar, .close_nav_mobile", function(){         if(menuon)             $(".caption_holder").show();         smallmenu();     });      $(document).on("click", ".menu_order_link", function(){         smallmenu();         j=0;     });     $(document).on("click", ".menu_reg_form_link", function(){         smallmenu();         j=0;     });          //function opens or closes menu      function smallmenu() {        if(!menuon) { //if menu closed         $("#menu_icon").attr("src", base_url + "public/web/images/close_menu.png").addclass("menu_close"); //icon changes        //$("nav > ul").show();             //the 'menu' caption dissapears, we've seen code before           length = lengthmenu;            interval = 150 / length;           j = length;             (var = 0; <= length - 1; i++) {                 $('.caption_holder').delay(interval / 2).queue(function (next) {                     j--;                     $('.caption_parcial_' + j).remove();                     //and 'close' caption appear right away                     if (j == 0) {                         captionmenuon = false;                         length = lengthclose; //now we're working 'close' caption                         interval = 150 / length;                         j = 0;                         (var = 0; <= length - 1; i++) {                             $('p.caption_holder').delay(interval).queue(function (next) {                                 $(this).append( '<span class="caption_parcial_' + j + '">' + lettersclose[j] + '</span>' );                                 j++;                                 if (j == length-1) {                                     captioncloseon = true;                                 }                                 next();                             });                         }                     }                     next();                 });             }                /*        $("#navigation_holder").animate(              {                  'left' : '0%'              }, 1250, 'easeoutexpo' );*/          $("#navigation_holder").css("left", "0%"); //and menu shows          menuon = true; //the menu opened        }       else { //if menu opened         $("#menu_icon").attr("src", base_url + "public/web/images/menu.png").removeclass("menu_close"); //changing icon             //we need hide 'close' caption           length = lengthclose;            interval = 150 / length;           j = length;           (var = 0; <= length - 1; i++) {               $('.caption_holder').delay(interval / 2).queue(function (next) {                   j--;                   $('.caption_parcial_' + j).remove();                   if (j == 0) {                       captioncloseon = false;                   }                   next();               });           }         /*        $("#navigation_holder").animate(              {                  'left' : '-50%'              }, 1250, 'easeoutexpo' );*/               //and hide menu         if($(".mobile_nav").is(":visible")) {             $("#navigation_holder").css("left", "-100%");         } else {             $("#navigation_holder").css("left", "-50%");         }           menuon = false; //now menu closed        }        }       //not important      $(window).resize(function() {          if(!menuon) {              if($(".mobile_nav").is(":visible")) {                 $("#navigation_holder").css("left", "-100%");             } else {                 $("#navigation_holder").css("left", "-50%");             }          }       });   </script> 

css (in case want run on localhost properly):

@import url(https://fonts.googleapis.com/css?family=biryani:400,700,300,600);   * {     font-family: 'biryani', sans-serif !important;     margin: 0px;     padding: 0px; }  body, html {   margin:0;   padding:0;   height:100%; }  body {   overflow-x:hidden; }   /*---------------------------navigation------------------------*/   #navigation_bar {   width: 55px;   height: 100%;   background-color: #000;   display: block;   position: fixed;   margin: 0;   text-align: center;   cursor: pointer;   z-index: 1500; }  #menu_icon {   margin: auto;   max-width: 22px;   text-align: center;   position: relative;   top: 49%; }  .zatvorit {   display: none;   font-size: 16px;   color: white;   font-family: "bauerbodonidot-regular", serif !important;   -ms-transform: rotate(-90deg);   -webkit-transform: rotate(-90deg);   transform: rotate(-90deg);   position: absolute; top: 50%; left: -11px; margin-top: -74px; }  .menu {   display: none;   font-size: 16px;   color: white;   font-family: "bauerbodonidot-regular", serif !important;   -ms-transform: rotate(-90deg);   -webkit-transform: rotate(-90deg);   transform: rotate(-90deg);   position: absolute;   top: 42%;   left: 6px;   margin-top: 5px; }  .menu_close {   max-width: 18px !important; }  .caption_holder {   font-size: 16px;   color: white;   font-family: "bauerbodonidot-regular", serif !important;   -ms-transform: rotate(-90deg);   -webkit-transform: rotate(-90deg);   transform: rotate(-90deg);   position: absolute;   top: 50%;   left: 3px;   margin-top: -59px;   width: 50px;   text-align: left; }  .right_buttons {   position: absolute;   top: 48px;   right: 55px; }  .caption_holder span {   font-family: "bauerbodonidot-regular", serif !important;   letter-spacing: 3px; }  #navigation_holder {   width: 50%;   max-width: 50%;   height: 100%;   background-color: #000;   display: block;   position: fixed;   padding: 50px;   margin: 0;   text-align: right;   z-index: 1000;   left: -50%;       transition:all ease 0.5s;     -webkit-transition:all ease 0.5s;     -moz-transition:all ease 0.5s;     -o-transition:all ease 0.5s; } 

thanks , suggestions! :)

use semaphor pattern, variable named locked false if event's action stopped (finished):

var locked_mouseenter=false; //initialize "unlock" $(document).on("mouseenter", "#navigation_bar", function(){     if( !locked_mouseenter ){         locked_mouseenter = true; //lock          // code here of event's action          // code stop here, next instruction :          locked_mouseenter = false; //unlock     } }); 

Comments

Popular posts from this blog

jOOQ update returning clause with Oracle -

java - Warning equals/hashCode on @Data annotation lombok with inheritance -

java - BasicPathUsageException: Cannot join to attribute of basic type -