Search code examples
javascriptjqueryjquery-animatesetintervalmouseup

Scroll tabs with animation - Stop setInterval immediately on mouseup


I've make scroll buttons , and while I'm pressing, the tabs are scrolling.

When I scroll to right and back to the begin, the tabs overflow area. How not to let this happen?

Problem

Code:

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>
<div id="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

Sorry, my English is not very good.


Solution

  • I've fixed changing the code:

    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>
    <div id="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>