Overflow hides content (should appear while scroll) - javascript

I am working on a website which uses snap.js and chart.js.
DEMO JSFIDDLE
After adding JavaScript to display the content from chart.js while user scroll, seems like it is in some trouble with the following style:
Line 10 - CSS: overflow: auto;
If I delete this style it works perfectly:
DEMO2 JSFIDDLE (without overflow)

The issue is that your window is no longer scrolling. Instead your .snap-content is. So you'll need to change the scroll handler to that element. You will then also have to modify your calculation a bit to work with this new setup:
http://jsfiddle.net/MU9aw/27/
function isScrolledIntoView(elem) {
var docViewTop = 0;
var docViewBottom = $(".snap-content").height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemTop <= docViewBottom) && (elemBottom >= docViewTop));
}
$(".snap-content").scroll(function () {
/* ... */
Note that your calculations will get considerably more complicated if your scrolling box does not fill the entire screen as you will need to determine if the element is visible within its box as well as that portion of the box being visible on the screen.

It's not the overflow that makes the issue.. It's the
.snap-content {
position: absolute; }
makes the issue. When I removed it, it works!
The problem is
$(window).scroll(function() {});
Doesn't fire when I scrolled maybe because since the element is absolute it keeps the original position in the screen without changing it. Make it to relative, and it will work.

Related

Page noscroll keeping scrollTop position in sticky footer layout

I can't handle such a mind-breaker:
It's common approach to hide page scroll when a tall popup shows. But when you set overflow: hidden to html and body elements, the content automatically returns to it's top (scrollTop: 0). It's no problem to keep scrollTop position, and reset it on popup's disappearing. But if you use transparent mask, user will see unnecessary jump from current scroll position to the top. How to escape this?
In the current Chrome and Firefox, I can set overflow: hidden only to html element to reach what I want, but it's not working on mobile devices.
Maybe someone can propose a good cross-browser solution.
I don't think this should be happening. I would look at the popup code to see if it's the culprit sending the page to the top and using subpar css to position the popup element.
In any case, here's code that ought to counter the behavior you're encountering. Since I cannot reproduce the problem, I cannot test my proposed fix. I think you'll find though that your pop up will be scrolled away out of view.
function keepScroll(){
var x = $('body').scrollLeft() + $(document.documentElement).scrollLeft();
var y = $('body').scrollTop() + $(document.documentElement).scrollTop();
$('html').css({
'overflow':'hidden'
});
$('body').css({
'overflow':'hidden'
});
$(window).scrollTop(y).scrollLeft(x);
}
The sicky footer layout has html and body height equal to '100%'. And when you set overflow:hidden it crops all the content and returns it to the top position.
To avoid this, you should set html and body height to 'auto' if scroll exists (you should check it to keep sticky footer behavior)
function keepScroll(){
var scrollHeight = $('body')[0].scrollHeight > $('html')[0].scrollHeight ? $('body')[0].scrollHeight : $('html')[0].scrollHeight,
keepCSS = scrollHeight > $(window).height() ? {'overflow':'hidden','height':'auto'} : {'overflow':'hidden'};
$('html, body').css(keepCSS);
}
See the fiddle, for live demo
Edit 1
This solution is still not working on mobile (overflow: hidden doesn't disable scrolling on iPad, the position 'fixed' fix for body throw the content to the top), so the issue is open
Edit 2
Find a fix, for mobiles. Maybe it isn't so clean, but works.
var scrollKeeper = (function() {
var scrollHeight = $('body')[0].scrollHeight > $('html')[0].scrollHeight ? $('body')[0].scrollHeight : $('html')[0].scrollHeight,
keepCSS = scrollHeight > $(window).height() ? {'overflow':'hidden','height':'auto'} : {'overflow':'hidden'},
scrollTop = 0;
return {
keep : function() {
scrollTop = $(window).scrollTop();
$('body').css({'position': 'fixed', 'width':'100%', 'top': -scrollTop + 'px'});
$('html, body').css(keepCSS);
},
release : function() {
$('html, body').removeAttr('style').scrollTop(scrollTop);
}
}
})();
Tip: Of course in the real development you should use css classes to avoid removeAttr(style) etc.
Tested on iPhone and Ipad (iOS 8+).
The fiddle http://jsfiddle.net/m1eav032/5/

How to make scrollbar to see full content in below case?

see demo url of the framework i'm using: http://alvarotrigo.com/fullPage/examples/navigationH.html#secondPage
However,using almost same kind of code from above,
when I try to achieve below effect in which title text is excluded from slider. (title text to be static, and content is sliding)
jsfiddle url: http://jsfiddle.net/097wvnot/8/
I can't scroll to see all the content; what's the best code to achieve this effect?
if i want to use the top framework, must i do a lot of hack into its core functions?
if not hacking the top animation framework , what are other recommendations to this effect
Use an absolute positioned element for your title. Fullpage.js calculates the height of your content inside the slide elements. (as they are suppose to be full height...).
If you place anything outside any slide, it would have to be absoluted positioned.
Take a look at the solution I propose: http://jsfiddle.net/097wvnot/11/
I added the following style to your title:
#demo{
position:absolute;
top:50px;
margin: 0;
left:0;
right:0;
text-align:center;
}
It looks like the plugin is calculating the height of the fp-scrollable incorrectly. At least for your use case. I was able to get it looking good by just manually adjusting the fp-scrollable's height attribute to a smaller amount (obviously that is not a long term fix, just something I was doing for testing). I'm not sure if the calculating takes into account your font size, and things like that, so that might effect it.
If you want to hack on the plugin, generally the place you need to make your changes is fairly restricted, and wouldn't be too bad. From the github page. https://github.com/alvarotrigo/fullPage.js/blob/master/jquery.fullPage.js
All you need to do is fix the value being placed into the scrollHeight variable. I'm not sure exactly what it's not accounting for in the scroll height calculation (the scrollHeight needs to be smaller in your case, it's too big), but I think that's an exercise you can try your hand at first :) I've got to get to bed z.z
You also may need to mess with the calculation for the contentHeight, since ostensibly you'll be shrinking the scrollHeight, and the script only puts the scroll bar on there if the content is bigger than the scroll.
function createSlimScrolling(element){
//needed to make `scrollHeight` work under Opera 12
element.css('overflow', 'hidden');
//in case element is a slide
var section = element.closest('.fp-section');
var scrollable = element.find('.fp-scrollable');
//if there was scroll, the contentHeight will be the one in the scrollable section
if(scrollable.length){
var contentHeight = scrollable.get(0).scrollHeight;
}else{
var contentHeight = element.get(0).scrollHeight;
if(options.verticalCentered){
contentHeight = element.find('.fp-tableCell').get(0).scrollHeight;
}
}
var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top'));
//needs scroll?
if ( contentHeight > scrollHeight) {
//was there already an scroll ? Updating it
if(scrollable.length){
scrollable.css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px');
}
//creating the scrolling
else{
if(options.verticalCentered){
element.find('.fp-tableCell').wrapInner('<div class="fp-scrollable" />');
}else{
element.wrapInner('<div class="fp-scrollable" />');
}
element.find('.fp-scrollable').slimScroll({
allowPageScroll: true,
height: scrollHeight + 'px',
size: '10px',
alwaysVisible: true
});
}
}
//removing the scrolling when it is not necessary anymore
else{
removeSlimScroll(element);
}
//undo
element.css('overflow', '');
}

Check whether an element is fully visible and then stop scrolling

I´m using FullSlider.js to create a full-slide-webpage. In case the red element is fully visible, I need the browser to block the scroll event (means: window is not moving, but I´m able to receive the action) and than after I did some stuff I want to enable scrolling again.
That is what I did so far:
I read a lot of stuff about this and tried even more solutions like:
stop scrolling:
1. stop scrolling of webpage with jquery does not work at all
How to programmatically disable page scrolling with jQuery does stop the scrolling, but it is not possible to enable scrolling again
event prevent default, works fine in chrome, but less fine in firefox
check if element is visible:
Check if element is visible after scrolling
I used the solution above and tried:
to check if the red element is visible (did not work)
checked if a tiny span above the red element is visible (did not work well)
checked if a tiny span below the red element is visible (did not work well)
checked if a tiny span above and below the element is visible (did not work at all)
tried some idea about getting the scrollTop of the red element and check if the bodys scrollTop is equal or near
In fact the 2. solution did work quiet well, but I just was not able to figure out the offset I needed to at to compensate the "fixed-header navigation".
Currently I´m using the "isScrolledIntoView" to detect whether the position fits (works well on large screens, does not work at all on small screens). For the stop scrolling, I´m using the following hack:
CSS:
.scrollHack { position: static; overflow: hidden; }
JS:
$(document).on('mousewheel', function(event, delta) {
// stopScroll and isStopped are booleans delivered by another script
if(isScrolledIntoView($("#s3")))
{
isStopped = false;
if(delta >= 0) {
$('#s3').get(0).contentWindow.car.next(); // car.next();
}
else{
$('#s3').get(0).contentWindow.car.previous();
}
stopScroll = $('#s3').get(0).contentWindow.isStopped;
}
if(!stopScroll && isScrolledIntoView($("#s3")))
{
event.preventDefault();
$("body").addClass("scrollHack");
}
else
{
$("body").removeClass("scrollHack");
}
});
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
Was someone faced with an familiar situation and has some scripts or hacks that would help me out?
Sorry, I can't answer in a comment yet. So this is only a partial answer, regarding the second part of your question.
For checking whether your element is fully in view:
Try using jQuery innerHeight() instead of height(). This gives you the element height without margins and borders.
Checking for a tiny span above the red element should not be necessary. Wouldn't that be equal to just checking whether the top of the red element is on the screen? You could do that like this:
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var elemTop = $(elem).offset().top;
return (elemTop >= docViewTop));
}
But this is only checking whether the top of your element is visible!
You say that your current solution does not work well on small screens. Could it be that the element you are checking is taller than the viewport on small screens?
Maybe this helps a little. Else it would be really good to see an example page or a jsfiddle example.

