How to synchronize two scrollbars for divs with different style overflow - javascript

I have a problem trying sync scroll in divs, I have a two divs, the first div has a style with overflow: hidden and the second div has the style with overflow:scroll,then i found a several answers for sync scroll in divs using jquery for example :
$("#div2").scroll(function () {
$("#div1").scrollTop($(this).scrollTop());
});
http://jsfiddle.net/gqHyW/43/
but i have a problem with that solution because at the bottom of scroll the divs are desynchronized , see the image .
Someone has an idea how to solve this error.
Thank you in advance

Your horizontal scroll is showing despite not needing to be there. You can target your horizontal scroll and hide it, while keeping your vertical scroll:
.bottom {
left : 50%;
overflow-y : scroll;
overflow-x : hidden;
}

My bad on my previous answer.
I see what you're after now.
You need to rifle through your P tags and sync the heights depending on the content heights in each.
Here's a function that ought to work in either direction:
var topPs = $(".top p");
var bottomPs = $(".bottom p");
for(var i=0; i< topPs.length;i++){
var topPHeight = $(topPs[i]).height();
var bottomPHeight = $(bottomPs[i]).height();
console.log(bottomPHeight);
if(bottomPHeight>topPHeight){
$(topPs[i]).height(bottomPHeight);
}else{
$(bottomPs[i]).height(topPHeight);
}
}
You still need the horizontal scroll fix I mentioned in my other answers.
I rolled it into a single fiddle: http://jsfiddle.net/op9nddoq/1/
Edit: since this isn't a layout hack, it's perfectly acceptable to use a table here, as it's a table, and the cell heights will adjust all by themselves.

Related

Overflow: hidden but i still want to have the empty scrollbar

