My .scrollBottom button works, but once it auto scrolls to the bottom I can't manually scroll back up because it is active and constantly scrolling down. What does it need for it scroll to absolute bottom and then STOP?
JavaScript
var timeOut;
function scrollToBottom() {
if (document.body.scrollBottom!=0 || document.documentElement.scrollBottom!=0){
window.scrollBy(0,20);
timeOut=setTimeout('scrollToBottom()',10);
}
else clearTimeout(timeOut);
}
HTML
BUTTON
I found that by removing the timeOut=setTimeout('scrollToBottom()',10);
the button scrolls down by 20 pixels on press.
With that information - I changed the window.scrollBy(0,20); to a ridiculous number like: window.scrollBy(0,2000000);
so I got this code:
var timeOut;
function scrollToBottom() {
document.body.scrollBottom!=0 || document.documentElement.scrollBottom!=0
window.scrollBy(0,2000000);
}
And paired with
html {
scroll-behavior: smooth;
}
It does the trick :)
Related
Context
I am working on a one-page website where the fixed navigation's class changes as it scrolls through the different sections in order to match the section's background color. To achieve this effect, I used and modified the 2nd solution listed here.
Issue
While it works great most of the time, the navigation code breaks when I resize the browser (or leave the page and click back). More specifically, the navigation's background color changes too early or too late and no longer matches the section's background.
I'm guessing that this happens because the section's height are calculated on page load. Ideally, they would be recalculated on every scroll - but I am a novice and that's just a guess. Any help to solve this issue would be appreciated.
JavaScript
FYI: there are four sections in the websites (Hero, Work, About, Contact). Navigation's bg color should be transparent in Hero, white in Work and Contact, and teal in About.
var afterhero = $('#hero-section').offset().top + $('#hero-section').height();
var afterwork = afterhero + $('#work-section').height();
var afterabout = afterwebsites + $('#about-section').height();
$(window).on('scroll', function() {
stop = Math.round($(window).scrollTop());
if (stop > afterabout) {
$('header').removeClass('teal');
$('header').addClass('white');
} else if (stop > afterwork) {
$('header').addClass('teal');
} else if (stop > afterhero) {
$('header').removeClass('teal');
$('header').addClass('white');
} else {
$('header').removeClass('teal');
$('header').removeClass('white');
}
});
Just try adding all your size variables into your scroll event handler:
$(window).on('scroll', function() {
var afterhero = $('#hero-section').offset().top + $('#hero-section').height();
var afterwork = afterhero + $('#work-section').height();
var afterabout = afterwebsites + $('#about-section').height();
stop = Math.round($(window).scrollTop());
if (stop > afterabout) {
$('header').removeClass('teal');
$('header').addClass('white');
} else if (stop > afterwork) {
$('header').addClass('teal');
} else if (stop > afterhero) {
$('header').removeClass('teal');
$('header').addClass('white');
} else {
$('header').removeClass('teal');
$('header').removeClass('white');
}
});
Now afterhero, afterwork and afterabout should all be recalculated on a page scroll.
When i am using the above function in javascript div to auto scroll in chat box
but i am not able to scroll up to bottom.
window.setInterval(function() {
var elem = document.getElementById('chatlog');
elem.scrollTop = elem.scrollHeight;
}, 10);
The chatlog is a div in my code and I have put above function to scroll the replies. Now I cannot scroll up.
This is logical mistake. In your code every 10 ms your script will scroll div to bottom. There are many variants how to implement autoscroll behaviour. One of them use flag, which will set up by checkBox (autoscroll). If checkBox is selected script will scroll down, if deselected script will do nothing.
Something like:
window.setInterval(function() {
if (needAutoScroll) {
var elem = document.getElementById('chatlog');
elem.scrollTop = elem.scrollHeight;
}
}, 10);
My guess is , since it is scrolling down to the bottom of the div every second , you are not able to scroll up. So on scroll up you have to clear the setInterval function.
You can try this in you chatlog div.
<div id="chatlog" onscroll="myStopFunction()">
function myStopFunction() {
if document.body.scrollTop <= 0 {
console.log("scrolling down")
} else {
console.log("scrolling up");
clearInterval(myVar);
}
}
Again on scroll down you can trigger the setInterval function.
Is there a way to get elements which is:
Inside a div with overflow: scroll
Is in viewport
Just like the following picture, where active div (5,6,7,8,9) is orange, and the others is green (1-4 and >10) :
I just want the mousewheel event to add "active" class to div 5,6,7,8,9 (currently in viewport). View my JSFiddle
$('.wrapper').bind('mousewheel', function (e) {
//addClass 'active' here
});
You could do something like this. I would have re-factored it, but only to show the concept.
Firstly I would attach this to scroll event and not mousewheel. There are those among us that likes to use keyboard for scrolling, and you also have the case of dragging the scrollbar. ;) You also have the case of touch devices.
Note that with this I have set overflow:auto; on wrapper, thus no bottom scroll-bar.
With bottom scrollbar you would either have to live with it becoming tagged as in-view a tad to early, or tumble into the world of doing a cross-browser calculating of IE's clientHeight. But the code should hopefully be OK as a starter.
»»Fiddle««
function isView(wrp, elm)
{
var wrpH = $(wrp).height(),
elmH = $(elm).height(),
elmT = $(elm).offset().top;
return elmT >= 0 &&
elmT + elmH < wrpH;
}
$('.wrapper').bind('scroll', function (e) {
$('div.box').each(function(i, e) {
if (isView(".wrapper", this)) {
$(this).addClass('active');
} else {
$(this).removeClass('active');
}
});
});
Note that you should likely refactor in such a way that .wrapper height is only retrieved once per invocation, or if it is static, at page load etc.
Update; a modified version of isView(). Taking position of container into account. This time looking at dolphins in the pool.
»»Fiddle««
function isView(pool, dolphin) {
var poolT = pool.offset().top,
poolH = pool.height(),
dolpH = dolphin.height(),
dolpT = dolphin.offset().top - poolT;
return dolpT >= 0 && dolpT + dolpH <= poolH;
}
I'm currently using a combination of smooth scroll and IDs/anchor tags to scroll to content on my site. The code below is getting the ID of the next 'section' in the DOM, and adding it's ID as the 'view next section' href, so once it's clicked, it'll scroll to the top of that div. Then, it iterates through, updating the href with the next ID each time etc until the last section is seen and it scrolls back to the top. Pretty straightforward.
The only problem is that the 'sections' are fullscreen images, so as it's scrolling to the top of the next section, if you resize the browser, the top position of that section (where we scrolled to) has moved, and means the position is lost.
I've created a JSFiddle. You can see this happening after you click the arrow to visit the next section then resize the window: http://jsfiddle.net/WFQ9t/3/
I'm wanting to keep this top position fixed at all times so even if you resize the browser, the scroll position is updated to reflect this.
Thanks in advance,
R
var firstSectionID = $('body .each-section').eq(1).attr('id');
$('.next-section').attr('href', '#' + firstSectionID);
var i = 1;
$('.next-section').click(function() {
var nextSectionID = $('body .each-section').eq(i).attr('id');
i++;
$('.next-section').attr('href', '#' + nextSectionID);
var numberOfSections = $('body .each-section').length;
var lastSectionID = $('body .each-section').eq(numberOfSections).attr('id');
if ($('.next-section').attr('href') == '#' + lastSectionID ) {
$('.next-section').attr('href', '#introduction');
i = 1;
}
});
Ok, Please check out this fiddle: http://jsfiddle.net/WFQ9t/9/
The few things I did were:
Made some global variables to handle the screen number (which screen you're on and also the initial window height. You will use this when the screen loads and also when you click on the .next-session arrow.
var initWinHeight = $(window).height();
var numSection = 0;
Then I tossed those variables into your resizeContent() function
resizeContent(initWinHeight, numSection)
so that it will work on load and resize
I made the body move around where it needs to, to accomodate for the movement of the divs (I still don't understand what divs are moving when the regular animation happens).
$('body').css({
top: (((windowHeight - initWinHeight)*numSection)*-1) + "px"
});
Then in your click function, I add 1 to the section number, reset the initial window height and then also reset the body to top:0. The normal animation you have already puts the next section at the top of the page.
numSection++;
initWinHeight = $(window).height();
$('body').css({top:"0px"}, 1000);
Finally, I reset the numSections counter when you reach the last page (You might have to make this 0 instead of 1)
numSection = 0;
The fiddle has all of this in the correct places, these are just the steps I took to change the code.
Here is a solution that i found, but I dont use anchor links at this point, i use classes
Here is my HTML code:
<section class="section">
Section 1
</section>
<section class="section">
Section 2
</section>
<section class="section">
Section 3
</section>
<section class="section">
Section 4
</section>
And here is my jQuery/Javascript code,
I actually used a preety simple way:
$('.section').first().addClass('active');
/* handle the mousewheel event together with
DOMMouseScroll to work on cross browser */
$(document).on('mousewheel DOMMouseScroll', function (e) {
e.preventDefault();//prevent the default mousewheel scrolling
var active = $('.section.active');
//get the delta to determine the mousewheel scrol UP and DOWN
var delta = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? 1 : -1;
//if the delta value is negative, the user is scrolling down
if (delta < 0) {
next = active.next();
//check if the next section exist and animate the anchoring
if (next.hasClass('section')) {
var timer = setTimeout(function () {
$('body, html').animate({
scrollTop: next.offset().top
}, 800);
next.addClass('active')
.siblings().removeClass('active');
clearTimeout(timer);
}, 200);
}
} else {
prev = active.prev();
if (prev.length) {
var timer = setTimeout(function () {
$('body, html').animate({
scrollTop: prev.offset().top
}, 800);
prev.addClass('active')
.siblings().removeClass('active');
clearTimeout(timer);
}, 200);
}
}
});
/*THE SIMPLE SOLUTION*/
$(window).resize(function(){
var active = $('.section.active')
$('body, html').animate({
scrollTop: active.offset().top
}, 10);
});
so I have this javascript:
$(window).scroll(function () {
if ($(window).scrollTop() > 0 && !document.contains(document.getElementById('toTop'))) {
var top = '<div id="toTop" onclick="tTop()"></div>';
$('body').append(top);
}
});
function tTop() {
$('html,body').scrollTop(0);
}
$(window).scroll(function () {
if (document.contains(document.getElementById('toTop')) && $(window).scrollTop() == 0) {
$('div').remove('#toTop');
}
});
It works just fine if the page is loaded while the scroll bar is at the top; however when I refresh the page while the scroll bar is at the bottom, the page will still scroll up, but the scroll stays at the bottom. Can anyone tell me how to fix this?
when I refresh the page while the scroll bar is at the bottom, the
page will still scroll up, but the scroll stays at the bottom
Maybe I'm misreading this, but are you concerned that the buttons are staying at the bottom of the page? Or $(window).scrollTop() is set to 0 after you click the button, after a page refresh?
Regardless, I would separate the scroll callback to another method, checking if the element exists (I used a button for an example instead of a div)
function scrollCallback() {
if ($(window).scrollTop() > 0) {
if ($('body').has('#toTop').length == false) {
var top = '<input type="button" id="toTop" onclick="tTop();" value="top" />';
$('body').append(top);
}
}
else {
// Removes the button if the scroll is at the top of the page.
$('body #toTop').remove();
}
}
Then on your page load, call the scrollCallback, and set your scroll to also use the scroll back:
$(function() {
// Execute it when you load the page.
scrollCallback();
$(window).scroll(scrollCallback);
});