2015-11-15 2 views
2

В настоящее время у меня есть несколько тегов div, которые можно увидеть ниже, каждый из которых является высотой области просмотра.Не удалось получить анимацию прокрутки, чтобы не запускать событие прокрутки

<!-- .current represents the div the user is currently viewing --> 
<div class="full-height current" id="id1"> 
    <div class="container"> 

    </div> 
</div> 

<div class="full-height" id="id2"> 
    <div class="container"> 
    </div> 
</div> 

<div class="full-height" id="id3"> 
    <div class="container"> 
    </div> 
</div> 

<div class="full-height" id="id4"> 
    <div class="container"> 
    </div> 
</div> 

<div class="full-height" id="id5"> 
    <div class="container"> 
    </div> 
</div> 

Я пытаюсь реализовать функцию, где при прокрутке пользователя, то окно будет перейти к следующему сНу тегу, всегда имея только один DIV в режиме одновременно. Способ, которым я его реализовал, отлично работает, за исключением того факта, что анимация снова запускает событие прокрутки, что приводит к бесконечному циклу прокрутки страницы, когда пользователь вообще прокручивается. Я попытался исправить это, указав переменную, которая остановит событие от запуска, если анимация выполняется, но она не работает. Я знаю, что я не делал этого для прокрутки вверх, но я просто хотел посмотреть, сработало ли оно сначала.

CSS прилагается на всякий случай. 100vh - 111px связано с фиксированной навигационной панели в верхней части, которая является 111px высокой

/* Makes the element take up the entire height of the screen */ 
.full-height{ 
    height: -o-calc(100vh - 111px); /* opera */ 
    height: -webkit-calc(100vh - 111px); /* google, safari */ 
    height: -moz-calc(100vh - 111px); /* firefox */ 
} 

#id1 { 
    background-color: red; 
} 
#id2 { 
    background-color: blue; 
} 

#id3 { 
    background-color: yellow; 
} 
#id4 { 
    background-color: green; 
} 

#id5 { 
    background-color: purple; 
} 

Если кто-то может дать мне какие-нибудь идеи для фиксации мою проблему, что было бы здорово.

+0

Нет '.current' элементы появляются в' html'? – guest271314

+0

@ guest271314 не уверен, что вы подразумеваете под этим – SpeedOfSmell

+0

'html' at Question, похоже, не содержит элементов, имеющих' class''.current', на который ссылается обработчик события 'scroll' – guest271314

ответ

1

Вы хотите остановить событие и предотвратить проблему. Вот код из текущей целевой страницы:

$(document).ready(function() { 
     $('a.page-scroll').on('click', function(event) { 
      var link = $(this); 
      $('html, body').stop().animate({ 
       scrollTop: $(link.attr('href')).offset().top - 50 
      }, 500); 
      event.preventDefault(); 
     }); 
     $('body').scrollspy({ 
      target: '.navbar-fixed-top', 
      offset: 80 
     }); 

    }); 

Он использует самозагрузку scrollspy так просто игнорировать это. Но обратите внимание, что он останавливает любую анимацию прокрутки, которая может быть запущена, а затем также вызывает event.preventDefault(), чтобы остановить событие прокрутки от барботажа и, таким образом, стать рекурсивным.

EDIT:

O.k. поэтому я лучше посмотрю и основная проблема: бесконечная прокрутка - это код, который не проверяет, находится ли scrollTop в «где он должен быть». Вам нужна дополнительная проверка короткого замыкания свитка:

if (animating == false) { 

     if ($(this).scrollTop() == lastScrollTop) return; 

     if (($(this).scrollTop() > lastScrollTop) && $(".current").next("div")) { 
     console.log("down"); 

     $(".current").next("div").addClass("current"); 
     $(".current").first().removeClass("current"); 

     animating = true; 
     $("html, body").stop().animate({ 
      scrollTop: $(".current").offset().top 
     }, 1000, 
     function() { lastScrollTop = $(this).scrollTop(); animating = false; }); 

     // If user scrolls up 
    } else { 
     if ($(".current").prev("div").length > 0) { 
      console.log("up"); 

      $(".current").prev("div").addClass("current"); 
      $(".current").last().removeClass("current"); 

      $("html, body").stop().animate({ 
       scrollTop: $(".current").offset().top 
      }, 1000, function() { lastScrollTop = $(this).scrollTop(); animating = false; }); 
     } 
    } 
} 

