Right now the code below floats to the left side of the content and it's visible when you scroll down. So far everything is Okay as long as the window is maximized. But when it's minimized or you increase the zoom the bar shows over the content which I don't want it to. In these cases (minimized window and increased zoom) I'd like the bar to be stuck to left margin so it won't be shown over the content. Obviously the bar must keep being floating to the left and visible when scrolled down (if the window is maximized). What changes do I need to do to accomplish this? Thank you very much for your support in advance!
#pageshare
{
position:fixed;
bottom:15%;
right:10px;
float:left;
border: 1px solid #5c5c5c;
border-radius:5px;
-moz-border-radius:5px;
-webkit-border-radius:5px;
background-color:#e5e5e5;
padding:0 0 2px 0;
z-index:10;}
#pageshare .sbutton
{
float:left;
clear:both;
margin:5px 5px 0 5px;
...
}
You can accomplish this by using JavaScript to modify the attributes of both the main site container as well as the pageshare container. For simplicity, I utilized jQuery.
Adjust Site Margin (jsfiddle)
I created a method that adjusts the site margin based on the amount of space needed by the pageshare container. First, this method calculates the amount of space needed for the pageshare container (based on its width and its left offset) and the amount of space available (the site width subtracted from the window width, normalized to zero if negative). The method then calculates the difference between these two values and applies the value to the left margin of site container. This ensures that the pageshare container does not overlay the content. In addition, the reason I am setting and removing scroll event handlers is because otherwise the pageshare container will still appear over the content on a small window when you scroll left and right (example of issue).
function adjustSiteMarginForPageShare() {
// Get the window dimensions
var windowWidth = $(window).width();
var windowHeight = $(window).height();
// Get the site width
var siteWidth = $('#inner-wrapper').outerWidth();
// Get the pageshare dimensions
var pageshareWidth = $('#pageshare').outerWidth();
var pageshareHeight = $('#pageshare').outerHeight();
// Get the pageshare left offset
var pageshareLeft = $('#pageshare').offset().left;
// Calculate the needed pageshare space
var pageshareSpaceNeeded = pageshareWidth + pageshareLeft;
// Calculate the available pageshare space (division because of centering)
var pageshareSpaceAvailable = (windowWidth - siteWidth) / 2;
// Ensure the minimum available pageshare space as zero
pageshareSpaceAvailable = (pageshareSpaceAvailable > 0) ? pageshareSpaceAvailable : 0;
// If the pageshare space available is less than what is needed
if (pageshareSpaceAvailable <= pageshareSpaceNeeded) {
// Calculate the left margin needed as the difference between the two
var leftMarginNeeded = pageshareSpaceNeeded - pageshareSpaceAvailable;
// Add the left margin needed to the site
$('#inner-wrapper').css('margin-left', leftMarginNeeded);
// Modify the pageshare style
$('#pageshare').css({
'position': 'absolute'
});
// Set the pageshare scroll behavior
$(window).off('scroll.pageshare');
$(window).on('scroll.pageshare', function() {
// Set the bottom to top conversion factor (100% total height - 15% bottom offset = 85% top offset)
var conversionFactor = 0.85;
// Calculate the top offset based on the conversion factor and the pageshare height
var pageshareTopOffset = (conversionFactor * windowHeight) - pageshareHeight;
// Adjust the pageshare top offset by the current scroll amount
pageshareTopOffset += $(window).scrollTop();
$('#pageshare').css({
'top': pageshareTopOffset + 'px',
'bottom': 'auto'
});
});
// Trigger the pageshare scroll handler
$(window).triggerHandler('scroll.pageshare');
} else {
// Reset the pageshare style
$('#pageshare').css({
'position': 'fixed',
'top': 'auto',
'bottom': '15%'
});
// Turn off the pageshare scroll behavior
$(window).off('scroll.pageshare');
}
}
The last step is to call that method, both on page load and every time the window is resized.
// Adjust the content margin for pageshare container on load
adjustSiteMarginForPageShare();
// When the window is resized
$(window).resize(function () {
// Adjust the content margin for the pageshare container
adjustSiteMarginForPageShare();
});
Related
I have a HTML class navigation with the initial height of 100px and min-height is 40px. I want to change the height of the class, based on the scroll (if scroll down than size will decrease and if scroll up than size will increase). I use the following code and it's working perfectly.
$(window).scroll( function() {
if( $('.navigation').offset().top > 50 )
{
$('.navigation').css({
'height' : '40px',
'background' : 'rgba(37, 37, 37, 0.9)'
});
} else {
$('.navigation').css({
'height' : '100px',
'background' : '#b24926'
});
}
});
If I press the keyboard down arrow key two times than navigation class moved from original height to minimum height and if the up arrow key press two times than navigation class moved from minimum height to original height.
But I want to make the scroll more smooth (like 4-5 up or down key presses to reach from one height to another).
For example: initial height is: 100px and minimum height is 30px. Now:
if down arrow key is pressed/mouse wheel is move down one time than height will be 85px, if again down arrow is pressed height will be 70px and so on. That means for each down arrow key is pressed/mouse wheel is move down than height will decrease by 15-20px and for each up arrow key is pressed/mouse wheel is move up, height will increase by 15-20px.
Can anyone tell me how can I do that (without using third party api).
Thanks
You can use simple percent calculation to update height
var limitForMinimalHeight = 400; //after this distance navigation will be minimal height
var maxHeight = 100;
var minHeight = 40;
$(window).scroll( function() {
var screenTop = $(document).scrollTop();
var achievedDistancePercent = Math.min(screenTop*100/limitForMinimalHeight, 100);
var amounToAdd = ((maxHeight - minHeight) * (100 - achievedDistancePercent))/100;
var newHeight = minHeight + amounToAdd;
$('.navigation').height(newHeight);
});
You can test it on JSFiddle
$(document).scroll(function() {
if($(this).scrollTop()>100) {
$('.selector').addClass('scrolled');
}
if($(this).scrollTop()<40) {
$('.selector').removeClass('scrolled');
}
});
I have a div with an image background thats height is 100% so it fills the screen on any device. At the bottom of the screen is then a navigation bar. When the page is scrolled I want the navigation bar to fix to the top of the screen at a set distance away from the top.
I have tried using this JavaScript:
$(window).scroll(function(){
if ($(this).scrollTop() > 587) {
$('.hnav').addClass('hfixed');
} else {
$('.hnav').removeClass('hfixed');
}});
It works fine on my screen but on any other screen it doesn't because the navigation changes distance from the top depending on the window size because of the 100% height image.
How can I get the navigation to fix in place when its a set distance from the top regardless of the window size??
Thanks
You can get the element's position with element.getBoundingClientRect(), so you can add the 'hfixed' class once this returns a top value of 0:
var nav = $('.hnav');
var pos = nav.position();
$(window).scroll(function() {
var windowpos = $(window).scrollTop();
if (windowpos + 50 >= pos.top) {
nav.addClass("hfixed");
} else {
nav.removeClass("hfixed");
}
});
EDIT:
Added an extra margin of 50px to the calc, because the top bar.
EDIT 2:
Changed the example, now it's based on this
EDIT 3:
Add the 50px margin because the top bar to the new example
Wrapper - Overflow Hidden
Div One: Sidebar
Div Two: Main Content
Div Two will have a normal scroll. Div One I wish to have no visible scroll however when you scroll Div One it scrolls Div Two.
Upon Div One's height hitting the bottom, it will no longer scroll and visa-versa for scrolling back up.
This will result in the sidebar always being visible at the side. Before you ask, I've tried all positioning types to get this to work resulting in many failed attempts.
My live demo can be seen here: http://rafflebananza.com/admin/newadmin.html#
Note I've tried to make a JSFiddle simplified but my maths does not seem to work in there the same. Please suggest whether I should fork all my page to there or whatnot for future visitors needing the same help.
Overview
Scrolling in the wrapper will scroll sidebar to point x only (x being the sidebars height) then stopping but will continue to allow the content to be scrolled. Visa-versa for scrolling back up.
Somewhat half way there...
var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop,
position = document.body.scrollTop;
function scrollD() {
var scroll = document.body.scrollTop;
if (scroll > position) {
// Scrolling Down Functions
} else {
// Scrolling Up Functions
}
position = scroll;
}
Updated the answer to match OPs requirements.
I downloaded your website in its current state and made the following changes to your code:
var scrollY = 0;
$(window).scroll(function() {
var sideNav = $('.SideNav'); // The side navigation
var wScrollY = $(this).scrollTop(); // Current scroll position of Window
var navHeight = sideNav.height(); // Height of the Navigation
var StageHeight = $(window).height() - 46; // The display space
if(sideNav.height() > StageHeight) { // Do the following if the side navigation is higher than the display space
var spaceLeft = sideNav.height() - StageHeight; // spaceLeft -> how many pixel left before fixing navigation when scrolling
if(scrollY < wScrollY) { // Scroll direction is down
if (wScrollY >= spaceLeft) // If scroll top > space left -> fixate navigation at the bottom, otherwise scroll with the content
sideNav.css({top:46-spaceLeft+wScrollY});
if (wScrollY <= 46) // Set top strict to 46. Sometimes there is white space left, caused by the scroll event.
sideNav.css({top:46});
} else { // Scroll direction is up
var sideNavTop;
if (sideNav.offset().top < 0) {
sideNavTop = Math.pow(sideNav.offset().top); // if top is negative, make it positive for comparison
} else {
sideNavTop = sideNav.offset().top;
}
if (sideNavTop > (46+wScrollY)) // Fixate the header if top of navigation appears
sideNav.css({top:46+wScrollY});
}
} else {
sideNav.css({top:46+wScrollY}); // Fixate always
}
scrollY = wScrollY;
});
This will let you scroll your side navigation up until its end. Then fixate. If you scroll up, it will still be fixated until your reach the point, where the navigation must scrolled back to its original position.
You can check the edited version here: http://pastebin.com/Zkx4pSKe
Just copy the raw code into a blank html page and try it out.
It's a bit messy and maybe not the best solution, but it works.
Ok, here you go:
var $sidebar = $('.sidebar'),
$window = $(window),
previousScroll = 0;
$window.on('scroll', function (e) {
if ($window.scrollTop() - previousScroll > 0) {
$sidebar.css({
'top': Math.max($window.scrollTop() + $window.height() - $sidebar.outerHeight(true), parseInt($sidebar.css('top'))) + 'px'
});
} else {
$sidebar.css({
'top': Math.min($window.scrollTop(), parseInt($sidebar.css('top'))) + 'px'
});
}
previousScroll = $window.scrollTop();
});
http://jsfiddle.net/7nwzcpqk/1/
i might have misunderstood your desired result incorrectly but you can see if this works for you :
.SideNav {
position: fixed; // you currently have this as position:absolute;
}
You don't need nor a wrapper element nor jQuery. I assume that you are using a wrapper because you want to have the top bar placed there. I think there is a better way to do it by using simply three divs.
The top bar has to be fixed (to be always visible) and of full width.
The side bar also has to be fixed (to be always visible) with a top margin of the height of the top bar.
The content needs just a left padding (width of side bar) and top padding (height of top bar).
Here is the example code (http://jsfiddle.net/zckfwL4p/):
HTML
<div id="top_bar"></div>
<div id="side_bar">links here</div>
<div id="content"></div>
CSS
body {
margin:0px;
padding:0px;
}
#side_bar {
width:50px;
position: fixed;
left:0px;
top:20px;
background-color:blue;
}
#top_bar {
position:fixed;
height:20px;
left:0px;
right:0px;
background-color:red;
}
#content {
position:relative;
padding-left:55px;
padding-top:25px;
}
I want to put a bar on the bottom of my page containing a varying number of pictures, which (if wider than the page) can be scrolled left and right.
The page width is varying, and I want the pane to be 100% in width.
I was trying to do a trick by letting the middle div overflow and animate it's position with jquery.animate().
Like this:
Here is a fiddle without the js: http://jsfiddle.net/SoonDead/DdPtv/7/
The problems are:
without declaring a large width to the items holder it will not overflow horizontally but vertically. Is this a good hack? (see the width: 9000px in the fiddle)
I only want to scroll the middle pane if it makes sense. For this I need to calculate the width of the overflowing items box (which should be the sum of the items' width inside), and the container of it with the overflow: hidden attribute. (this should be the width of the browser window minus the left and right buttons).
Is there a way to calculate the length of something in js without counting all of it's childrens length manually and sum it up?
Is there a way to get the width of the browser window? Is there a way to get a callback when the window is resized? I need to correct the panes position if the window suddenly widens (and the items are in a position that should not be allowed)
Since the window's width can vary I need to calculate on the fly if I can scroll left or right.
Can you help me with the javascript?
UPDATE: I have a followup question for this one: Scroll a div vertically to a desired position using jQuery Please help me solve that one too.
Use white-space:nowrap on the item container and display:inline or display:inline-block to prevent the items from wrapping and to not need to calculate or set an explicit width.
Edit:: Here's a live working demo: http://jsfiddle.net/vhvzq/2/
HTML
<div class="hscroll">
<ol>
<li>...</li>
<li>...</li>
</ol>
<button class="left"><</button>
<button class="right">></button>
</div>
CSS
.hscroll { white-space:nowrap; position:relative }
.hscroll ol { overflow:hidden; margin:0; padding:0 }
.hscroll li { list-style-type:none; display:inline-block; vertical-align:middle }
.hscroll button { position:absolute; height:100%; top:0; width:2em }
.hscroll .left { left:0 }
.hscroll .right { right:0 }
JavaScript (using jQuery)
$('.hscroll').each(function(){
var $this = $(this);
var scroller = $this.find('ol')[0];
var timer,offset=15;
function scrollLeft(){ scroller.scrollLeft -= offset; }
function scrollRight(){ scroller.scrollLeft += offset; }
function clearTimer(){ clearInterval(timer); }
$this.find('.left').click(scrollLeft).mousedown(function(){
timer = setInterval(scrollLeft,20);
}).mouseup(clearTimer);
$this.find('.right').click(scrollRight).mousedown(function(){
timer = setInterval(scrollRight,20);
}).mouseup(clearTimer);
});
Thanks Phrogz for this part -- give the image container the white-space: nowrap; and display: inline-block;.
You can calculate the width without having to calculate the width of the children every time but you will need to calculate the width of the children once.
//global variables
var currentWidth = 0;
var slideDistance = 0;
var totalSize = 0;
var dispWidth = (winWidth / 2); //this should get you the middle of the page -- see below
var spacing = 6; //padding or margins around the image element
$(Document).Ready(function() {
$("#Gallery li").each(function () {
totalSize = totalSize + parseFloat($(this).children().attr("width"));// my images are wrapped in a list so I parse each li and get it's child
});
totalSpacing = (($("#Gallery li").siblings().length - 1) * spacing); //handles the margins between pictures
currentWidth = (parseFloat($("#Gallery li.pictureSelected").children().attr("width")) + spacing);
maxLeftScroll = (dispWidth - (totalSize + totalSpacing)); //determines how far left you can scroll
});
function NextImage() {
currentWidth = currentWidth + (parseFloat($("#Gallery li.pictureSelected").next().children().attr("width")) + spacing); //gets the current width plus the width of the next image plus spacing.
slideDistance = (dispWidth - currentWidth)
$("#Gallery").animate({ left: slideDistance }, 700);
}
There is a way to get the browser window with in javascript (jQuery example).
and there is a way to catch the resize event.
var winWidth = $(window).width()
if (winWidth == null) {
winWidth = 50;
}
$(window).resize(function () {
var winNewWidth = $(window).width();
if (winWidth != winNewWidth) {
window.clearTimeout(timerID);
timerID = window.setInterval(function () { resizeWindow(false); }, 100);
}
winWidth = winNewWidth;
});
On my gallery there's actually quite a bit more but this should get you pointed in the right direction.
You need to change your #items from
#items
{
float: left;
background: yellow;
width: 9000px;
}
to
#items {
background: yellow;
}
Then calculate the width very easily with jQuery
// #items width is calculated as the number of child .item elements multiplied by their outerWidth (width+padding+border)
$("#items").width(
$(".item").length * $(".item").outerWidth()
);
and simply declare click events for the #left and #right elements
$("#left").click(function() {
$("#middle").animate({
scrollLeft: "-=50px"
}, 'fast');
});
$("#right").click(function() {
$("#middle").animate({
scrollLeft: "+=50px"
}, 'fast');
});
jsFiddle link here
EDIT
I overlooked that detail about the varying image widths. Here is the correct way to calculate the total width
var totalWidth = 0;
$(".item").each(function(index, value) {
totalWidth += $(value).outerWidth();
});
$("#items").width(totalWidth);
I have an image on a webpage that needs to be stretched to fit the available space in the window whilst maintaining its proportion. Here's what I've got:
http://www.lammypictures.com/test/
I would like the large image to proportionally stretch to match the height and widths of the browser, minus the size of the divs to the left and bottom.
So the problem is 2 fold really; first i need to get the max height and width minus the link and image bars, secondly i need to resize the image on a browser resize whilst maintaining proportions.
Any help would be much appreciated.
Cheers
CIP
You could try using jQuery ui scaling effect:
$(document).ready(function () {
resizeImage(); // initialize
$(window).resize(function () {
resizeImage(); // initialize again when the window changes
});
function resizeImage() {
var windowHeight = $(window).height() - $('#nav').height(),
windowWidth = $(window).width(),
percentage = 0;
if (windowHeight >= windowWidth) {
percentage = (windowWidth / $('#image').width() ) * 100;
}
else {
percentage = ( windowHeight / $('#image').height() ) * 100;
}
$('#image').effect('scale', { percent : percentage }, 1);
};
});
Tested and works great, however, a few tweaks maybe needed to get it just the way you like it.
You may just not setup the image element width and height attributes, and write next styles:
.hentry img { max-width: 100%; }
And it will shrink relative to the minimum side.
P.S. But not in position: absolute; block which not have any size. Set up the parent block to relative positioning.