I set 'overflow:hidden' on my html body with Javascript when I press a button. But when I do that the whole body moves 5 pixels or so to the left because the space of the scrollbar is gone. How do i prevent that.
I can't set margin of the body to a specific size because the width of scrollbars differentiate between browsers
Since the previous solution does not work anymore (see original answer below), I've come across another solution which works for me and, according to MDN, it should work in all browser, with IE starting from version 6.
This solution to get the scrollbar width is even a bit simplified:
Append a div without a scrollbar to the body and position it off screen
Measure the client width of the div
Set the div to have a scrollbar (using css overflow style)
Measure the clientWidth of the div again
Remove the div
Return the difference of the two widths
And the code would look like this:
function scrollbarWidth() {
var div = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"></div>');
// Append our div, do our calculation and then remove it
$('body').append(div);
var w1 = div.prop('clientWidth');
div.css('overflow-y', 'scroll');
var w2 = div.prop('clientWidth');
$(div).remove();
return (w1 - w2);
}
And here is a working jsFiddle.
Original answer (for completeness sake)
Here is a solution to calculate the width of a scrollbar, which you can use in conjuction with some of the other answers here (and your own knowledge as far as I can tell).
The idea is to do the following steps:
Append two divs to the body and position them off screen
Measure the width of the inner div
Set the outer div to overflow
Measure the width of the inner div (again)
Remove the divs
Return the difference of the two widths
And here is the code, copied from the referenced page:
function scrollbarWidth() {
var div = $('<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
// Append our div, do our calculation and then remove it
$('body').append(div);
var w1 = $('div', div).innerWidth();
div.css('overflow-y', 'scroll');
var w2 = $('div', div).innerWidth();
$(div).remove();
return (w1 - w2);
}
You could try this old trick:
html {
overflow-y: scroll;
}
What this does is force the scrollbar to always be visible.
Compare:
normal JSFiddle
JSFiddle with the vertical scrollbar always there
Here is code to add a disabled vertical scroll bar. If placed more prominent in CSS than the rest of the CSS, it should override whatever you've done to other portions.
html {
overflow-y: scroll;
}
You could always put a wrapper around the content that you are hiding and then place the overflow: scroll on div and overflow: hidden on the content div.
#wrapper { overflow-y: scroll; }
#content { overflow: hidden; }
See the attached fiddle for a working version
http://jsfiddle.net/15km/bfpAD/1/

Creating CSS divs that read top-bottom, left-right and overflow to the right

I'm trying to get my divs to flow top-to-bottom, but upon reaching the bottom of the window, overflow new divs to the right. See template layout: http://i.imgur.com/nknD0.png
I've tried css/javascript combinations of... white-space:nowrap, display: inline, display: table, float:left, and others but can't seem to get it working like in the diagram.
Use float: right on each of the divs
See fiddle: http://jsfiddle.net/maniator/wzYpV/
(make the pane larger and smaller to see the effect)
Here is a fiddle that makes columns: http://jsfiddle.net/maniator/wzYpV/
I used jQuery:
var maxHeight = $('.overflow').height();
var floatHeight = $('.float').height();
var amountOfFloat = $('.float').length;
if(floatHeight * amountOfFloat > maxHeight){
var minPer = Math.floor(maxHeight / floatHeight);
var overflow = $('.overflow');
$('.float').each(function(index, item){
console.log(item, index);
if(index%minPer == 0 && index != 0){
overflow = $('<div>', {class: 'overflow'});
$('body').append(overflow);
}
$(item).appendTo(overflow);
})
}
First
http://jsfiddle.net/nPSUM/
Second
http://jsfiddle.net/AKW5A/1/
Well it's not really fully supported yet but multi-column layouts are in CSS3.
http://www.quirksmode.org/css/multicolumn.html
So how about something like this?
http://jsfiddle.net/nPSUM/6/
i think it doesnt quite act like youd want it to but its pretty close.. i think..

Chrome Extension Scrollbar Placement

After dabbling in Chrome Extensions I've noticed that when the data inside the Page Action gets to a certain point the scroll bars automatically attach themselves to the popup, this I expect. However, instead of pushing the content to the left of the scroll bar it overlays the content causing a horizontal scrollbar to become active. I ended up just adding a check on my data and applying a css class to push the content to the left more to run parallel to the scroll bar and beside it not under it. What is the correct way to handle this besides my hackish solution?
I was wondering this myself too. Currently I just don't put anything important closer than 20px to the right side of a popup and disable horizontal scrollbars:
body {overflow-x:hidden;overflow-y:auto;}
So when a vertical scrollbar appears the content at least doesn't jump.
Perhaps you need to specify a width on the scrollbar.
::-webkit-scrollbar {
width: 42px; //Do not know actual width, but I assume you do
}
I haven't found a way to do this that isn't a hack, but here's the simplest hack I could think of:
<script type="text/javascript">
function tweakWidthForScrollbar() {
var db = document.body;
var scrollBarWidth = db.scrollHeight > db.clientHeight ?
db.clientWidth - db.offsetWidth : 0;
db.style.paddingRight = scrollBarWidth + "px";
}
</script>
...
<body onresize="tweakWidthForScrollbar()">
The idea is to detect whether the vertical scrollbar is in use, and if it is, calculate its width and allocate just enough extra padding for it.

Always scroll a div element and not page itself

I have a page layout with an inner <div id="content"> element which contains the important stuff on the page. The important part about the design is:
#content {
height: 300px;
width: 500px;
overflow: scroll;
}
Now when the containing text is larger than 300px, I need to be able to scroll it. Is it possible to scroll the <div>, even when the mouse is not hovering the element (arrow keys should also work)?
Note that I don’t want to disable the ‘global’ scrolling: There should be two scrollbars on the page, the global scrollbar and the scrollbar for the <div>.
The only thing that changes is that the inner <div> should always scroll unless it can’t be moved anymore (in which case the page should start scrolling).
Is this possible to achieve somehow?
Edit
I think the problem was a bit confusing, so I’ll append a sequence of how I would like it to work. (Khez already supplied a proof-of-concept.)
The first image is how the page looks when opened.
Now, the mouse sits in the indicated position and scrolls and what should happen is that
First the inner div scrolls its content (Fig. 2)
The inner div has finished scrolling (Fig. 3)
The body element scrolls so that the div itself gets moved. (Fig. 4)
Hope it is a bit clearer now.
(Image thanks to gomockingbird.com)
I don't think that is possible to achieve without scripting it, which could be messy, considering the numerous events which scroll an element (click, scrollwheel, down arrow, space bar).
An option could be using the jQuery scroll plugin. I know it has the availability to create scrollbars on an div. The only thing you need to add yourself is the logic to catch the events when keyboard buttons are pressed. Just check out the keycodes for the arrow keys and make the div scroll down.
The plugin can be found here.
You can use it like this;
<script type="text/javascript">
// append scrollbar to all DOM nodes with class css-scrollbar
$(function(){
$('.css-scrollbar').scrollbar();
})
</script>
here is a solution that might work: (fiddle: http://jsfiddle.net/maniator/9sb2a/)
var last_scroll = -1;
$(window).scroll(function(e){
if($('#content').scrollTop());
var scroll = $('#view').data('scroll');
if(scroll == undefined){
$('#content').data('scroll', 5);
scroll = $('#content').data('scroll');
}
else {
$('#content').data('scroll', scroll + 5);
scroll = $('#view').data('scroll');
}
/*
console.log({
'window scroll':$('window').scrollTop(),
'scroll var': scroll,
'view scroll':$('#view').scrollTop(),
'view height':$('#view').height(),
'ls': last_scroll
});
//*/
if(last_scroll != $('#content').scrollTop()){ //check for new scroll
last_scroll = $('#content').scrollTop()
$('#content').scrollTop($('#content').scrollTop() + scroll);
$(this).scrollTop(0);
//console.log(e, 'scrolling');
}
})
It is a bit buggy but it is a start :-)
The only way I believe you can achieve this is through the use of frames.
Frames - W3Schools Reference
If you just want to have a fixed positioned "div" and scroll only it, maybe you could use a trick like:
http://jsfiddle.net/3cpvT/
Scrolling with mouse wheel and all kinds of keys works as expected. Only thing is that the scrollbar is on the document body only.
I found a solution... Not perfect... http://jsfiddle.net/fGjUD/6/.
CSS:
body.noscroll {
position: fixed;
overflow-y: scroll;
width: 100%;
}
JS (jQuery):
if ($("body").height() > $(window).height()) {
var top;
$('#scrolldiv').mouseenter(function() {
top = $(window).scrollTop();
$('body').addClass('noscroll').css({top: -top + 'px'});
}).mouseleave(function() {
$('body').removeClass('noscroll');
$(window).scrollTop(top);
});
}
The text wrapping problem can be solved putting the whole content in fixed-width div. There is another bug for IE browser. If the page has center-aligned backgrond, it will move left-right on mouseenter on #scrolldiv

jScrollPane Scrollbar height relative to div

I have a resizable div which is using custom scrollbars of jScrollPane.
I want to have vertical scrollbar above the resize handle, is it possible to do so?
I tried changing verticalTrackHeight to be always 40 less and bar size reduces too, but when we scroll the scroller goes to the bottom.
Here is my code http://www.jsfiddle.net/WRMSn/4/
It seems like some extra space is somehow being added below the scrollbar. You can use a jspCap to get around this using some code like this:
.jspCapBottom {
display: block;
height: 22px;
}
I added that to your fiddle and it seems to work well:
http://www.jsfiddle.net/UnEqt/
You forgot ; on var pane = $("#container")
It should be var pane = $("#container");

Categories