Check scrollpoint each pixel is scrolled - javascript

I need your help again. A try to code something like this:
I got an imaginary point on screen in pixel (lets say half of body) and I got a element in body. I want to alert if the elements TOP hits the imaginary line and alert if the elements bottom leave imaginary line.
I got something to work (for hit the line) but it only works a few times, but if I scroll fast it doesn't work. If I scroll very very slow and exactly the alert appears:
$(window).scroll(function () {
// A POINT I SET On SCREEN --> IN THIS CASE HALF SIZE OF BODY
var halfBody = $("body").height() / 2;
if ($(window).scrollTop() == halfBody) alert('HIER');
});
I think the problem is the exact pixels i try to match. I think with scrolling I haven't always the exact pixels.
How can this be done so that elements top cross the line alert('element top hits the line') and elements bottom leave the line alert('no element leaving the line'); ?
I hope you understand :)

Scroll events are trigger happy and handing each even can overwhelm your handler.
Try using lodash/underscore debnounce/threshould to handle them every X milliseconds.
It's a common practice to scroll handling in browsers.

Ok i found a nice solution with caching variables and a set timeout:
var timer;
var windowHeight = $(window).height();
var triggerHeight = 0.5 * windowHeight;
$(window).scroll(function() {
if(timer) {
window.clearTimeout(timer);
}
timer = window.setTimeout(function() {
// this variable changes between callbacks, so we can't cache it
var y = $(window).scrollTop() ;
if(y > triggerHeight) {
}
if( $(window).scrollTop() == 0 ) { // IF HITS TOP OF PAGE
}
}, 10);
});
maybe it helps someone!

Related

How can I add this scroll function?

I need to implement a scroll function in my site.
When I will scroll down, document will be scrolled until a fixed position, which I want.
For example:
$(“.scroll-block”).scrollTop(250);
I realized this function. Pseudo-code:
when (scrollTop > 0)
do (scrollTop(250))
But then scroll is fixed. And any scroll-actions doesn’t work.
But I have three block. And I want to keep the possibility to scroll to all three blocks.
How can I do that?
P.S.: sorry for my terrible English. It’s my first post on this platform for communication.
P.S.S.: and first topic on English language.
Register a scroll callback like so:
jQuery(window).scroll(scrollCallback);
In the callback you can get the scroll position and do whatever you want at specific heights.
function scrollCallback(){
//gets the current windows scroll top value
var scrollPos = jQuery(window).scrollTop();
//get the position of the top of the elements you want to trigger actions on.
var first = jQuery('the-element-you-want-to-select1').position().top;
var second = jQuery('the-element-you-want-to-select2').position().top;
if(scrollPos > first){
//do something for first height
}else if(scrollPos > second){
//do something for second height
}
..
..
}

Perform action when object is visible in viewport

I have a div on my page, and I would like the background color to change when the viewer scrolls down to it.
How can I do this?
I would have used CSS3 with something like this...
var elemTop = $('div').offset().top;
$(window).scroll(function() {
if($(this).scrollTop() == elemTop) {
$('div').removeClass('hidden');
}
});
The commenter above is right. You should try something first and when you get stuck, the community will help you get unstuck. That said, here's a quick jquery to solve your problem.
$(document).ready(function(){
var offsetTop = $('#test').offset().top, //offset from top of element - element has id of 'test'
finalOffset = offsetTop - document.documentElement.clientHeight; //screen size
$(window).on('scroll',function(){
var whereAmI = $(document).scrollTop();
if(whereAmI >= offsetTop){
console.log("i've arrived at the destination");
}
})
})
Note that the above code executes the console.log() at every point past your requirement (meaning from there downwards). In case you want the execution to happen only one, you need to adapt the code a bit. One more note - if you're checking this in a fiddle, this document.documentElement.clientHeight needs to be adapted to work in an iframe. So test it on your local machine.

javascript: animate scrolling when user scrolls

