synchronizing scrolling between 2 divs with different text size - javascript

I can't find a way to synchronize two divs, with the same text, but different text size and padding.
I have two divs, one with a markdown text, and the other one with the html render of the markdown and I want to synchronize the scrollTop between the divs.
For an example, look stackedit.io

You can see the example of synchronizing two divs at: JSFiddle
HTML
Given you have two divs placed next to each other horizontally. Each of the divs contain another div and it is scrollable vertically:
<div class="outer" id="div1">
<div>
</div>
</div>
<div class="outer" id="div2">
<div>
</div>
</div>
CSS
This is just to make two outer divs lie next to each other at the same baseline and make it scrollable vertically.
div.outer
{
display:inline-block;
width:150px;
height:320px;
border:1px solid black;
overflow-y:auto;
}
div.outer > div
{
width:100%;
height:3000px;
}
JavaScript
The simplest approach is, bind scroll event to each of the outer divs, take the scrollTop value and apply to its counterpart div as follows:
$('#div1').scroll(function(){
$('#div2').scrollTop( $('#div1').scrollTop() );
});
$('#div2').scroll(function(){
$('#div1').scrollTop( $('#div2').scrollTop() );
});
So when you scroll on the left div, it synchronizes the right div, and vice-versa.

Related

Scroll vertically with fixed columns

I have a fixed-size container with dynamic content. The content is a series of items of varying heights. I want the items to flow vertically (each visually beneath the previous), but be able to inject a column break on a particular item. I use JavaScript to inject the column breaks, and thus know how many total columns are needed, and thus can inject the total column count somewhere (if helpful).
Here's what I had been using that I thought used to work in Chrome. The desire is to have A1-A5 in one column, and B1-B2 in a second column. The entire section should scroll vertically, not horizontally.
section { width:400px; height:300px; font:9pt sans-serif; overflow:auto }
div { margin-bottom:1em; -webkit-column-break-inside:avoid }
h3 { margin:0; background:#000; color:#fff; padding:4px; font-size:9pt }
span { display:block; height:45px; background:#ddd; padding:4px }
/* The following are injected by JavaScript */
section { -webkit-column-count:2 }
#B1 { -webkit-column-break-before:always }
<section>
<div id="A1"><h3>A1</h3><span>content</span></div>
<div id="A2"><h3>A2</h3><span>content</span></div>
<div id="A3"><h3>A3</h3><span>content</span></div>
<div id="A4"><h3>A4</h3><span>content</span></div>
<div id="A5"><h3>A5</h3><span>content</span></div>
<div id="B1"><h3>B1</h3><span>content</span></div>
<div id="B2"><h3>B2</h3><span>content</span></div>
</section>
As seen in Chrome, the above snippet wraps A4 onto a second column and creates three columns scrolling horizontally. How can I achieve my desire of two columns, scrolling vertically?
It is easy for me to change the global CSS, and to apply new custom CSS to each <div> with JavaScript, but (for complex reasons) it is hard for me to modify the DOM using JavaScript. I'd prefer a solution that does not modify the DOM.
I believe the problem you're having it to do with defining the height of the "section" element in the first css block. Make it so:
section { width:400px; height:auto; font:9pt sans-serif; overflow:auto }
Everything should be fine with that change. jsfiddle here
You will lose the fixed size though. I couldn't find a configuration that didn't fail this requirement.

Prevent divs from wrapping, but do not add default scroll

Alright, so I'm a little puzzled about this: as you can see on the site for the Polymer Project, they have tabs that are horizontally scrollable if there are too many. I'd like to replicate this effect, but I can't figure out how to both prevent the <div> elements for tabs from wrapping as well as scrolling. Obviously, JS will need to be used here. Unless it's possible to get a custom scrollbar?
How can I do the above? A non-jQuery solution would be very much preferable.
Should be able to use plain JavaScript or jQuery to compare the calculated width of the inner div to the set width of the outer div. If #inner is wider than #outer, add a class to one of the divs to change how they're displayed. If not, remove the class.
The markup:
<div id="outer">
<div id="inner">
<div class="scroll-button"></div>
<!-- your tabs here -->
<div class="scroll-button"></div>
</div>
</div>
The styling:
#outer{
width:500px;
overflow-x:hidden;
}
#outer .scroll-buttons{
display:none;
}
#outer.has-scroll-buttons .scroll-button{
display:block;
}
Give the divs a fixed height and dynamic length. Where the length property of the div is made by counting the number of columns you want in a div.
Why the aversion to jquery?

Vertical align absolute positioned div

I have two elements; input field and div - one next to another. Div is absolute positioned inside the relative element and positioned to the right of the input.
Input has fixed height, but div's height depends on the content.
What i would like to achieve is to middle vertical align div next to input. I am not sure if this is pure CSS possible, so thats why i added the javascript tag.
HTML:
<td>
<input type="text"/>
<div id="rel" style='position:relative;'>
<div id="content">
content
</div>
</div>
</td>
CSS:
#content {
position:absolute;
left:30px;
}
...
Just use
td input {
vertical-align:middle;
}
Good you already have a table, vertical centering via CSS is not easy.
Btw: Instead of two divs and absolute positioning, you might use margin-left: -30px;

How to reposition CSS-hover popups to stay within a fixed frame?

