how to fix loop "go to bottom" when i scroll top - javascript

After you click Go To Bottom then roll the mouse over it just automatically roll down it? way still uses the setInterval without fail no summer?
link source code
http://jsfiddle.net/trananh/v7gdr4n0/
var process;
var delay = 50;
var scrollPixel = 20;
//Fix Undefine pageofset when using IE 8 below;
function getPapeYOfSet() {
var yOfSet = (typeof (window.pageYOffset) === "number") ? window.pageYOffset : document.documentElement.scrollTop;
return yOfSet;
}
function goToBottom() {
process = setInterval(function () {
var yOfSet = getPapeYOfSet();
if (yOfSet >= document.body.scrollHeight) {
clearInterval(process);
} else {
window.scrollBy(0, scrollPixel);
}
}, delay);
}
JAvascript function goToBottom

Related

How to get the second animation to start, only after the first animation has finished using Javascript callbacks?

I have two animations which both work, but I'd like to have it so the second animation starts only after the first animation has finished, I tried this with Javascript callbacks but can't seem to get it to work. I'm sure someone can show me how to do this. There must be other ways to do this too? I'd be really interested to find out what they are actually. It's amazing how many different ways there are too do things isn't it.
document.addEventListener("DOMContentLoaded", first, false);
var obj, height, goUp;
function first() {
obj = document.getElementById("thetext");
obj.style.position = "absolute";
obj.style.bottom = "10px";
height = document.body.clientHeight;
goUp = true
second();
}
function second() {
var pos = parseInt(obj.style.bottom, 10);
(goUp) ? pos++ : pos--;
obj.style.bottom = pos + "px";
if (pos < 0) {
goUp = true;
}
if (pos > height) {
goUp = false;
}
if (pos < 0) {
return;
}
setTimeout(second, 10);
}
var objz, width, goRight;
function animatefirst() {
objz = document.getElementById("tues");
objz.style.position = "absolute";
objz.style.left = "10px";
objz.style.bottom = "10px";
width = document.body.clientWidth;
goRight = true;
animatesecond();
}
function animatesecond() {
var position = parseInt(objz.style.left, 10);
(goRight) ? position++ : position--;
objz.style.left = position + "px";
if (position > width) {
goRight = false;
}
if (position < 0) {
goRight = true;
}
if (position < 0) {
return;
}
setTimeout(animatesecond, 10);
}
<body>
<p id="thetext">ANIMATION </p>
<p id="tues"> Tuesday</p>
</body>
I fixed this issue in a simple way, I just put my call to the next function just before the return; which closes the current function. So the call to the next function is not inserted until the part in the code where the first function has finished, to avoid overlapping functions. I'm surprised no one could help with this, but it must be a very busy site :)
if (pos < 0) {
nextfunction();
return;
}

Creating a simple "smooth scroll" (with javascript vanilla)

