2016-07-25 6 views
0

だから、ここに事がある。ウェブサイトの横にメニューバーがあります。あなたがそれをクリックすると、メニューホルダーが横から転がり(メニューが開きます)、バーを再びクリックすると、メニューホルダーがロールバックしてメニューを非表示にします。これまでのところかなり単純です。タットバーには、「MENU」という文字列のアイコンがあります。メニューを開くと、アイコンが変わり、テキストが「CLOSE」に変わります。メニューを閉じると、通常に戻ります。まだ大きな問題ではありません。イベントがまだ停止していない場合、再度トリガーしないようにする方法を教えてください。

これは、それがどのように見えるかです:

今度は空想取得してみましょう( 'ZATVORIŤ' キャプション手段 'CLOSE' はそのことについて心配しないでください)

closed menu

opened menuエフェクト、テキストのトランジションが必要です。メニューが閉じているときは、キャプションはありません。メニューアイコンだけです。ユーザーがバーの上を移動すると、テキストが表示されます。ユーザーがバーの上を移動すると、「MENU」のキャプションに文字「」が表示されます。つまり、最初に表示される文字は「M」、2番目の文字は「E」...「N」...「U」です。キャプション全体は数百ミリ秒で表示され、半分の時間で表示されます。ユーザーが移動すると、のキャプションは、の文字が消えます。だから 'MEN' ... 'ME' ... 'M' ... ''。あなたはポイントを持っています。 「CLOSE」キャプションも同じように機能します。ユーザーがバーをクリックすると(もちろんバーの上にカーソルを置く必要があるので、「MENU」キャプションが既にある)、「MENU」キャプションは文字で文字が消え、「CLOSE」キャプションは文字で表示されます。ユーザーがメニューを閉じると、「CLOSE」キャプションも同様に消えます。かなり素敵なもの。

今、問題全体の根本に。これは、ユーザーが正常に動作するとすぐに機能します。ユーザーがバーをあまりに速く動かし続けるとすぐに、イベントが既に実行されている間にイベントがトリガーされます(問題が何であるかがわかります)。彼がバーをクリックし続けると同じことが起こります - 'CLOSE'キャプションは 'MENU'キャプションの代わりに混乱します。次に、 'undefined'のキャプションのカップルの文字の代わりにが表示されます。キャプションは 'MEundefinedundefinedundefined ....'や 'MMMMENundefinedundefined ...'などのようになります。だから私が最初に考えたのは、キャプションが文字の配列で保存されていて、それが「未定義」であることを示しているからです。私はすぐにそれをパッチして、「未定義」が現れないことを確認しました。ユーザーがブレーキをかけようとすると、イベントはトリガーを止めるだけです。彼はバーの上に乗ることができ、何も起こりません。彼がメニューを開いて(そしてそれを閉じると)普通になります。しかし、それはどのように動作するはずではなく、私はそれを修正する必要があります。

私がしなければならないことは、すでに進行中の場合(何とか)、イベントが発生しないようにすることです。私は遅延()やsetTimeout()のようないくつかのjavascript関数を試してみました...私は効果から機能を作りようとしました - 失敗しました。私はこれに多くの時間を費やし、私はこれを適切に動作させるために必要なアイデアやスキルがありません。誰かが私のためのコードをチェックし、いくつかの提案を与えるか、多分それにパッチを当てることができますか?

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(場合には、あなたが適切にあなたのローカルホスト上でそれを実行したい

はこちらCODE'S ):

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

ご協力ありがとうございます! :)

+3

TL。 DR - [ask]を読む! – Amit

+0

最初のイベントで設定したフラグを使用し、すべてのイベントでチェックします。 – dandavis

+1

あなたの要素に 'onclick =" return false; "'属性を追加して読んでみようと思います* *(/ help/how-to-ask)と* [mcve] * –

答えて

1

使用イベントのアクションが停止した場合falseあるlockedという名前の変数を持つSEMAPHORパターン、(終了):

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 
    } 
}); 
関連する問題