How to synchronize scroll between two elements with different height - javascript

I have two DIV elements #page and #block :
<div id="page"></div>
<div id="block"></div>
#block element has fixed position and long content inside with overflow:hidden property.
#page element has some content inside too, but it height of #page will be longer or shorter then #block height.
My goal is to achieve synchronized scroll between this two elements. Something like this:
I need to calculate speed of #block element scroll, because header and footer elements of #page and #block should be at same position from beginning and at the end of scroll.
The way I tried to achieve this:
Calculated height of #page element
Calculated height of #block element content (because block element is fixed and has alwas fixed height)
Calculated #block element scroll speed by:
$("#block").outerHeight / $("#page").outerHeight
Triggered .scrollTop() of #block
It's working from the beginning and #block element scroll is faster then #page element scroll, but at the end, #block is not scrolled fully.
Here is my JsFiddle: http://jsfiddle.net/zur4ik/bQYrf/2/
Maybe anyone can see what I'm doing wrong?
Thanks in advance.

You must take the window height into the case and subtract it from the elements heights.
$(window).scroll(function() {
var pageH = $('#page').height() - $(this).height();
var pageT = this.scrollY - $('#page').offset().top;
$('#block').scrollTop(pageT / pageH * ($('#blockLength').height() - $(this).height()));
});
Here's the updated fiddle: http://jsfiddle.net/bQYrf/4/

I have found two examples of this same question already answered in SO:
If I understand you question correctly this is exactly what you are looking for:
Synchronized scrolling using jQuery?
This is also a good solution:
How do I synchronize the scroll position of two divs?

function getClientHeight()
{
return document.compatMode=='CSS1Compat' && !window.opera?document.documentElement.clientHeight:document.body.clientHeight;
}
var clientHeight = getClientHeight();
$(window).scroll(function() {
var diff = ($("#blockLength").height() - clientHeight) / ($("#page").height() - clientHeight);
var blocktoSet = $(window).scrollTop() * diff;
$("#block").scrollTop(blocktoSet);
console.log()
});
http://jsfiddle.net/PeGky/1/

Related

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', '');
}

How to snap elements to grid by jquery or javascript

There are some elements that have class='snap'
I want to find these elements in the body. Then snap and resize elements to fit grids by Jquery.
When?
The document is ready.
The window is resized.
Note:
Size of grid cells are 10px
Contents of elements can be different.
Element can move down maximum in 1 cell size. (Up is not allowed).
Because of responsive elements, It's not true to snap the element by specifying width and height.
See on JsFiddle
Any ideas or help would be greatly appreciated.
JsFiddle updated: Removed width of .content in CSS, It can be not specified.
What you could do, and this is just an idea that is perfectible, is getting the offset of the .snap div and remove all margins. Then you snap to the next (right and bellow) lines :
var Content = {
snapElement: function(element){
offset = element.offset();
element.css('left', (Math.ceil(offset.left/10)*10)+'px');
element.css('top', (Math.ceil(offset.top/10)*10)+'px');
element.css('margin', '0');
},
snapElements: function(){
var elements = $("body").find(".snap");
elements.each(function(){
Content.snapElement($(this));
});
}
}
You will also have to make your .snap divs relative :
.snap {position:relative;}
The demo
You can also keep the margins but you will have to subtract them to the left and top.
Edit : A more sophisticated demo that handle width

Get the width of the viewport and apply it to a tag or class width

I have horizontal layout and it has 5 inline divs. Is there a way in javascript to get the width of the users' viewport then apply it to the each content panel tags width, so it will be 100% in every content panel? I need it to be 100% of the viewport because there are parallax elements inside it
I have tried this css code below but the panels are just stacking on top of each other.
#contentPanel { width: 100%; float: left;}
I really don't know if the questions makes any sense, because I've been up for 16 hours searching and trying to work this out.
It's easy with JQuery:
var fullDiv = $("div");
var viewportWidth = $(window).width();
var viewportHeight = $(window).height();
$("body, html").width(3*viewportWidth);
fullDiv.width(viewportWidth);
fullDiv.height(viewportHeight);
Simple Demo.
You will want to update the divs when the browser is resized probably, currently it only works when it first loads. Read more about .resize().

javascript scroll to bottom of div if current scroll location is near bottom

I am working on a script that will append text (varies on size) to a div block (varies in height) with overflow scroll. After this text is appended I need the div block to be scrolled to the bottom in order to see the new appended text, however I need it only to scroll to the bottom if the current scroll position is around 10% of scroll close to the bottom, otherwise it would be annoying if it scrolled down while viewing the top portion of the div.
This is what I came up with, it is run after text is appended:
var divblock = document.getElementById('div'); //the block content is appended to
var divheight = divblock.offsetHeight;//get the height of the divblock
//now check if the scroller is near the bottom and if it is then scroll the div to the abslute bottom
if (***HELP HERE***) divblock.scrollTop=divblock.scrollHeight; ///scroll to bottom
much appreciated thanks!
if( divblock.scrollTop < divblock.scrollHeight )
div.scrollTop + lineheight > scrollHeight
Like this?
You just need to check to see if scrollTop is greater than 90% of the scrollHeight.
if (divblock.scrollTop > divblock.scrollHeight*0.9) {
divblock.scrollTop=divblock.scrollHeight;
}
scrollHeight = scrollTop + clientHeight + [fudge factor]
The "fudge factor" seems to be around 30-40 (pixels) for me. So try this:
if ((divblock.scrollTop + divblock.clientHeight + 50) > divblock.scrollHeight) {
...
}

javascript jquery find left position of element in horizontal scroll container

I have a overflow:auto container that spans 400% width of the document window. Therefore I have a horizontal scrollbar on my page. I also have multiple div's inside this container with different left positions. I need to get the left position of each container as I click on them. I use $(this).offset().left but that gives me the left offset of the container div which is 0px and I've used $(this).position().left but that gives me the same thing.... any suggestions?
Markup looks like this:
<div id='scroll'>
<div id='content'>
<div class='container' rel='1'></div>
<div class='container' rel='2'></div>
<div class='container' rel='3'></div>
<div class='container' rel='4'></div>
</div>
</div>
css
#scroll{
position:absolute;
width:100%;
height:95%;
overflow:auto;
}
#content{
float:left;
height:100%;
}
.container{
height:100%;
float:left;
}
jquery
var iMaxSize = $(".container").size();
$("#content").css({width: $(document).width()*iMaxSize +'px' });
$(".container").css({width: $("#content").width()/iMaxSize +'px' });
You can use the scroll position in the container element like this;
$('#container .element').offset().left - $('#container').offset().left + $('#container').scrollLeft();
See JSFiddle here
Use position() instead of offset if you having trouble with offset.
Use width() of the object your scrolling to account for it.
Of course you can change the selector types to use ids or whatever fits your situation.
$('.class for container div')
.animate( { scrollLeft:
$('.class for you want to scroll to').position().left -
$('.class for you want to scroll to').width() }
,'slow');
did you try something like this...
$('#id').width();
I haven't used it myself before, but I imagine it works similarly to scrollTop - take a look at scrollLeft() One thing you'll need to do is find the starting scrollLeft position of the element before scrolling occurred and cache it - then subtract that from the new scrollLeft position obtained after scrolling.
edit Wait, offset() isn't working? It should be working.
Since for some reason I still can't get .offset() to work the way it should, or scrollLeft(). I just decided to do this a very round about way.
$('.container').click(function(){
var num = parseInt( $(this).attr('rel') );
var left = $('.container').width() * num-1;
var top = $('.container').css('top');
//do something with these values
});

Categories

Resources