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
});
Related
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', '');
}
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/
This is how I call it
document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
document.addEventListener('DOMContentLoaded', function () { setTimeout(loaded, 200); }, false);
/**/
$(document).ready(function() {
//Created an array for adding n iScroll objects
var myScroll = new Array();
$('.content').each(function(){
if($(this).attr('id')==null){
$(this).attr('id') = $(this).attr('class');
}
id = $(this).attr('id');
console.log(id);
$(this).html('<div class="scroller">'+$(this).html()+'</div>');
myScroll.push(new iScroll(id));
});
});
I modified it a little bit so you can use it with a class and not only id.
It seems to work (to be enabled) because I can drag the container and its content (but it wont keep position, it will restore on mouse release)
If you want to see it happening please visit http://toniweb.us/grano and click on any item in the menu, the new shown has the effect.
Any idea why it is working but not as expected?
The reason I want to do this is because the container has several subcontainers that will be hidden or shown depending on the content selection.
CSS:
#nvl1{
padding:0px 25px;
z-index:10;
position:absolute;
left:0px;
background:url("../img/fondoNivel2.jpg") no-repeat scroll right 0 #79797B ;
height:100%;
}
#nvl1 .content{
width:650px;
z-index:11;
display:none;
color:#6666b6b;
position:relative;
line-height:30px;
}
I had a look at your code on: http://toniweb.us/grano
I think what you would like to do is use iScroll on your class with "scrolling". That is not what you are doing in the following code but instead you are actually setting iScroll to use the parent of your scroller DIV:
id = $(this).attr('id');
$(this).html('<div class="scroller">'+$(this).html()+'</div>');
myScroll.push(new iScroll(id));
For reference: iScroll uses an ID rather than a class
The effect this is having is that it is causing the "snap" effect on the immediately following block level element - your scroller DIV.
Consider this example where there is a DIV (id="scroller") containing an OL which contains a number of (block level) LIs:
http://cubiq.org/dropbox/iscroll4/examples/simple/
Long story short, give your DIV with the scroller class an id and create your iScroll from that instead.
if you set the style on the div tag you put the scroller on to (example)
style="position:relative;overflow: hidden;height:350px;
i think it's setting the height explicitly that should solve the dragging problem
Don't you just want:
.content {overflow-y:scroll;}
Is that not what you're saying mate?
The elements within the scroll div can't be floating. If they are floating and not cleared the flow of the page will mean your scrolling div is not the correct height. Try avoiding any floats within your scrolling and div and see how that goes. This was the problem for me.
I also found Matthews answer to be helpful as I was also calling iscroll on the wrong div. I think the confusing thing about the iScroll example is that it's easy to assume iScroll is called on the div with the ID scroller, but it's called on the wrapper div. The div with the ID scroller doesn't actually need an ID and I think for the examples sake this would be clearer without that. e.g.
<div id="wrapper">
<div>
<p>Whatever you want here</p>
<ul>
<li>1</li>
</ul>
</div>
</div>
...
myScroll = new iScroll('wrapper');
For example I have I a div tag with the scroll bar on the right of the div tag.
I want to show the div with the last line, so I have this:
document.getElementById("divscroll").scrollTop = 250000;
I can make it scroll to the end in Firefox but never succcess with IE event with the bigger number!
Is there any simple Cross-borwser script (not JQuery or any big framework!)
scrollTop works in all major browsers.
To scroll to the bottom of the element:
var div = document.getElementById('divscroll');
div.scrollTop = div.scrollHeight - div.clientHeight;
clientHeight also works across browsers, and scrollHeight mostly works.
Make sure that overflow property is set:
<div id="divscroll" style="height: 100px; width: 100px; overflow: scroll;">
//// something something
</div>
Try setting the scroll position to a real figure, instead of just an arbitrary big number:
document.getElementById("divscroll").scrollTop = document.getElementById("divscroll").scrollHeight;
I needed to put in a flyout menu real quick for a client. I didn't want to mess with the CSS or HTML as they have it styled without JS exactly how they want it and they just want me to add the JS. I just thought it'd be simple to set the inner <ul> to position absolute and then the top offset to be the top of the parent <li> but it's not working at all. not even close.
$(function(){
$('#snav-links > li > ul').css({
display:'none',
position:'absolute',
background:'#00182E',
left:$('#snav-links').width()+'px'
})
.parent().hover(
function(){
$(this).find('ul').css({display:'block',top:$(this).offset().top+'px'})
},
function(){
$(this).find('ul').css({display:'none'})
}
);
});
Here is the page: http://www.nwcidisplays.com/_temp/
Hover over the left sidebar menu items Banner Stands and Truss Displays. You'll see how off it is. Im not sure how to fix it. Ideas?
The culprit of you troubles is the anchors within #snav-links > li. They are floating and don't take up space withing the li-element. This will lead the li element to have the minimal height and they are positioned way above the actual link.
Remove the float and set the parent to relative positioning and that's it: http://jsfiddle.net/rEVwd/6/.
You'll also have to tweak the margin or padding in the li-elements so that the end result will be the same as before.
If you set position of #snav-links > li element to relative then the nested absolute ul will be relative to that container.
So (top 0, left 0) for your ul will be the top corner of the LI.
$('#snav-links > li').css({
position:'relative', // magic here
}.find(' > ul').css({
display:'none',
position:'absolute',
background:'#00182E',
top:0,
left:$('#snav-links').width()+'px'
}).end() // end() will take to back to the last selector (ie. $('#snav-links > li'))
.hover(
function(){
$(this).find('ul').css({display:'block'})
},
function(){
$(this).find('ul').css({display:'none'})
}
);
You might then need to adjust the top and left based on that menu size (i'm not sure how your menu looks like)
If you inspect with FireBug the parent li is positioned quite a bit above the button. (As Aleksi said, due to it being a floated element) (The button shows up as a.slink, it's parent li is located above it) So when you're retrieving the offset of the li, you're getting that location.
So you could try using the a.slink instead as it's positioned where you want it.
Also, to position the left directly next to the button, you'll need the offset + width of #snav-links
$(function(){
$('#snav-links > li > ul').css({
display:'none',
position:'absolute',
background:'#00182E',
left:$('#snav-links').offset().left + $('#snav-links').outerWidth()+'px'
})
.parent().hover(
function(){
$(this).find('ul').css({display:'block',top:$(this).find('a').offset().top+'px'})
},
function(){
$(this).find('ul').css({display:'none'})
}
);
});