detecting how much of a div is beyond window height - javascript

I have a fixed div that I want to sit on top of a number of background images. The issue is that if this fixed div is taller than the window, it wont scroll, meaning content is lost. I've tried using max-height: 100% and y-overflow:scroll; but no luck.
I have figured a workaround using the following javascript:
<script>
$(window).scroll(function(){
var css = {};
if ($(window).scrollTop() > 120){
css = { top:'0'};
}
else {
css = {top:'120'};
}
$('#writtenContent').animate(css,{duration:200,queue:false});
});
</script>
Which moves it up, but this is not ideal for a number of reasons. Id like to either be able to know how much of the div is hidden, and then move up that amount, or have the fixed div scrollable. Ideally either of these should only happen if necessary i.e. if the div fits in the window, then no action taken.
Any ideas would be great!
===============UPDATE=================
Hi guys - here is a quick jsfiddle showing the type of thing. Its a stripped down version, but shows the problem Im having. If the window is resized to be smaller than the content holding div, we loose it.

Ok well first off, you said that it's a fixed div, which generally means position:fixed but then you say position:relative? What do those refer to? But it really should be scrolling. You said you tried y-overflow but of course that won't work. It's overflow-y with the y after. Try that again and see if it works. If it doesn't work then you will need to post all of the relevant code and styles so we can see what is going on.
Also it's somewhat hackish but try using max-height: with varying percentages less than 100% to see if it works even a little bit correctly.

If I'm understanding you correctly, this will work for you.
var win = window,
$writtenContent = $('#writtenContent'),
$writtenContentPosition;
function windowScrollMagic(){
$writtenContentPosition = $writtenContent.offset().top; // get elements distance from top
// if you've scrolled farther than the elements position:
if (win.scrollY > $writtenContentPosition) {
// do something, like animating $writtenContent to the win.scrollY coordinate
}
}
$(document).ready(function(){
$(win).scroll(){
windowScrollMagic();
});
});
Update in response to example jsfiddle:
var $win = $(window),
$winHeight,
$writtenContent = $('#writtenContent'),
$writtenContentPosition,
$writtenContentHeight,
$writtenContentBottomEdgePosition,
heightDifference;
function calculateHeights() {
$winHeight = $win.height();
$writtenContentPosition = $writtenContent.offset().top;
$writtenContentHeight = $writtenContent.height();
$writtenContentBottomEdgePosition = $writtenContentPosition + $writtenContentHeight;
heightDifference = $winHeight - $writtenContentBottomEdgePosition;
}
function windowResizeMagic() {
calculateHeights();
if (heightDifference < 0) {
$('#alert').html('Written Content is off screen by ' + heightDifference + 'px');
} else {
$('#alert').html('Written Content is not off screen');
}
}
$(document).ready(function(){
calculateHeights();
$win.resize(function(){
windowResizeMagic();
});
});

Related

How do I get a div to appear outside it's container, and scroll, while keeping overflow on it's container