using a simple jquery script to have a div follow the page on scroll

I'm trying to use this script here: http://css-tricks.com/scrollfollow-sidebar/ to make a simple div that follows the window as the user scrolls. I changed it from 0 to topPadding and changed topPadding to topPadding*2 to get the right top offset.
Unfortunately this has the side effect of the object making the page a little longer and allowing the user to scroll infinitely. This bug is also actually in the original code without my larger toppadding changes if you make the window small enough.
I also tried another plugin for jquery, but it didn't work at all and this gives me what I need, so how can I fix it?
Why not just use CSS.
#theNonMovingDiv {position:absolute; position: fixed; top: Npx; right:Mpx}
position:fixed; doesn't work in ie6, but including the position:absolute; will give you a rough approximation.
I've knocked together this quick amendment, which limits based on the document height. I'm not certain that jQuery is giving an accurate height, hence a safety barrier of 100px. Even if the height isn't quite right, any extra scrolling will be limited and certainly not infinite.
<script type="text/javascript">
var documentHeight = 0;
var topPadding = 15;
$(function() {
var offset = $("#sidebar").offset();
documentHeight = $(document).height();
$(window).scroll(function() {
var sideBarHeight = $("#sidebar").height();
if ($(window).scrollTop() > offset.top) {
var newPosition = ($(window).scrollTop() - offset.top) + topPadding;
var maxPosition = documentHeight - (sideBarHeight + 100);
if (newPosition > maxPosition) {
newPosition = maxPosition;
}
$("#sidebar").stop().animate({
marginTop: newPosition
});
} else {
$("#sidebar").stop().animate({
marginTop: 0
});
};
});
});
</script>
I can duplicate your bug in my browser (Firefox 3.5).
The problem is that the code doesn't look to see if the bottom of the sidebar falls off the end of the document.
Your best bet is to use the .height() method to check. You can get the height of the sidebar (as presented in the example) as $("#sidebar").height(), and the height of the whole document as $(document).height().
What exactly the behavior should be -- up to you. It involves an extra if, to make sure all your pixels line up right, but design questions, like how the sidebar should align against the bottom, are going to be a matter of personal taste.

change div based on how far down the page you have scrolled

I am trying to change the text inside a div based on how far down a page you have scrolled. I've been tinkering with jQuery's scrollTop and document height but have so far failed to produce the desired results.
How would I get the position of an element on the page and then get jQuery to do something once you have scrolled to that elements position?
Help is much appreciated!
There was a question on Stackoverflow that asked something similar and I whipped up a small example to illustrate how to accomplish this. I can't find the question right now, but here is the example. In this example there is a div that is shown until you scroll to a certain element in the page at which point the div is hidden. You can change this to achieve what you want, as the idea is the same. Here is the code modified for what you need:
$(document).ready(function() {
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom));
}
var myelement = $('#formcontainer'); // the element to act on if viewable
$(window).scroll(function() {
if(isScrolledIntoView(myelement)) {
// do something when element is scrolled to and viewable
} else {
// do something when element is not viewable
}
});
});
Good old ppk from quirksmode.org can show you how to find the position of an element: "This script finds the real position, so if you resize the page and run the script again, it points to the correct new position of the element."

Categories

Resources