I have been trying to make a simple "smoothscroll" function using location.href that triggers on the mousewheel. The main problem is that the EventListener(wheel..) gets a bunch of inputs over the span of ca. 0,9 seconds which keeps triggering the function. "I only want the function to run once".
In the code below I have tried to remove the eventlistener as soon as the function runs, which actually kinda work, the problem is that I want it to be added again, hence the timed function at the bottom. This also kinda work but I dont want to wait a full second to be able to scroll and if I set it to anything lover the function will run multiple times.
I've also tried doing it with conditions "the commented out true or false variables" which works perfectly aslong as you are only scrolling up and down but you cant scroll twice or down twice.
window.addEventListener('wheel', scrolltest, true);
function scrolltest(event) {
window.removeEventListener('wheel', scrolltest, true);
i = event.deltaY;
console.log(i);
if (webstate == 0) {
if (i < 0 && !upexecuted) {
// upexecuted = true;
location.href = "#forside";
// downexecuted = false;
} else if (i > 0 && !downexecuted) {
// downexecuted = true;
location.href = "#underside";
// upexecuted = false;
}
}
setTimeout(function(){ window.addEventListener('wheel', scrolltest, true); }, 1000);
}
I had hoped there was a way to stop the wheel from constantly produce inputs over atleast 0.9 seconds.
"note: don't know if it can help in some way but when the browser is not clicked (the active window) the wheel will registre only one value a nice 100 for down and -100 for up"
What you're trying to do is called "debouncing" or "throttling". (Those aren't exactly the same thing, but you can look up the difference in case it's going to matter to you.) Functions for this are built into libraries like lodash, but if using a library like that is too non-vanilla for what you have in mind, you can always define your own debounce function: https://www.geeksforgeeks.org/debouncing-in-javascript/
You might also want to look into requestanimationframe.
a different approach
okey after fiddeling with this for just about 2 days i got fustrated and started over. no matter what i did the browsers integrated "glide-scroll" was messing up the event trigger. anyway i decided to animate the scrolling myself and honestly it works better than i had imagined: here is my code if anyone want to do this:
var body = document.getElementsByTagName("BODY")[0];
var p1 = document.getElementById('page1');
var p2 = document.getElementById('page2');
var p3 = document.getElementById('page3');
var p4 = document.getElementById('page4');
var p5 = document.getElementById('page5');
var whatpage = 1;
var snap = 50;
var i = 0;
// this part is really just to read what "page" you are on if you update the site. if you add more pages you should remember to add it here too.
window.onload = setcurrentpage;
function setcurrentpage() {
if (window.pageYOffset == p1.offsetTop) {
whatpage = 1;
} else if (window.pageYOffset == p2.offsetTop) {
whatpage = 2;
} else if (window.pageYOffset == p3.offsetTop) {
whatpage = 3;
} else if (window.pageYOffset == p4.offsetTop) {
whatpage = 4;
} else if (window.pageYOffset == p5.offsetTop) {
whatpage = 5;
}
}
// this code is designet to automaticly work with any "id" you have aslong as you give it a variable called p"number" fx p10 as seen above.
function smoothscroll() {
var whatpagenext = whatpage+1;
var whatpageprev = whatpage-1;
var currentpage = window['p'+whatpage];
var nextpage = window['p'+whatpagenext];
var prevpage = window['p'+whatpageprev];
console.log(currentpage);
if (window.pageYOffset > currentpage.offsetTop + snap && window.pageYOffset < nextpage.offsetTop - snap){
body.style.overflowY = "hidden";
i++
window.scrollTo(0, window.pageYOffset+i);
if (window.pageYOffset <= nextpage.offsetTop + snap && window.pageYOffset >= nextpage.offsetTop - snap) {
i=0;
window.scrollTo(0, nextpage.offsetTop);
whatpage += 1;
body.style.overflowY = "initial";
}
} else if (window.pageYOffset < currentpage.offsetTop - snap && window.pageYOffset > prevpage.offsetTop + snap){
body.style.overflowY = "hidden";
i--
window.scrollTo(0, window.pageYOffset+i);
if (window.pageYOffset >= prevpage.offsetTop - snap && window.pageYOffset <= prevpage.offsetTop + snap) {
i=0;
window.scrollTo(0, prevpage.offsetTop);
whatpage -= 1;
body.style.overflowY = "initial";
}
}
}
to remove the scrollbar completely just add this to your stylesheet:
::-webkit-scrollbar {
width: 0px;
background: transparent;
}

How to remove jank when setting an element to a fixed position using JavaScript

I have a webpage that when scrolled down, the text freezes when it reaches the last paragraph of text but the images keep on scrolling. I've got the implementation working but there is a lot of jank when scrolling with a mouse wheel, not so much if I click and drag the scroll bar.
Are there any optimizations I can make to this code to make work as intended or is there a different way to accomplish the same task?
window.addEventListener('scroll', function (e) {
window.requestAnimationFrame(keepTextStationary);
//keepTextStationary(); // Less janky, but still horrible
});
function keepTextStationary() {
var textRect = writtenContent.getBoundingClientRect();
var imageRec = images.getBoundingClientRect();
if (textRect.bottom < window.innerHeight && document.documentElement.scrollTop > 0) {
writtenContent.style.position = 'relative';
writtenContent.style.bottom = (225 - document.documentElement.scrollTop) + 'px';
if (imagesTop === undefined) {
imagesTop = imageRec.y;
}
} else {
writtenContent.style.bottom = (225 - document.documentElement.scrollTop) + 'px';
}
if (imageRec.y >= imagesTop) {
writtenContent.style.position = '';
}
}
Here is the site so you can see the problem.
https://bowerbankninow.azurewebsites.net/exhibitions/oscar-perry-the-pheasant
You are causing layout trashing every time you call getBoundingClientRect. Try debouncing your scroll events:
var lastScrollY = 0;
var ticking = false;
function keepTextStationary() {
var textRect = writtenContent.getBoundingClientRect();
var imageRec = images.getBoundingClientRect();
if (textRect.bottom < window.innerHeight && lastScrollY > 0) {
writtenContent.style.position = 'relative';
writtenContent.style.bottom = (225 - lastScrollY) + 'px';
if (imagesTop === undefined) {
imagesTop = imageRec.y;
}
} else {
writtenContent.style.bottom = (225 - lastScrollY) + 'px';
}
if (imageRec.y >= imagesTop) {
writtenContent.style.position = '';
}
ticking = false;
}
function onScroll() {
lastScrollY = document.documentElement.scrollTop;
requestTick();
}
function requestTick() {
if (!ticking) {
requestAnimationFrame(keepTextStationary);
ticking = true;
}
}
window.addEventListener('scroll', onScroll );
See this article for in-depth explanation: https://www.html5rocks.com/en/tutorials/speed/animations/
You dont.
Relocations / styling in javascript take place after the CSS has been loaded. Bad practise. What you can do, is make it animated to make it look less horrible.
Why is pure CSS not an option ?

