странное поведение setInterval () - PullRequest
0 голосов
/ 04 апреля 2019

Я пытаюсь анимировать несколько простых диаграмм с помощью js. Я хочу, чтобы они поднимались один за другим, когда они видны. Все хорошо, когда держатель диаграммы является первым элементом, но когда я добавляю некоторое пространство над ним, чтобы проверить прокрутку, он как setInterval () запускается мгновенно без задержки, которую я установил

Я пробовал различные исправления Google, некоторые циклы и установил таймаут, установленный для setinterval

const chartIsInView = el => {
    const scroll = window.scrollY || window.pageYOffset
    const boundsTop = el.getBoundingClientRect().top + scroll

    const viewport = {
        top: scroll,
        bottom: scroll + window.innerHeight,
    }

    const bounds = {
        top: boundsTop,
        bottom: boundsTop + el.clientHeight,
    }

    return ( bounds.bottom >= viewport.top && bounds.bottom <= viewport.bottom ) 
        || ( bounds.top <= viewport.bottom && bounds.top >= viewport.top );
}

var i = 0

function animate(e){
    e[i].classList.remove("animate")
    i++
}

document.addEventListener( 'DOMContentLoaded', () => {
    const tester = document.querySelector( '.container--chart' )
    const answer = document.querySelectorAll( '.percentage' )

    var IntervId = setInterval(
        handler = () => raf(() => {
            if (i>=11) {
                clearInterval(IntervId)
            }
            if (chartIsInView( tester )){
                animate(answer)
            }
        }
    ),500)

    handler()

    window.addEventListener( 'scroll', handler )
});

const raf = 
    window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    function( callback ) {
        window.setTimeout( callback, 1000 / 60 )
    }
.spacer{
    height: 1000px;
}
.container--chart
{
    display: flex;
    justify-content: space-between;
    height: 150px;
    width: 340px;
    align-items: flex-end;
}
.percentage
{
    height: 150px;
    width: 23px;
    border-radius: 2px;
    background: rgba(114,56,235,1);
    background: -moz-linear-gradient(top, rgba(114,56,235,1) 0%, rgba(219,208,246,1) 100%);
    background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(114,56,235,1)), color-stop(100%, rgba(219,208,246,1)));
    background: -webkit-linear-gradient(top, rgba(114,56,235,1) 0%, rgba(219,208,246,1) 100%);
    background: -o-linear-gradient(top, rgba(114,56,235,1) 0%, rgba(219,208,246,1) 100%);
    background: -ms-linear-gradient(top, rgba(114,56,235,1) 0%, rgba(219,208,246,1) 100%);
    background: linear-gradient(to bottom, rgba(114,56,235,1) 0%, rgba(219,208,246,1) 100%);
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7238eb', endColorstr='#dbd0f6', GradientType=0 );
}
.percentage--one
{
    max-height: 100%;

}
.percentage--two
{
    max-height: 133px;
    background:#E0D5F9;
}
.percentage--three
{
    max-height: 111px;

}
.percentage--four
{
    max-height: 87px;

}
.percentage--five
{
    max-height: 65px;
}
.percentage--six
{
    max-height: 55px;
}
.percentage--seven
{
    max-height: 45px;
}
.percentage--eight
{
    max-height: 35px;
}
.percentage--nine
{
    max-height: 25px;
}
.percentage--ten
{
    max-height: 20px;
}
.percentage--eleven
{
    max-height: 15px;
}
.percentage--twelve
{
    max-height: 10px;
}

.percentage
{
    -webkit-transition: max-height 1s; 
    -moz-transition: max-height 1s; 
    -ms-transition: max-height 1s; 
    -o-transition: max-height 1s; 
    transition: max-height 1s;  
    overflow: hidden;
    /* do animacji */
    /* max-height: 0; */
}
.percentage:hover{
    height: 500px;
}
.faded-colour{
    background: #EFEBFB;
}
.animate{
    max-height: 0;
}
<!-- <div class="spacer"></div> -->
<div class="holder">
    <div class="container--chart">
        <div class="percentage percentage--one animate"></div>
        <div class="percentage percentage--two animate"></div>
        <div class="percentage percentage--three faded-colour animate"></div>
        <div class="percentage percentage--four faded-colour animate"></div>
        <div class="percentage percentage--five faded-colour animate"></div>
        <div class="percentage percentage--six faded-colour animate"></div>
        <div class="percentage percentage--seven faded-colour animate"></div>
        <div class="percentage percentage--eight faded-colour animate"></div>
        <div class="percentage percentage--nine faded-colour animate"></div>
        <div class="percentage percentage--ten faded-colour animate"></div>
        <div class="percentage percentage--eleven faded-colour animate"></div>
        <div class="percentage percentage--twelve faded-colour animate"></div>
    </div>
</div>
<div class="spacer"></div>

1 Ответ

1 голос
/ 04 апреля 2019

1001 ** * codepen 1002 ** * 1003

const chartIsInView = el => {
    const scroll = window.scrollY || window.pageYOffset
    const boundsTop = el.getBoundingClientRect().top + scroll

    const viewport = {
        top: scroll,
        bottom: scroll + window.innerHeight,
    }

    const bounds = {
        top: boundsTop,
        bottom: boundsTop + el.clientHeight,
    }

    return ( bounds.bottom >= viewport.top && bounds.bottom <= viewport.bottom ) 
        || ( bounds.top <= viewport.bottom && bounds.top >= viewport.top );
}

var i = 0

function animate(e){
    e[i].classList.remove("animate")
    i++
}

document.addEventListener( 'DOMContentLoaded', () => {
  let handlerTriggered = false;
    const tester = document.querySelector( '.container--chart' )
    const answer = document.querySelectorAll( '.percentage' )

    var IntervId = setInterval(
        handler = () => raf(() => {
            if (i>=11) {
                clearInterval(IntervId)
            }
            if (chartIsInView( tester )){
                animate(answer)
            }
        }
    )
    ,500)

    handler()

    window.addEventListener( 'scroll', () => {
      if (!handlerTriggered) {
        handlerTriggered = true;
        handler();
      }
    } )
});

const raf = 
    window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    function( callback ) {
        window.setTimeout( callback, 1000 / 60 )
    }
Обработчик

() присоединен к событию прокрутки и часто запускается во время прокрутки. Добавьте логический флаг, чтобы проверить, запущен ли он.

...