如何确保活动获胜't如果没有再次触发'还没有停止

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

本文关键字:还没有 如果没有 活动 确保 获胜 何确保      更新时间:2023-09-26

所以,事情是这样的。网站的侧面有一个菜单栏。当你点击它时,菜单支架会从侧面滚动(菜单打开),当你再次点击栏时,菜单架会向后滚动并隐藏菜单。到目前为止还很简单。在工具栏上,有一个带有文本"MENU"的图标。当您打开菜单时,图标将更改,文本将更改为"关闭"。当您关闭菜单时,它将恢复正常。还是没什么大不了的。

这就是它的样子:

关闭菜单

打开菜单("ZATVORIŤ"标题的意思是"关闭",不用担心)

现在让我们来想象一下。我们需要一个效果,一个文本转换,让它看起来很酷,很流畅。因此,当菜单关闭时,没有标题。只有菜单图标。当用户将鼠标悬停在工具栏上时,文本将显示出来。用户一将鼠标悬停在工具栏上,"菜单"标题就会逐个出现。这意味着,将出现的第一个字母将是"M",第二个字母是"E"N'…'U’。整个标题将在几百毫秒,也许半秒后出现。当用户离开时,标题将按字母顺序消失。所以"男人"我"…"M"…"。你说得对。"关闭"标题的工作方式相同。当用户点击栏时(当然,他需要先将鼠标悬停在栏上,所以已经有了"MENU"标题),"MENU(菜单)"标题将逐个字母消失,"CLOSE(关闭)"标题也将逐个字母出现。当用户关闭菜单时,"关闭"标题以同样的方式消失。非常好的事情。

现在来谈谈整个问题的根源一旦用户正常工作,此功能就会立即工作。一旦用户在工具栏上停留和离开的速度过快,它就会在事件已经运行时触发事件(我猜问题出在哪里)。如果他一直点击工具栏,情况也是如此——"关闭"标题会出错,而不是"菜单"标题。然后,将出现而不是这些标题的字母"undefined"所以标题看起来像"MEundefinedundefinedundefined……"或"MMMMENundefinedundefined…"或者类似的东西。所以我一开始的想法是,这是一个错误,因为我把标题保存在字母数组中,它显示为"未定义",对吧?我很快修复了它,只是为了确保不会出现"未定义"——如果用户试图制动它,事件就会停止触发。他可以在酒吧上空盘旋,什么都不会发生。当他打开菜单(然后关闭菜单)时,一切都会恢复正常。但这不是它应该如何工作,我需要修复它。

因此,我需要做的(我认为)是确保事件不会在已经在进行的情况下触发(不知何故)。我尝试了一些javascript函数,比如delay()或setTimeout()。。。我试图用效果来制造功能,但没有成功。我在这上面花了太多时间,我没有足够的想法和技能来让它正常工作。有人能帮我检查代码并给出一些建议或修补它吗?

这里是代码:

HTML:

<div id="navigation_bar"> <!-- THE NAVIGATION BAR WITH ICON AND CAPTION HOLDER FOR THE 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 WILL THE MAGIC HAPPEN --></p> 
</div>
<div id="navigation_holder"> <!-- NOT IMPORTANT PART, ONLY THE MENU HOLDER AND 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(神奇的东西)

<script type="text/javascript">
    menuOn = false; //is true when menu is opened
    //this makes the array of letters for 'MENU' caption
    captionMenu = $( "p.menu" ).text();
    var lettersMenu = [];
    lengthMenu = captionMenu.length;
    for (var i = 0; i <= lengthMenu - 1; i++) {
        lettersMenu[i] = captionMenu.charAt(i);
    };
    //this makes the array of letters for 'CLOSE' (acutally 'ZATVORIŤ') caption
    captionClose = $( "p.zatvorit" ).text();
    var lettersClose = [];
    lengthClose = captionClose.length;
    for (var i = 0; i <= lengthClose - 1; i++) {
        lettersClose[i] = captionClose.charAt(i);
    };
    //some variables to be able to check what's going on
    length = 0; //length of the caption we're working with
    captionMenuOn = false; //true when the 'MENU' caption is visible
    captionCloseOn = false; //true when the 'ZATBORIŤ' caption is visible
    j = 0; // how many letters have appeared already
    k = lengthMenu-1; //example of "how not to name your variables" but It should solve the off-by-one error
    //now the 'MENU' caption will appear letter by letter
    $(document).on("mouseenter", "#navigation_bar", function(){
        if(!menuOn && j==0) { //of course it won't be possible if the menu is opened and there are any letters left
            j = 0;
            length = lengthMenu; //we're working with 'MENU' now
            interval = 150 / length; //counts the interval depending on caption lenght
            for (var i = 0; i <= length - 1; i++) { //looping the 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 all the letters have appeared
                        captionMenuOn = true; //now you see me
                    }
                    next();
                });
            }
            k = lengthMenu - 1; //we should have 4 letters there somewhere
        }
    });
    //now the 'MENU' caption will disappear letter by letter an inverse event to that above
    $(document).on("mouseleave", "#navigation_bar", function(){
        if(!menuOn && k==lengthMenu-1) { //so the menu needs to be closed and the 'MENU' caption should be visible
            length = lengthMenu; //we're working with 'MENU' again
            interval = 150 / length;
            k = length;
            for (var i = 0; i <= length - 1; i++) {
                $('.caption_holder').delay(interval / 2).queue(function (next) {
                    k--; //a letter has disappeared
                    $('.caption_parcial_' + k).remove();
                    if (k == 0) { //if we have no letters left
                        captionMenuOn = false; //now you don't (see me)
                    }
                    next();
                });
            }
            j = 0; //we have 0 letters visible now
        }
    });
    //--------------------------------------THIS PART OPENS AND CLOSES THE MENU and resets the 'j' variable in case someone messed up the 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 that opens or closes the menu
     function smallMenu() {
      if(!menuOn) { //if the menu is 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 this code before
          length = lengthMenu; 
          interval = 150 / length;
          j = length;
            for (var i = 0; i <= length - 1; i++) {
                $('.caption_holder').delay(interval / 2).queue(function (next) {
                    j--;
                    $('.caption_parcial_' + j).remove();
                    //and the 'CLOSE' caption will appear right away
                    if (j == 0) {
                        captionMenuOn = false;
                        length = lengthClose; //now we're working with 'CLOSE' caption
                        interval = 150 / length;
                        j = 0;
                        for (var i = 0; i <= 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 the menu shows
        menuOn = true; //the menu is opened
      }
      else { //if the menu is opened
       $("#menu_icon").attr("src", base_url + "public/web/images/menu.png").removeClass("menu_close"); //changing icon
            //we need to hide the 'CLOSE' caption
          length = lengthClose; 
          interval = 150 / length;
          j = length;
          for (var i = 0; i <= 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 the menu
        if($(".mobile_nav").is(":visible")) {
            $("#navigation_holder").css("left", "-100%");
        } else {
            $("#navigation_holder").css("left", "-50%");
        }

       menuOn = false; //now the menu is 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(如果您想在本地主机上正确运行它):

@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;
}

感谢您的帮助和建议!:)

使用SEMAPHOR模式,变量名为locked,如果事件的操作停止(完成),则为false

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