Jquery typing effect on scroll bug

Hi I have some js code that do typing effect on my web page it start typing when you scroll down end of page. For first it work normally but when you start scroll faster down to up the typing effect goes crazy how can I fix that
demo page
code
$(window).scroll(function (e) {
var elem = $(".hello-page");
var scrollTop = $(window).scrollTop();
var blockTop = elem.offset().top;
var docHeight = $(document).height();
var windowH = $(window).height();
if (scrollTop >= blockTop) {
var helloPageA = $(".hello-page").find("a");
var text = helloPageA.attr("data-text");
helloPageA.text('');
$.each(text.split(''), function (i, letter) {
setTimeout(function () {
helloPageA.html(helloPageA.html() + letter);
}, 150 * i);
});
} else {
elem.find("a").text('');
}
});
jsfiddle example
Thanks for your help
So, here is the solution - http://jsfiddle.net/u3ojjx8r/1/
I borrowed initial structure of the code from previous answer here and it was removed unfortunately, therefore I can't mention one of the co-authors. Though the code looked quite similar to topic-starter's one.
The idea of the code below is to separate the queuing of characters to render and the actual rendering. Another important improvement is always have control over timeouts, i.e. never schedule more than one timeout. That allows you to cancel them any time without unpredicted/uncontrolled behavior.
var timeoutVar;
var queue = [];
var drawQueueTimeout = -1;
var helloPageA = $(".hello-page").find("a");
function pushQueue (element) {
console.log('pushQUeue', element.char);
queue.push(element);
checkQueue();
}
function flushQueue () {
console.log('flushQueue');
queue = [];
clearTimeout(drawQueueTimeout);
drawQueueTimeout = -1;
}
function checkQueue () {
console.log('checkQueue', queue.length, drawQueueTimeout);
if (queue.length > 0 && drawQueueTimeout < 0) {
console.log('schedule drawQueue');
drawQueueTimeout = setTimeout(drawQueue, 150);
}
}
function drawQueue () {
drawQueueTimeout = -1;
console.log('draw queue');
if (queue.length > 0) {
var element = queue.shift();
console.log('drawQueue', element.char);
helloPageA.html(helloPageA.html() + element.char);
}
checkQueue();
}
$(window).scroll(function (e) {
var elem = $(".hello-page");
var scrollTop = $(window).scrollTop();
var blockTop = elem.offset().top;
var docHeight = $(document).height();
var windowH = $(window).height();
if (scrollTop + windowH == docHeight) {
// Empty anything typed so far
helloPageA.empty();
flushQueue();
var text = helloPageA.attr("data-text");
helloPageA.text('');
$.each(text.split(''), function (i, letter) {
pushQueue({
char: letter,
index: i
});
});
} else {
helloPageA.empty();
flushQueue();
}
});

javascript code not working if placed at top of file

I have the following code. It set a filter bar in a search results page in a fixed position in the window after scrolling down to a certain point:
var docked;
var filters = document.getElementById('filters');
var init = filters.offsetTop;
function scrollTop() {
return document.body.scrollTop || document.documentElement.scrollTop;
}
window.onscroll = function () {
if (!docked && (init - scrollTop() < 0)) {
filters.style.top = 0;
filters.style.position = 'fixed';
filters.className = 'docked';
docked = true;
} else if (docked && scrollTop() <= init) {
filters.style.position = 'absolute';
filters.style.top = init + 'px';
filters.className = filters.className.replace('docked', '');
docked = false;
}
}
My issue is (and it's more curiosity) - if I place this code at the top of my file (in the <head>), it doesn't work at all. The filter section doesn't scroll with the window as it should. However, when I place this code at the bottom of the file (right above the closing </body> tag), it works just fine.
Why is this? Does this have something to do with the way the code works? Or could it be just a quirk or bug in the rest of my file causing this?
Wrap your assignments in window.onload = function(){ /* your code here */ }; and it will run. The reason being that your assignment of var filters = document.getElementById('filters'); comes back as undefined since that element does not exist during page load at the time you reference it.
Example:
var docked;
var filters;
var init;
window.onload = function(){
filters = document.getElementById('filters');
init = filters.offsetTop;
};
if you do this, it should work:
$(document).ready(window.onscroll = function () {
if (!docked && (init - scrollTop() < 0)) {
filters.style.top = 0;
filters.style.position = 'fixed';
filters.className = 'docked';
docked = true;
} else if (docked && scrollTop() <= init) {
filters.style.position = 'absolute';
filters.style.top = init + 'px';
filters.className = filters.className.replace('docked', '');
docked = false;
}
}
);

Categories

Resources