В противном случае, как он стоит, он всегда будет либо прокрутки вверх или вниз, и никогда не осесть. Тем не менее, «работа» - это ужасный пользовательский опыт. Это скажется, поскольку ваш свиток для кода будет бороться с пользователем на текущем scrollTop, если они будут продолжать прокрутку. т. е. ваш код заставит его вернуться к предыдущей позиции.

+0

Я немного не понимаю, как это реализовать. Я изменил '.animate()' на '.stop(). Animate()' и добавил 'event.preventDefault()', но он все равно прокручивается бесконечно, просто замедляя со временем. – SpeedOfSmell

1

Попробуйте определить scroll обработчик события как названная функция; определение lastScrollTop за пределами scroll обработчик; заменяя .one() на .on(), чтобы анимация завершилась до повторного присоединения scroll событие; используйте .promise(), который следует вызывать не более одного раза, чтобы избежать .animate()complete callback вызывается дважды с селектором "html, body"; заменяя одиночный if для проверки на следующий или предыдущий элемент .length и .animate() вызывать множественные if..else условия и заявления, вызовы анимационных функций; повторно не придает scroll события в .then() после завершения анимации .promise()

var lastScrollTop = 0; 
 

 
function scroller(event) { 
 

 
    var scrollTop = $(this).scrollTop(); 
 
    var direction = scrollTop > lastScrollTop ? "next" : "prev"; 
 
    var el = $(".current")[direction](".full-height"); 
 
    console.log(direction === "next" ? "down" : "up"); 
 
    if (el.is("*")) { 
 
    $("html, body").animate({ 
 
     scrollTop: el.offset().top 
 
    }, 1000).promise().then(function() { 
 
     console.log(this) 
 
     lastScrollTop = $(window).scrollTop(); 
 
     $(".current") 
 
     .removeClass("current")[direction]("div") 
 
     .addClass("current") 
 
     setTimeout(function() { 
 
     $(window).one("scroll", scroller) 
 
     }) 
 
    }); 
 
    } else { 
 
    lastScrollTop = scrollTop; 
 
    $(window).one("scroll", scroller) 
 
    } 
 
} 
 

 
$(window).one("scroll", scroller);
/* Makes the element take up the entire height of the screen */ 
 

 
.full-height { 
 
    height: -o-calc(100vh - 111px); 
 
    /* opera */ 
 
    height: -webkit-calc(100vh - 111px); 
 
    /* google, safari */ 
 
    height: -moz-calc(100vh - 111px); 
 
    /* firefox */ 
 
} 
 
#id1 { 
 
    background-color: red; 
 
} 
 
#id2 { 
 
    background-color: blue; 
 
} 
 
#id3 { 
 
    background-color: yellow; 
 
} 
 
#id4 { 
 
    background-color: green; 
 
} 
 
#id5 { 
 
    background-color: purple; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<!-- .current represents the div the user is currently viewing --> 
 
<div class="full-height current" id="id1"> 
 
    <div class="container"> 
 

 
    </div> 
 
</div> 
 

 
<div class="full-height" id="id2"> 
 
    <div class="container"> 
 
    </div> 
 
</div> 
 

 
<div class="full-height" id="id3"> 
 
    <div class="container"> 
 
    </div> 
 
</div> 
 

 
<div class="full-height" id="id4"> 
 
    <div class="container"> 
 
    </div> 
 
</div> 
 

 
<div class="full-height" id="id5"> 
 
    <div class="container"> 
 
    </div> 
 
</div>

+1

@Shikkediel Просмотреть обновленный пост; включал '' html '' selector, replace' .promise(). then() 'для' .animate() '' complete' callback function – guest271314

Смежные вопросы