I'm working on a Wordpress blog design, and running into an issue with the entry-header. I would like my entry-header to be offset, going outside the bounds of it's container, yet scrolling with the content, inside the content wrap. Here is a screenshot of what i'm trying to achieve.
]1
I'd like to have the red areas scroll along with the text of the blog post, but so far, the only way I've been able to get the red areas to be offset as seen above, is to set position: absolute. When position is set to relative, it shows up as seen below.
Do you have any ideas that could help me resolve this issue?
Thanks.
give it position relative with higher z-index
position:relative;
z-index:10;
left:-50px;
JSFiddle
As user #divy3993 states a fiddle would be helpful.
Anyway: The overflow of your outer div seems to be hidden. This is the reason why you don't see the left part of your header when position is relative.
Apply the css-property
overflow-x: visible;
to your outer div (the one with the dark background) and the full header should be shown.
EDIT:
Sorry for keep you waiting.. I had a while no look at SO.
Sadly the solution that i was thinking of (with pure CSS) does not work as it is pointed out in https://stackoverflow.com/a/6433475/1402667 the combination of
overflow-x: visible
and
overflow-y: auto
won't work as expected.
So it seems you have to use JavaScript to solve your issue. I had a look at the link that you are pointing out in comments (http://basil-gen.marathonwp.com/blog/) and successfully run the following jQuery code there:
var $headers = $('.site-inner h1');
var $scrollContainer = $('.site-inner .content-sidebar-wrap');
var hideShowHeaders = function(visibleTop, visibleBottom){
$headers.each(function(){
if($(this).show().offset().top < visibleTop || $(this).offset().top + $(this).outerHeight() > visibleBottom){
$(this).hide();
}else{
$(this).show();
}
});
};
$headers.each(function(){
$(this).data('initTop', $(this).position().top);
});
hideShowHeaders($scrollContainer.offset().top, $scrollContainer.offset().top + $scrollContainer.height()); //might consider borders
$scrollContainer.scroll(function(){
$headers.each(function(){
$(this).css('top', $(this).data('initTop') - $scrollContainer.scrollTop() );
});
hideShowHeaders($scrollContainer.offset().top, $scrollContainer.offset().top + $scrollContainer.height()); //might consider borders
});
It essentially repositions the headers whenever your content container is scrolled. When the headers (or a part of those) would not be visible with position:relative those headers are hidden. In all other cases they are shown.
As i mentioned it's jQuery-Code so you need to include jQuery yet and e.g. execute above code inside
$(document).ready(function(){
...code above
});
If you want to straight test it you can browse to your site (http://basil-gen.marathonwp.com/blog/) open Javascript-Console,
inject jQuery via javascript e.g. like
var script = document.createElement('script');
script.src = "http://code.jquery.com/jquery-latest.min.js";
document.getElementsByTagName('head')[0].appendChild(script);
and then execute above code in Javascript-Console (when directly testing it you should not have scrolled before executing javascript code).
I should mention that the code above is not perfect since it only shows and hides headers instead of showing e.g. 50% of it. I couldn't come up quickly with a solution for it. Anyway you could do this with a more complex showHideHeaders-function where marked lines need to be implemented
var hideShowHeaders = function(visibleTop, visibleBottom){
$headers.each(function(){
if($(this).show().offset().top + $(this).outerHeight() < visibleTop){
if($(this).offset().top < visibleTop){
$(this).hide();
}else{
//lower part of this header needs to be displayed
var bottomPxToShow = $(this).offset().top + $(this).outerHeight() - visibleTop;
var hiddenPx = $(this).outerHeight() - bottomPxToShow;
//show lower bottomPxToShow Pxs of header
}
}else if($(this).offset().top + $(this).outerHeight() > visibleBottom){
if($(this).offset().top > visibleBottom){
$(this).hide();
}else{
//upper part of this header needs to be displayed
}
}else{
//show full header
}
});
};
I hope that helps you!

Browser Resize event for sticky navigation

I've been dealing with this problem since days now and I hope somebody here can help me.
I'm trying to make a sticky navigation and a 100% height header (body and html are set to 100% height too). Basically the problem I have is that the sticky navigation only works well after the page is (re)loaded. However scrolling after having resized the browser's window makes the navigation either jump to early or to late to the fixed position at the very top.
I'd need to implement a resize event I guess, so that the calculation of the variable "navOffset" fires everytime the window is resized, right?
I tried many ways of inserting this into my code which are also explained in the link below, but I falied everytime.
I hope somebody can disclose this secret to me as I'm getting insane about this.
Thanks a lot and have a great week!
Sascha
Example of the effect I want to achieve:
http://html5-webdesign.berlin/
Tutorials, which didn't help me:
https://stackoverflow.com/…/jquery-combine-document-ready-an…
jQuery(document).ready(function() {
var navOffset = jQuery("nav").offset().top;
jQuery("nav").wrap('<div class="nav-placeholder"></div>');
jQuery(".nav-placeholder").height(jQuery("nav").outerHeight());
jQuery(window).scroll(function() {
var scrollPos = jQuery(window).scrollTop();
if (scrollPos >= navOffset) {
jQuery("nav").addClass("fixed");
} else {
jQuery("nav").removeClass("fixed");
}
});
});
Just copy your second function (which you should probably name) and add it to the window resize event:
jQuery(document).ready(function() {
var navOffset = jQuery("nav").offset().top;
jQuery("nav").wrap('<div class="nav-placeholder"></div>');
jQuery(".nav-placeholder").height(jQuery("nav").outerHeight());
function setPosition() {
var scrollPos = jQuery(window).scrollTop();
if (scrollPos >= navOffset) {
jQuery("nav").addClass("fixed");
} else {
jQuery("nav").removeClass("fixed");
}
}
jQuery(window).scroll(setPosition);
jQuery(window).resize(setPosition);
});

Test if element can be seen by the user on an html page

Is there any way to know if an element is visible on an html page?
Like this:
One can probably do it considering the horizontal/vertical scrolling positions, the width/height of the browser window and the position/size of the element on the page, but I have little experience in jQuery so I don't know how to do it. And there might be a simple function one can call, I don't know.
You can use the .is(':visible') selectors to check if an element is currently visible in the DOM.
Edit:
However, as #BenM mentioned, this doesn't check if the elements on your page are actually out of your scrollable range - a great little plugin you could use in that case would be Viewport Selectors for jQuery.
Here is some code that I use to do this. It has been tested to work great.
function isVisible($obj) {
var top = $(window).scrollTop();
var bottom = top + $(window).height();
var objTop = $obj.offset().top;
var objBottom = objTop + $obj.height();
if(objTop < bottom && objBottom > top) {
//some part of $obj is visible on the screen.
//does not consider left/right, only vertical.
}
}

How to keep a div visible on page re-size?

I have a facebook "like us" icon on one site, now client requirement is to keep it visible when user scrolls the up until it reaches the top position of page (which is sorted by using jquery stickynotes) and the icon should still be visible when somebody re-size the browser (X = (browser width/2) + (wrapper/2)).
Not able to make out how can I do that, since first condition forces the div to be static positioned so that it can move-along when the page is scrolled down.
But in order to re-position it I'll require to make the potion fixed.
Kindly suggest a way out.
Just a simple example how you can fix that:
function movement() {
var topPosition = $(window).scrollTop();
if(topPosition > 100) {
// do something
$('element').addClass('dosomething');
} else {
// do something
$('element').removeClass('dosomething');
}
}
$(document).ready(function() {
$(window).scroll(function() {
movement();
});
});
Have you looked at something like jQuery Waypoints?
I'm not sure it's an exact match, but it solves some of these problems elegantly.

Keeping sidebar in viewport, problem with scrolling

I've got a solution for keeping a sidebar in the viewport as you scroll up and down the page. Problem comes in when the sidebar is longer than the content area, and you keep scrolling you get this jittering effect as the sidebar keeps pushing the footer down.
I've got an example of this setup in jsFiddle: http://jsfiddle.net/U9F7w/2/ (full screen: http://jsfiddle.net/U9F7w/2/embedded/result/ )
My question is, is there a way to make the sidebar stop once it touches the bottom/footer area?
I've read some solutions about setting the sidebar to absolute, unfortunately it's an existing site and changing the position didn't work and messed with a lot of the existing page elements.
Here's the jQuery/js I'm working with:
// set the offset
var sidebarOffset = $(".sidebar").offset();
var sidebarPadding = 15;
// when the window scrolls, keep sidebar in view
$(window).scroll(function() {
if ($(window).scrollTop() > sidebarOffset.top) {
$(".sidebar").stop().animate({marginTop: $(window).scrollTop() - sidebarOffset.top + sidebarPadding });
}
else {
$(".sidebar").stop().animate({marginTop: 0});
};
});
edit
One thing I thought about was (not sure if this is possible) to detect if the bottom of one div was lower than the bottom of another, stop the scrolling. Is there a way to detect if the bottom of one div is lower than the other?
Check if the sidebar's height is greater then that of the content:
var ct = $(".content");
var sb = $(".sidebar");
var sbOffsetTop = sb.offset().top;
var sbPadding = 15;
$(window).scroll(function() {
if (sb.height() < ct.height()) {
if ($(window).scrollTop() > sbOffsetTop) {
sb.stop().animate({top: $(window).scrollTop() - sbOffsetTop + sbPadding });
}
else {
sb.stop().animate({top: 0});
};
};
});
See demo fiddle with large content and demo fiddle with large sidebar.
And I don't know why exactly, I would use top in conjunction with position: relative, but marginTop works also fine.

Categories

Resources