I have a page filled with many fixed-size boxes in a grid layout (div's simply piled up with float:left). On hovering the mouse on any of them, a 'popup' - larger div with the same and also additional info is shown over it, as if the box expanded in all directions (but not moving the other boxes, it's shown also over them). Simplified html/css below. It's like thumbnails/full images, but the actual content is a pile of various html data, including links, etc.
The problem is that in this way the 'popup' div for the leftmost/rightmost boxes goes over the screen, triggering the scrollbar; or they are cut off if I don't allow the overflow.
I would like instead to reposition these popups to left/right so that they stay within the total borders. How to approach this need?
I can't do this server-side as the server does not know which boxes will be rightmost/leftmost - it depends on window size, how many columns will fit there. My first idea is to use javascript to change the positioning for all the popups right after the page is loaded, but I don't know how to a) find out which popups would be sticking out of the frame; and even b) find out the size of the popups, since they are hidden normally, which means width=height=0 until they are shown.
Perhaps a completely different approach of showing these popups would be easier than repositioning the div's that I currently have?
Currently Prototype/scriptaculous is used at some other pages, the server side is ruby on rails.
<div class="frame">
<div class="box", id="object123" >
small, fixed size content here
<div class="popup">
large, variable size/width/height content here that describes object123
</div>
</div>
<div class="box", id="object456" >
small, fixed size content here
<div class="popup">
large, variable size/width/height content here that describes object456
</div>
</div>
... many other similar boxes.
</div>
div.frame {
overflow: hidden;
}
div.box {
border:1px solid #efe9dc;
margin:5px;
position:relative;
float:left;
height:70px;
width:150px;
}
div.popup {
min-width:200px;
display:none;
position:absolute;
left:-30px;
top:-30px;
z-index:1000;
}
div.box:hover .popup { display: block; }
right now your div.popup is positioned absolute to div.box; if you removed the position from div.box and put it on div.frame, the popups would be absolute to the frame. you can then set left/top/right/bottom to be offset from the frame's edges instead.
i hope this helped :)
In the end this is what I did.
I replaced the popups with css+jquery script that expands the content box larger/above the normal grid; centers the 'popup' over the place of the original box, and if it goes over the sides, then adjusts the position.
As a bonus, the functionality works on everything that I tag with the 'expands' 'expand_show' 'expand_hide' classes, so no duplication as it is applied in several places.
sample html
<div class="box_grid expands">
<div class="box_content">
basic content that's always visible
<p class="expand_hide>short content summary shown in the small boxes</p>
<p class="expand_show> detailed content</p>
<div class="expand_show> detailed extra content</div>
</div>
</div>
css and javascript to show it
div.box_grid {
margin:5px;
float:left;
height:80px;
width:170px;
}
div.expanded { position:relative; }
div.expanded > * {
position:absolute;
width:auto;
height:auto;
z-index:1000;
min-width:100%;
min-height:100%;
}
div.expands .expand_show { display:none; }
div.expanded .expand_show { display: block; }
div.expanded .expand_hide { display: none; }
$(document).ready(function(){
$('.expands').hover(
function(){
grid = $(this);
expanded = grid.children();
border = $('.content_borders');
grid.addClass('expanded');
var top = (grid.outerHeight() - expanded.outerHeight())/2;
var left = (grid.outerWidth() - expanded.outerWidth())/2;
var left_limit = border.offset().left + 5 - grid.offset().left;
var right_limit = border.offset().left + border.outerWidth() - expanded.outerWidth() - 5 - grid.offset().left;
var bottom_limit = border.offset().top + border.outerHeight() - expanded.outerHeight() - 5 - grid.offset().top;
if (left < left_limit) { left = left_limit }
if (left > right_limit) { left = right_limit }
if (top > bottom_limit) { top = bottom_limit }
expanded.css('top',top);
expanded.css('left',left);
},
function(){ $(this).removeClass('expanded') }
);
});
As my understanding you have multiple small divs which ave the thumbnails and you have a div to sow large content for each image.
So for each image there are two divs.
Tats why you are having difficulty for each div.some will be left , some center , some on right.
Instead of that , use a common div to show large content for all the smaller div.
Pass a parameter on hover and show the content in that div using server side code.
That means your style is fine , you just position only one div in center by using
left:100px
top:100px
you modify it as you want. Put large content in that single div for all smaller divs
Use Firefox Firebug for better understanding of position

How can I prevent one div from overlapping another on resize?

Here's an example: http://la.truxmap.com/truckpage?id=coolhaus
When I make the browser window narrower from the right hand side, the recent tweets div will go underneath the container div. i want to make it so that the recent tweets div can go no further left than the right hand border of the container div. Ive been trying to figure out if it can be done with css, but i cant seem to get it. is there a simple javascript solution that fits the bill?
Thanks!
You can either choose to work with a liquid layout or use the css property position.
Liquid layout:
You got 3 DIV's in your wrapper divand you want them to resize on a smaller browser window, you can do this with percentages that become variable widths :
css:
.wrapper {
width:100%
}
.divleft {
float:left;
width:20%
}
.divmiddle {
float:left;
width:60%
}
.divright {
float:left;
width:20%
}
html:
<div class="wrapper">
<div class="divleft">left</div>
<div class="divmiddle">middle</div>
<div class="divright">right</div>
</div>
As i said, the other possibility is the assigning the css property position to your different DIV's.
Try it yourself, its fairly easy:
http://www.w3schools.com/Css/pr_class_position.asp
You can also keep them from overlapping vertically:
.noOverlap{
float:left;
width:100%;
}

Categories