Detect scrolling - scroll to div - javascript

I'm trying to make a site whereby when the user starts to scroll it automatically scrolls them (not jump) to a set position, so that content can be seen. The content is already there on the page I just dont want them to scroll to it so as soon as they start to move down the page it will help them by scrolling to a set point.
This is what I had so far but I got lost:
<script type="text/javascript">
$(body).scroll(function() {
if ( $this).scrollTop() > 1 ) {
}
});
</script>

Here's a fiddle
var scrollFunction = function() {
$('html, body').not(':animated').animate({
scrollTop: $("#layer-2").offset().top //gets the position of the next layer
}, 1000, function() {
$(document).off('scroll', scrollFunction)
});
}
$(document).on('scroll', scrollFunction);

You can bind your element with scrollstart (also there is a scrollstop) event:
jQuery('#yourElementId').bind("scrollstart",scrollFunc);
var scrollFunc = function(){
//if(jQuery('#yourElementId').scrollTop()>1) //unnecessary
jQuery('#yourElementId').scrollTop(300); // change 300 to any number you want
}

Related

How to exclude "animate" from addEventListener "scroll"?

I have this problem I can't wrap my head around:
I am checking if the user is scrolling the page after using the search form. In which case, the search form should unfocus, with:
var content = document.querySelector('.content');
content.addEventListener("scroll", function(e) {
$("#search_box").blur();
});
Now, I also want the page to always scroll the content to the top as the user is typing, with:
$('#search_box').keyup(function() {
$('.content').animate({
scrollTop: 0
});
}
As you can see, this creates a problem. The user is typing, the page scrolls automatically to the top and the search box unfocuses basically on every letter being typed, which is super annoying.
Is there any easy way to exclude scrollTop or .animate from the addEventListener?
I want the user being able to type, have the content scrolled to the top and when they click anywhere on the page (scrolling down manually), the search box should unfocus.
You could make the search box only lose focus if the page is being scrolled down:
var content = document.querySelector('.content');
var currentPos = content.scrollTop;
content.addEventListener('scroll', function(e) {
if (content.scrollTop > currentPos) {
$('#search_box').blur();
}
currentPos = content.scrollTop;
});
You could refocus on the search box after the animation is complete:
$('#search_box').keyup(function() {
$('.content').animate({
scrollTop: 0
}, function() {
$('#search_box').focus();
});
}

Scrolling to anchors unpredictable

I am trying to build a simple vertical timeline. You can click up or down to scroll it little by little but I also wanted to have it jump, smooth scroll, to anchors. This somewhat works but the behavior is unpredictable.
This isn't usually difficult but something new for me is that the scrolling behavior is inside a div so the whole page shouldn't be moving.
You can try it in the fiddle. Clicking random buttons will sometimes bring you to the right spot, other times it will just scroll to a random place.
JSFiddle
Here is the basic Jquery.
var step = 280;
var scrolling = false;
$(".scrollUp").bind("click", function (event) {
event.preventDefault();
$("#timeline").animate({
scrollTop: "-=" + step + "px"
});
})
$(".scrollDown").bind("click", function (event) {
event.preventDefault();
$("#timeline").animate({
scrollTop: "+=" + step + "px"
});
})
$('.timelineButton').click(function () {
$('#timeline').animate({
scrollTop: $($(this).attr('href')).offset().top
}, 2000);
return false;
});
A few things need fixing :
Use .position().top (relative to offset parent) instead of .offset().top (relative to document)
Specify the offset parent by styling the #timeline container with position: relative
Because .position() returns dynamically calculated values, .position().top will be the value-you-want minus the current-scrollTop. Therefore you need to add the current-scrollTop back on.
CSS
#timeline {
...
position: relative;
}
Javascript
$('.timelineButton').click(function (event) {
event.preventDefault();
$('#timeline').animate({
scrollTop: $($(this).attr('href')).position().top + $('#timeline').scrollTop()
}, 2000);
});
Demo
Add Ids to each div & use that ID like href="#ID". This will scroll window to that particular section ID given in href
Check this
$('.timelineButton').click(function () {
if($('#timeline').is(':animated')){}else{
$('#timeline').animate({
scrollTop: $($(this).attr('href')).offset().top
}, 2000);
return false;
}
});
.is(':animated') will be tell you if the element is animating, if not, animate it.
It prevent the unpredictable jumps.
EDIT
Best way to prevent this is: .stop().animate
$('.timelineButton').click(function () {
$('#timeline').stop().animate({
scrollTop: $($(this).attr('href')).offset().top
}, 2000);
return false;
});
EDIT V2
Check this Fiddle: https://jsfiddle.net/a489mweh/3/
I have to put the position offset of each elements in an array, becouse every animate in timeline change the offset.top of each element.Check the data-arr="0" over each button, to tell the array what position of the element have to retrieve.Tell me if works.
Cheers

Scroll Up/Down want to slide in parts not in once

I am using a slider on my web page for that i used jQuery Function
to scroll down
jQuery("#downClick").click(function() {
jQuery("html, body").animate({ scrollTop: jQuery(document).height() }, "slow");
});
to scroll up
jQuery("#upClick").click(function(){ //Click event to scroll to top ==>> Slider
jQuery('html, body').animate({scrollTop : 0},800);
return false;
});
My page is having too much data to display, so when a person clicks on this buttons either he navigates to bottom or top in once.
Does anybody can suggest me how can i change to something like if i want to scroll up it will scroll up with multiple steps not in once.
$('#upClick').on('click', function() {
var scrollIndex = $(window).scrollTop(); // current page position
$(window).scrollTop(y - 150); // scroll up 150px
}
refer this!

Why does my scroll function trigger on page load?

I'm trying to create a simple scroll effect where the page header hides when the page scrolls down and reappears on scroll up. The HTML:
<header class="siteHeader">...</header>
...is hidden by applying the CSS class "siteHeader--up."
I'm using jQuery. Here is my code:
$(function () {
var $siteHeader = $('.siteHeader');
var $window = $(window);
// to determine scroll direction. initializes to 0 on page load
var scrollReference = 0;
function fixedHeader () {
var scrollPosition = $window.scrollTop();
// if page is scrolling down, apply the CSS class
if (scrollPosition > scrollReference)
{
$siteHeader.addClass('siteHeader--up');
}
// otherwise, page is scrolling up. Remove the class
else
{
$siteHeader.removeClass('siteHeader--up');
}
// update reference point to equal where user stopped scrolling
scrollReference = scrollPosition
}
$window.scroll(function () {
fixedHeader();
});
});
This works fine for the most part. The problem is when I scroll down the page and then refresh the page. Somehow the scroll function is being triggered. The header will be visible for a moment and then hide (as though the page thinks it's being scrolled down). The function is being triggered on page load (confirmed with a console.log), but I don't understand why, because it's only supposed to fire on scroll.
Can someone help me understand what's going on and how I can prevent it?
Thanks!
That is the expected behavior. When the page is refreshed, the browser remembers the scroll position and it scrolls the page to that position, later on the scroll event is fired.
I think that this could be a workaround to solve your problem:
When the jQuery scroll event is fired you can get the timeStamp property and if this timeStamp is very close to the window.onload timeStamp, surely it can't be an event triggered by the user:
I've used a value of 50 milliseconds, test if it is sufficient, I think that it is.
var startTime = false;
$(function () {
var $siteHeader = $('.siteHeader');
var $window = $(window);
// to determine scroll direction. initializes to 0 on page load
var scrollReference = 0;
function fixedHeader () {
var scrollPosition = $window.scrollTop();
// if page is scrolling down, apply the CSS class
if (scrollPosition > scrollReference)
{
$siteHeader.addClass('siteHeader--up');
}
// otherwise, page is scrolling up. Remove the class
else
{
$siteHeader.removeClass('siteHeader--up');
}
// update reference point to equal where user stopped scrolling
scrollReference = scrollPosition
}
$window.on("load", function (evt) {
startTime = evt.timeStamp;
});
$window.on("scroll", function (evt) {
if(!startTime || evt.timeStamp - startTime < 50) return;
fixedHeader();
});
});
Try Loading the function on window load as well as in the scroll function:
$window.load(function(){
fixedHeader();
});
Or on document ready maybe:
$(document).ready(function () {
fixedHeader();
});
This should trigger and reset the values in the Variables you made and therefore determine whether to set the header to fixed or not, regardless of the scroll position.
Let me know if it works because i'm kinda curious too :)

Full page slider with native scrollbar

I am building a full page slider that keeps the native scrollbar and allows the user to either free scroll, use the mouse wheel or navigation dots (on the left) to switch to a slide.
Once the user is on the last slide and tries to scroll down further, the whole slider moves up to reveal a simple scrollable section. If the user scrolls down and then tries to go back up, then this new section moves out of the way again and returns the slider back into view.
Fiddle: http://jsfiddle.net/3odc8zmx/
The parts I'm struggling with:
Only the first two navigation dots work. The third one DOES WORK if you area looking at the first slide. But doesn't do anything, if you are on slide 2. Note: the purple one is a short-cut to the second section of the page and not related to the slider.
When moving to the last slide (via the dots, if you're on the first slide) it causes the code to make the whole slider move upwards as it sees this as the user has slid past the last slide as per the description above. I have tried to combat this using a variable called listen to stop the scroll event listening when using the showSlide method... but it seems to be true even though I set it to false, and only reset it to true again after the animation...
When scrolling down using the mouse wheel, I can get to the second section and back up, but not to the first third section. I'm wondering if I could use the showSlide method to better handle this instead of the current dirty next and prev functions I have implemented.
Note: If the user has free-scrolled, when they use the mouse-wheel, I want the slider to snap to the nearest slide to correct itself... Any suggestions for how I could do this?
Can anyone offer some help?
Here's the JS:
var listen = true;
function nextSlide()
{
$('#section1').stop(true,false).animate({
scrollTop: $('#section1').scrollTop() + $(window).height()
});
}
function prevSlide()
{
$('#section1').stop(true,false).animate({
scrollTop: -$('#section1').scrollTop() + $(window).height()
});
}
function showSlide(index)
{
var offset = $('#section1 div').eq(index).offset();
offset = offset.top;
if(offset){
listen = false;
$('.slide-dot').removeClass('active');
$('.slide-dot').eq(index).addClass('active');
$('#section1').stop(true,false).animate({
scrollTop: offset
}, 500, function(){
listen = true;
});
} else {
alert('error');
}
}
$(document).ready(function(){
var fullHeight = 0;
$('#section1 div').each(function(){
fullHeight = fullHeight + $(this).height();
});
var lastScrollTop1 = 0;
$('#section1').on('scroll', function(e){
var st = $(this).scrollTop();
if (st > lastScrollTop1){
if( $('#section1').scrollTop() + $(window).height() == fullHeight) {
if(listen){
$('body').addClass('shifted');
}
}
}
lastScrollTop1 = st;
});
$('#section1').on('mousewheel', function(e){
e.preventDefault();
var st = $(this).scrollTop();
if (st > lastScrollTop1){
nextSlide();
} else {
prevSlide();
}
});
var lastScrollTop2 = 0;
$('#section2').on('scroll', function(e){
var st = $(this).scrollTop();
if (st > lastScrollTop1){
} else {
if( st == 0 ){
$('body').removeClass('shifted');
}
}
lastScrollTop1 = st;
});
$('.slide-dots').css({'margin-top':-$('.slide-dots').height() / 2});
$('.slide-dot').first().addClass('active');
$(document).on('click', '.slide-dot', function(e){
e.preventDefault();
showSlide( $(this).index() );
});
$(document).on('click', '.slide-dot-fake', function(e){
e.preventDefault();
$('body').addClass('shifted');
});
});
And for those wondering why I'm not using something like fullPage.js, it's because it can't handle the way I want to transition between the two areas and have two scrollbars (one for each area).
You can use:
e.originalEvent.wheelDelta
instead of:
st > lastScrollTop1
in the mousewheel event for your third problem to check if the user has scrolled up or down. And also change the +/- in prevSlide. I used dm4web's fiddle for your first problem. And I used:
scrollTop: offset - 1
instead of:
scrollTop: offset
for your second problem, because when the scroll reaches to the last pixel of the third element, it automatically goes to the next section, so 1 pixel is enough for it not to.
Here's the fiddle: http://jsfiddle.net/3odc8zmx/3/
As suggested by #chdltest, you could do it by using fullPage.js.
Here's an example. Go to the last section.
Code used for the example:
Javascript
$('#fullpage').fullpage({
sectionsColor: ['yellow', 'orange', '#C0C0C0', '#ADD8E6'],
scrollOverflow: true,
scrollBar: true,
afterLoad: function (anchor, index) {
//hiding the main scroll bar
if (index == 4) {
$('body, html').css('overflow', 'hidden');
}
//showing the main scroll bar
if (index == 3) {
$('body, html').css('overflow', 'visible');
}
}
});
CSS (in case you prefer to use the normal style for it)
/* Normal style scroll bar
* --------------------------------------- */
.slimScrollBar {
display: none !important;
}
.fp-scrollable {
overflow: auto !important;
}
Advantages of using fullPage.js instead to your own code:
Strongly tested in different devices and browsers. (IE, Opera, Safari, Chrome, Firefox..)
Prevent problems with trackpads, Apple laptops trackpads or Apple Magic Mouse.
Old browser's compatibility, such as IE 8, Opera 12...
Touch devices compatibility (IE Windows Phone, Android, Apple iOS, touch desktops...)
It provides many other useful options and callbacks.

Categories

Resources