42326


◎マウスホイールが一度回された時に、一度だけ処理し、  
再度回すとまた処理するというものを作りたいです。

「jquery.mousewheel.js」というプラグインを使っています。

下のコードだと、大きくホイールを回すと、複数回'mousewheel'イベントが呼ばれてしまいます。

mousewheelイベントが発生した直後に

[code]

    .off("mousewheel")
    
[/code]

としているのですが、mousewheelイベント自体の発生を止めるものではないのですかね。

◎なぜtrue／falseのフラグたと処理をスルーできないのかの理由も教えていただけますと幸いです。

[code]

    $(function(){
    
     var timer;
     var index = 0;
     var delay = 1000; //次のスクロールを許容する時間
     var boxes = $('.box');
    
     //ホイールイベントを検知
     $(document).on('mousewheel', function(eo, delta, deltaX, deltaY){
      console.log('mousewheel');
      count(eo, delta)
     });
    
     //関数の定義
     function count(eo, delta){
      if (delta === -1){
        $(document).off("mousewheel")//ホイールの検知を中止
        console.log('下');
        index = index + 1
        if (index >= boxes.length-1) {
         index = boxes.length-1
        }
        changeBox(index);
        timer = setInterval(allowCount, delay);
      }
    
      if (delta === 1) {
        $(document).off("mousewheel")//ホイールの検知を中止
        console.log('上');
        index = index - 1
        if (index < 0) {
         index = 0
        }
        changeBox(index);
        timer = setInterval(allowCount, delay);
      }
    
      function allowCount() {
       console.log('go!');
    
       //ホイールを検知の再登録
       $(document).on("mousewheel",function(eo, delta, deltaX, deltaY){
        console.log('mousewheel');
        count(eo, delta)
       })
       clearInterval(timer)
      }
     }
    
     function changeBox(index) {
      var cur = $('.effect');
      cur.removeClass('effect');
      boxes.eq(index).addClass('effect');
     }
    });
[/code]

[code]

    @charset "UTF-8";
    *{
     padding:0;
     margin:0;
    }
    
    html,body{
     width:100%;
     height:100%;
     overflow: hidden;
    }
    
    
    .container{
     height: 100%;
     display:grid;
     grid-auto-rows: 50px;
     grid-template-columns: 80%;
     justify-content: center;
     grid-gap: 5px;
    }
    
    .box{
     background: pink;
    }
    
    .effect{
     opacity: 0.5;
    }
[/code]

[code]

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <title></title>
    <link rel="stylesheet" type="text/css" href="styles.css" />
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="jquery.mousewheel.js"></script>
    <script src="scripts.js"></script>
    </head>
    <body>
     <div class="container">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
     </div>
    </body>
[/code]


CC BY-SA 3.0
2018-03-10T14:46:17.093
42297
2018-03-11T13:26:43.443
2018-03-11T13:26:43.443
12297
12297
question
javascript jquery
jQueryで'mousewheel'イベントが複数呼ばれるのを中止するにはどうすればいいですか？


ホイールは回るものなので「一度だけ動かす」という考え方自体がおかしいのです。おそらくマウスホイールが一定角度で段階的に(カクカクと)回るタイプのマウスをお使いなのでしょうが、無段階に周り続けるホイールを持つマウスも存在しています。またタッチパッドのスクロールのようなものも無段階になっているかと思います。そのためそのようなUIを作成することは個人的にあまり推奨しません。

しかしどうしてもやりたいのであれば、イベントを処理した時の時刻を記録しておいて次に発生したイベントが時の現在時間と比較して一定期間内ならばイベントを無視して処理をしないようにすればいいのではないでしょうか？

追記)  
以下のようにしてもうまくいかないということでしょうか？

[code]

    $(function(){
    
        var timer;
        var index = 0;
        var delay = 1000; //次のスクロールを許容する時間
        var last_time = 0;
        var boxes = $('.box');
    
        //ホイールイベントを検知
        $(document).on('mousewheel', function(eo, delta, deltaX, deltaY){
            console.log('mousewheel');
            var now = new Date().getTime()
            if (now - last_time >= delay) {
                 last_time = now;
                count(eo, delta)
            }
        });
    
        //関数の定義
        function count(eo, delta){
            console.log('処理するよ');
            if (delta === -1){
                    console.log('下');
                    index = index + 1
                    if (index >= boxes.length-1) {
                        index = boxes.length-1
                    }
                    changeBox(index);
            }
    
            if (delta === 1) {
                    console.log('上');
                    index = index - 1
                    if (index < 0) {
                        index = 0
                    }
                    changeBox(index);
            }
        }
    
        function changeBox(index) {
            console.log('changeBox() : index => ' + index);
            var cur = $('.effect');
            cur.removeClass('effect');
            boxes.eq(index).addClass('effect');
        }
    });
    
[/code]


CC BY-SA 3.0
2018-03-10T16:44:54.143
42304
2018-03-10T18:29:19.810
2018-03-10T18:29:19.810
27410
27410
42297
answer


イベントの間隔で判断すると良いかも

[code]

        var timer;
        var index = 0;
        var interval = 100;
        var boxes = $('.box');
        var last_time = 0;
    
        //ホイールイベントを検知
        $(document).on('mousewheel', function(eo, delta, deltaX, deltaY){
            console.log('mousewheel');
                var now = new Date().getTime();
            if (now - last_time > interval){
                    count(eo, delta)
            }
            last_time = now;
        });
    
[/code]


CC BY-SA 3.0
2018-03-11T12:22:33.680
42326
2018-03-11T12:53:24.860
2018-03-11T12:53:24.860
22793
22793
42297
answer