I want to animate page scrolling incrementally to different sections of the page when the user scrolls. So I wrote this code:
var $window = $(window);
var sectionHeight = $window.height();
var animating = false;
var dir;
// initialize page position (0)
var pagePos = $(window).scrollTop();
$(window).scroll(function() {
// current page position
var st = $(this).scrollTop();
// whether to animate up or down
dir = ((st > pagePos) ? '+=' : '-=');
// animate
if (animating == false) {
animating = true;
$('html, body').stop().animate({scrollTop: dir+sectionHeight},500, function() {
pagePos = $(window).scrollTop();
animating = false;
});
}
});
The problem is, I get a chained animation after my initial animation down, that animates the page back to the top. I'm not sure why, because it shouldn't animate unless 'animating' is set to false. It only gets set back to false when the animation is complete... right?
One potential fix, although I'm sure somebody can come up with a better solution, is to disable it for a set period of time after it scrolls.
Relevant code:
var ct = new Date().getTime();
if (animating == false && new Date().getTime() > ct + 10)
This will only allow the animation to happen if at least 11ms have passed. Seems to work for values as low as 2. You don't really notice any lag in scrolling but again, I would not consider this an ideal solution.
DEMO
I was able to get it to work, I still don't know why it wouldn't work as it was coded, but here is the solution that worked for me- I was inspired by #sachleen's answer. Thanks sachleen.
I moved the scroll animation into a separate function, then on the callback to the animation function I used a setTimeout with the same duration as the animation to call another function that simply changed the 'animating' boolean back to false.

Event at the end of the document

I don't understand why this doesn't work. Explanation will be appreciated.
var scrollTop = $(window).scrollTop();
var height = $(window).height();
if (scrollTop === height ) {
alert("end!");
}
http://jsfiddle.net/Zasxe/
$(window).height() gives you the size of the user's viewport, not the size of the total document, which is what you most likely want. To find if the user has reached the end of the document, you've got to find the document's size, by $(document).height().
Furthermore, to find if a user's reached the end of the document, using jQuery, you need to capture the scroll event, and see if the user's reached the bottom:
$(window).scroll(function () {
if ($(window).scrollTop() + $(window).height() === $(document).height()) {
alert("end!");
}
});
There's no event handler. That code only gets run once, when the page loads.
$(document).scroll(function () {
// Your code here
});
Be aware that the code will run every time you scroll, so don't make it to heavy.
And as someone else said, there were a number of other things wrong with the code - but start with putting the handler in.

issue with $(document).scrollLeft() as a variable

I'm trying to use the left variable to replace '1493' in this code. It works fine when it's a number but when I changed it over to use 'left' the if statement stops working.
$(document).scroll(function () {
var width = $(document).width();
var left = $(document).scrollLeft();
var postCount = $(".post").length;
var columnLength = ( width - ((postCount*743) - 1493)) - (width-(postCount*743));
if(left >= columnLength) {
$(".num").text(left);
}
});
Does anyone have any ideas where I'm going wrong with this? Any pointers would be great.
You may need to force it to be an integer:
var left = parseInt($(document).scrollLeft());
Lets take a look at the math you have really quick.
var columnLength = ( width - ((postCount*743) - 1493)) - (width-(postCount*743));
You are basically cancelling out width, and (postCount*743). It leaves you with --1493 which is positive 1493. The following would have the same effect:
var columnLength = 1493;
So, the reason the if statement fires when you put in the static value 1493, is because columnLength ALWAYS equals 1493 which, of course satisfies this condition:
if (1493 >= columnLength)
You could as easily write:
if (1493 >= 1493)
That said, it should still, theoretically fire when left becomes greater than or equal to 1493. But left is the current horizontal scroll position in pixels. It would be a HUGELY wide page to hit a scroll position of 1493.
Edit: Here's a fiddle to give an idea of how fast the scroll position increases: http://jsfiddle.net/vdQ7B/16/
EDIT 2:
Here is an update in response to your comment.
As I understand it, you were trying to get a horizontal scrollbar that would, essentially, scroll forever.
Please see the following fiddle for a demo: http://jsfiddle.net/vdQ7B/40/
The code is below:
$(document).scroll(function () {
var width = $(document).width();
var left = $(document).scrollLeft();
var viewportwidth = window.innerWidth;
// If our scrollbar gets to the end,
// add 50 more pixels. This could be set
// to anything.
if((left + viewportwidth) === width) {
$("body").css("width", width + 50);
}
});
Per the comments in the code, we simply increase the width of the body if we determine we've reached the end. scrollLeft() will only tell us the number of pixels that are currently not visible to the left of the viewable area. So, we need to know how much viewable area we have, and how much is hidden to the left to know if we've scrolled all the way to the end.
If you have a scroll bar on an inner element, like a div, you'd need to update with width of the div, not the body.
Note: You may also need to use $(window) instead of $(document) to get scrollLeft() to work across all browsers.
Note: See here about using "innerWidth". There are some compatibility issues, and you may need to expand it a bit to handle other cases (IE6).

Categories

Resources