What I am trying to achieve is this, imagine you have a tall page with several divs in it.
The tall page itself is scrollable, the divs as well.
What I want to achieve is to prevent scrolling the whole page when scrolling the divs to the limit.
What now happens is that when you reach the end of the div by scrolling ferociously you start scrolling the entire page. I want to prevent scrolling the entire page, as this is for a private project and the items in the bottom rarely get used.
The divs are not generated dynamically so I can hardcode everything.
If it is possible I would really like to avoid using jQuery, cause that seems a bit overkill in this case.
//edit:
A small example can be found at http://gnur.nl/demo.html
The intended behavior of this demo is that the entire page never scrolls when you are scrolling inside the bacon div.
I'm afraid it's a lost battle, the scroll event doesn't look to be cancelable:
http://www.w3.org/TR/DOM-Level-3-Events/#event-type-scroll
Or may be with a desperate hack to scroll back the amount of pixel that were scrolled:
var lastPos = isNaN(window.pageYOffset) ?
document.documentElement.scrollTop :
window.pageYOffset;
window.onscroll = function(ev){
var diff = (isNaN(window.pageYOffset) ?
document.documentElement.scrollTop :
window.pageYOffset) - lastPos;
window.scrollBy(0, -diff);
};
And using onmouseover and onmouseout over the DIVs to prevent it or not.
Related
I am having an issue. Im using a one page design for a friend with a fixed floating menu on the top. The problem I encounter is that when I click on a link it scrolls down but the offset is not right. Most the of time it scrolls down a little too much covering the content below the menu. What I am trying to achieve is that the scrolling stops at the div being exactly below my menu bar. The other issue is that somehow it wont scroll down when the space between two sections is too narrow. It tries but somehow only moves a few pixels then stops. I can imagine that both are related to the offset issue.
Im sorry, english is not my native language.
Here is what I got so far. A standard scrolling function with window.location.hash. The target are divs spread across the site.
$(document).ready(function () {
$('a[href^="#"]').on('click', function (e) {
e.preventDefault();
var target = this.hash;
var t = $(this.hash).offset().top;
$('.wrapper').animate({
scrollTop: t,
}, 1000, function () {
window.location.hash = target;
});
});
});
You can see an example of the problem live: http://rolfvohs.com/
What I tried so far was using the add.class function to bind the div with an extra padding when a link is clicked. It does work in a way but creates an awkward space. I also tried placing the divs at different locations but that does not fix the job either, just messes it up further.
I would appreciate some insight.
window.location.hash = target;
moves the scroll by default to the div position and you are setting offset top before the hash change so first its changes the offset after that it move to div location.
first try after removing the line "window.location.hash = target;" from the code
or
move the "window.location.hash = target;" out side and above the "$('.wrapper').animate({})" it will work .
I have a container (div) on the page. This container has a scrolling (provided by overflow:auto; height:400px).
I need no provide a URL, that will open a page so that the main page will not be scrolled, but the text in the container will be scrolled.
I tried www.mysite.com#position, but by this way the main page is scrolled too (and I need, that users will see the header on the top of the screen, and the "#position" position on the top of the container)
This is possible with javascript. And I will show a jQuery example here.
if (window.location.hash == '#position') {
$('#containerDiv').animate({
scrollTop: $("#actual_position").offset().top
}, 2000);
}
The actual_position should be the place where to scroll to. position should just be in the url and not on the page, to prevent the whole page from scrolling.
May you use the css-properties: position:fixed, top:..., left:... for your element that should stay at a certain place on your side, when an user scrolls.
Furthermore you can put all content that you do not want to be scrolled into a div and define the css-properties.
I hope this helps you a little bit.
Really it's an upgrading of Arjan answer (and now this really works).
As Arjan's suggestion the script will not work every time, but only by providing #scroll in the end of url (www.mysite.com#scroll). This script will scroll the container scroll bar to the #position element, and the all document will stay.
jQuery(window).load(function(){
container_top = jQuery('#container').offset().top;
element_top = jQuery('#position').offset().top;
element_relative_top = element_top -container_top;
if (window.location.hash == '#scroll') {
jQuery('#container').animate({
scrollTop: element_relative_top
}, 2000);
}
})
I'm relatively new to programming and am working on a Chrome extension with a popup. I want to save the scroll position between popup invocations. It seems like I've found a lot of info on the internet, but so far I haven't been able to solve my problem. Saving the scroll position almost works within my extension, but I'm seeing 2 issue:
1) To save the scroll position at each scroll event, I use:
addEventListener('scroll', function(){
localStorage.scrollTop = document.body.scrollTop;
});
When the popup is opened, I use:
document.body.scrollTop = localStorage.scrollTop
This seems to work fine until my scroll position exceeds the popup height. The max popup height for visible content in a Chrome extension is 600px. document.body.style.height is also always a fixed value greater than 600px. When the scroll position is greater than document.body.style.height - 600px, say 900px - 600px, document.body.scrollTop is reset to 300px. Even if the last scroll position (document.body.scrollTop) was 400px before the popup is closed, scroll position is reset to 300px when the popup is re-opened. Obviously, I get the wrong scroll position because the proper scroll position value of 400px (for example) is then overwritten by 300px.
However, it doesn't always happen. Sometimes I can properly save a scroll position of, say 500px with a window height of 900px, and other times I can't. I don't know for sure why this has any effect, but as the content in the popup is taller the problem seems to magically go away and the proper scroll position is saved.
How can I properly save the scroll position when the scroll position in this situation? Perhaps I'm doing something fundamentally wrong?
(This seems confusing to read. I hope it's possible to help with the code above.)
2) I think might be intertwined with the above issue, but I'm not sure. For every scroll event (first code block in this post), I see a pair of scroll events fired.
If I just open the popup but don't scroll the mousewheel, I see code inside my event listener fire. When the first event happens, document.body.scrollTop is reset to the "wrong" value (300px in the example above). I think this might be the root cause of both issues.
Shouldn't the event listener only fire if the mousewheel is moved, and thus the code inside the event listener doesn't execute if the popup is opened but the mousewheel isn't touched?
The issue was actually in the corresponding CSS code. The <div> wasn't scrollable, and so it didn't allow saving a scroll position bigger than the visible area of the popup.
The solution was to add the position: relative; and overflow-y: auto; (overflow-y: scroll; works as well) properties to the CSS element.
Once those properties were added, I could properly save the scroll position to an object.
I know this shouldn't be an answer, but I can't format code in a comment:
I'm going to go out on a limb and suggest you try test one of the basic assumptions: Are the scroll events firing in order?
Try this, see if adds some useful debugging info:
var scrollCounter = 0;
addEventListener('scroll', function(){
localStorage.scrollTop = document.body.scrollTop;
console.log({counter: scrollCounter, scrollTop: document.body.scrollTop});
scrollCounter++
})
See if the numbers seem to jump around, or if they go in progressive order.
Edit: P-code for a possible solution
I think I have an idea for a fix, though I use the word fix kind of loosely here.
var captureSemaphore; // Use this to flag exactly when we want the `scrollTop` captured.
captureSemaphore = true; // Go into catch mode
addEventListener('scroll', function(){
if (captureSemaphore) {
localStorage.scrollTop = document.body.scrollTop;
}
});
// then later, right before you open your popup
captureSemaphore = false; // Disable catch mode because the screen is about to change
openPopup(); // Open the popup
// Elsewhere
closePopup(); // Close the popup
captureSemaphore = true; // Go into catch mode
fiddle: http://jsfiddle.net/DerNalia/88N4d/9/
The behavior I'm trying to accomplish:
The Sidebar(s) should be fixed on the page if there is enough room
for them
The Sidebar(s) should scroll if there is ever not enough room for them
When scrolling down, and the bottom of the sidebar(s) is reached, it should stop scrolling
When scrolling down, the sidebar(s) should also scroll down, until
the bottom of the sidebar(s) is/are reached
When scrolling up, and the top of the sidebar(s) is reached, it should stop scrolling
If at any point during the scrolling of the content, the user switches directions of scrolling, the sidebar(s) shall also move in the same direction as the rest of the page / content
When scrolling up, the sidebar(s) should also scroll up, until the
top of the sidebar(s) is/are reached
If the content is shorter than the sidebar(s), the sidebar(s) should
still be able to scroll This is the one that I'm having trouble
with
How do I make it so that I can detect the intended scroll distance desired by the user, rather than use the actual scrolled distance of the content body? There may be another solution, but this is all I can think of for right now.
I'm currently using Chrome on Mac.
UPDATE:
something I've noticed: using the track pad on macs does the stretching / bouncy scrolling shenanigans on the edges.. which messes up this javascript hard core. It's possible to scroll the sidebar completely off the screen if you bounce up enough times. Mouse Wheel scrolling does not have this issue.
I think you’d be much better off positioning the columns absolute and then check positions onscroll and toggle the positions.
It gets quite complicated, since the scroll will jump if both columns are fixed and the content has regular flow.
I created a solution for you using a simpler logic that goes:
var $win = $(window);
var $containers = $(".container").css('position','absolute');
// we need to force a height to the body for fixed positioning
$('body').css('minHeight', Math.max.apply( Math, $containers.map(function() {
return $(this).height();
})));
$win.bind("resize scroll", function() {
var scrolled = $win.scrollTop(),
winheight = $win.height(),
elheight = 0;
$containers.each(function() {
elheight = $(this).height();
$(this).css('position', function() {
if ( elheight > (winheight+scrolled) ) {
$(this).css('top',0);
return 'absolute';
}
$(this).css('top', Math.min(0, winheight-elheight));
return 'fixed';
});
});
});
It should fill your requirements. The fixed positioning kicks in if the columns are shorter than the window height, or if the scrollTop is enough.
A demo in all it’s glory: http://jsfiddle.net/mb9qC/
I am trying to re-create website with parallax effect using JavaScript. That means that I have two or more layers, that are moving different speeds while scrolling.
In my case I'm moving only one layer, the other one remains static:
layer 1 = website text;
layer 2 = element background;
for this I'm using simple source code (with jQuery 1.6.4):
var docwindow = $(window);
function newpos(pos, adjust, ratio){
return ((pos - adjust) * ratio) + "px";
}
function move(){
var pos = docwindow.scrollTop();
element.css({'top' : newpos(pos, 0, 0.5)});
}
$(window).scroll(function(){
move();
});
The Problem:
- All calculations are done right and the effect "works" as expected. But there is some performance glitch under some browsers (Chrome MAC/Windows, Opera MAC, IE, paradoxically not Safari).
What do I see during scrolling?
- While scrolling the background moves in one direction together with scroll, but it seems to occasionally jump few pixels back and then forth, which creates very disturbing effect (not fluid).
Solutions that I tried:
- adding a timer to limit scroll events
- using .animate() method with short duration instead of .css() method.
I've also observed, that the animation is smooth when using .scrollTo method (scrollTo jQuery plugin). So I suspect that there is something wrong with firing scroll events (too fast).
Have you observed the same behavior?
Do you know, how to fix it?
Can you post a better solution?
Thanks for all responses
EDIT #1:
Here you can find jsfiddle demonstration (with timer): http://jsfiddle.net/4h9Ye/1/
I think you should be using scrollTop() instead and change the background position to fixed. The problem is that setting it to absolute will make it move by default when you scroll up or down.
The flicker occurs because the position is updated as part of the default browser scroll and updated again as part of your script. This will render both positions instead of just the one you want. With fixed, the background will never move unless you tell it so.
I've created a demo for you at http://jsfiddle.net/4h9Ye/2/ .