Tab Scroll - Interrupt setInterval with jQuery.mouseup

0

I need to implement tabs in my application, and when they exceed the area boundary, I need to have them rolled horizontally.

I created the scroll buttons ← , → and programmed so that while they are pressed the tabs are rolling.

When I release, they do not stop right away, the tabs still roll for a few milliseconds, and if you hold the button until the end the tabs go over the border a few pixels and that's the problem .

Enlightenment

Theproblemissimulatedwhenscrollingtotherightandthenbacktotheend,thelargerthedistance/timeofthescroll,thelargeristheoutdatedarea.

CodewithFunctionalExample:

jQuery(document).ready(function($) {
   
   var hidWidth;
   var scrollBarWidths = $('#page-tabs .scroller-right').width() + $('#page-tabs .scroller-left').width();

   var widthOfList = function(){
      var itemsWidth = 0;
      $('#page-tabs .list li').each(function(){
         var itemWidth = $(this).outerWidth();
         itemsWidth+=itemWidth;
      });
      return itemsWidth;
   };

   var widthOfHidden = function(){
      return (($('#page-tabs .wrapper').outerWidth())-widthOfList()-getLeftPosi())-scrollBarWidths;
   };

   var getLeftPosi = function(){
      return $('#page-tabs .list').position().left;
   };

   var timeout;
   $list = $('#page-tabs .list');
   $('#page-tabs .scroller-right').on('mousedown', function(event) {
      event.preventDefault();
      timeout = setInterval(function(){
         move = widthOfHidden();
         move = move < -10 ? -10 : move;

         if (move >= 0){
            clearInterval(timeout);
            return false;
         } else {
            $list.animate({left:"+="+move+"px"},10, 'linear');
         }
      }, 10);
   }).on('mouseup mouseleave', function(event){
      event.preventDefault();
      clearInterval(timeout);
   });

   $('#page-tabs .scroller-left').on('mousedown', function(event) {
      event.preventDefault();
      timeout = setInterval(function(){
         move = getLeftPosi();
         move = move < -10 ? -10 : move;

         if (move >= 0){
            clearInterval(timeout);
            //$list.animate({left:"0px"},300, 'linear');
            return false;
         } else {
            $list.animate({left:"-="+move+"px"},10, 'linear');
         }

      }, 10);

   }).on('mouseup mouseleave', function(event){
      event.preventDefault();
      clearInterval(timeout);
   });
});
#page-tabs{position:relative; width:100%; margin-top:50px;}
.scroller{width:30px;height:30px;position:absolute;top:0;}
.scroller-left{left:0;}
.scroller-right{right:0;}
.wrapper{position:relative; margin:0 34px; overflow:hidden; height:30px; background:#454545;}
ul{position:absolute;margin:0;padding:0; list-style:none; min-width:3000px;}
li{display:inline-block; margin:0; padding:10px;background:#CCC;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><divid="page-tabs">
    <div class="wrapper">
        <ul class="list">
             <li>Aba nº 1</li>
             <li>Aba nº 2</li>
             <li>Aba nº 3</li>
             <li>Aba nº 4</li>
             <li>Aba nº 5</li>
             <li>Aba nº 6</li>
             <li>Aba nº 7</li>
             <li>Aba nº 8</li>
             <li>Aba nº 9</li>
             <li>Aba nº 10</li>
             <li>Aba nº 11</li>
             <li>Aba nº 12</li>
             <li>Aba nº 13</li>
             <li>Aba nº 14</li>
             <li>Aba nº 15</li>
             <li>Aba nº 16</li>
             <li>Aba nº 17</li>
             <li>Aba nº 18</li>
             <li>Aba nº 19</li>
             <li>Aba nº 20</li>
        </ul>
    </div>
    <button class="scroller scroller-left">&larr;</button>  
    <button class="scroller scroller-right">&rarr;</button> 
</div>

JsFiddle

    
asked by anonymous 16.06.2015 / 22:51

1 answer

0

I fixed it by changing the code for:

timeout = setInterval(function() {
    move = getLeftPosi();
    move = move < -10 ? -10 : move;

    if (move >= 0) {
        clearInterval(timeout);
        return false;
    } else {
        $list.animate({
            left: "-=" + move + "px"
        }, 10, 'linear');
    }

}, 10);

To:

timeout = setInterval(function(){
    move = getLeftPosi();
    move = move < -100 ? -100 : move;

    if (move < 0)
        $list.animate({left:"-="+move+"px"},100, 'linear');

    if (move > -100){
        clearInterval(timeout);
        $list.stop(true, true);
        return false;
    }

}, 100);

Result:

   var hidWidth;
   var scrollBarWidths = $('#page-tabs .scroller-right').width() + $('#page-tabs .scroller-left').width();

   var widthOfList = function(){
      var itemsWidth = 0;
      $('#page-tabs .list li').each(function(){
         var itemWidth = $(this).outerWidth();
         itemsWidth+=itemWidth;
      });
      return itemsWidth;
   };

   var widthOfHidden = function(){
      return (($('#page-tabs .wrapper').outerWidth())-widthOfList()-getLeftPosi())-scrollBarWidths;
   };

   var getLeftPosi = function(){
      return $('#page-tabs .list').position().left;
   };

   var timeout;
   $list = $('#page-tabs .list');
   $('#page-tabs .scroller-right').on('mousedown', function(event) {
      event.preventDefault();
      timeout = setInterval(function(){
         move = widthOfHidden();
         move = move < -100 ? -100 : move;

         if (move < 0)
             $list.animate({left:"+="+move+"px"},100, 'linear');

         if (move > -100){
            clearInterval(timeout);
            $list.stop(true, true);
            return false;
         }
      }, 100);
   }).on('mouseup mouseleave', function(event){
      event.preventDefault();
      clearInterval(timeout);
   });

   $('#page-tabs .scroller-left').on('mousedown', function(event) {
      event.preventDefault();
      timeout = setInterval(function(){
         move = getLeftPosi();
         move = move < -100 ? -100 : move;

         if (move < 0)
             $list.animate({left:"-="+move+"px"},100, 'linear');
         
         if (move > -100){
            clearInterval(timeout);
            $list.stop(true, true);
            return false;
         }

      }, 100);

   }).on('mouseup mouseleave', function(event){
      event.preventDefault();
      clearInterval(timeout);
   });
#page-tabs {
    position: relative;
    width: 100%;
    margin-top: 50px;
}

.scroller {
    width: 30px;
    height: 30px;
    position: absolute;
    top: 0;
}

.scroller-left {
    left: 0;
}

.scroller-right {
    right: 0;
}

.wrapper {
    position: relative;
    margin: 0 34px;
    overflow: hidden;
    height: 30px;
    background: #454545;
}

ul {
    position: absolute;
    margin: 0;
    padding: 0;
    list-style: none;
    min-width: 3000px;
}

li {
    display: inline-block;
    margin: 0;
    padding: 10px;
    background: #CCC;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><divid="page-tabs">
    <div class="wrapper">
        <ul class="list">
            <li>Aba nº 1</li>
            <li>Aba nº 2</li>
            <li>Aba nº 3</li>
            <li>Aba nº 4</li>
            <li>Aba nº 5</li>
            <li>Aba nº 6</li>
            <li>Aba nº 7</li>
            <li>Aba nº 8</li>
            <li>Aba nº 9</li>
            <li>Aba nº 10</li>
            <li>Aba nº 11</li>
            <li>Aba nº 12</li>
            <li>Aba nº 13</li>
            <li>Aba nº 14</li>
            <li>Aba nº 15</li>
            <li>Aba nº 16</li>
            <li>Aba nº 17</li>
            <li>Aba nº 18</li>
            <li>Aba nº 19</li>
            <li>Aba nº 20</li>
        </ul>
    </div>
    <button class="scroller scroller-left">&larr;</button>
    <button class="scroller scroller-right">&rarr;</button>
</div>
    
18.06.2015 / 15:11