Move overflowed elements to another div - javascript

I have a div with fixed height and another div below it with fixed height. I want elements (whole elements) that cannot fit within first div to move to another div. I don't want elements to be cut- just moved in whole and I want the order to be kept- so span2 will never be before (higher) than span1.
<div id="div1" style="height: 200px; width: 300px">
<span id="span1">Hello world<span>
<span id="span2">El 1</span>
</div>
<div id="div2" style="height:200px; width: 300px"></div>
Is this possible with just CSS? It doesn't really have to move from div1 to div2. I need just 2 containers of fixed height and moving elements between them. Can this be done with CSS columns? Or flex?
JS FIDDLE:

Try the FIDDLE.
Following code checks the DIV overflow status.
Javascript:
function IsDivOverFlow(div)
{
if (div.outerHeight() < div.prop('scrollHeight') || div.outerWidth() < div.prop('scrollWidth')) {
return true;
} else {
return false;
}
}
Using the function on button click
var Count = 0;
$('button').click(function()
{
var EditableContent = '<span contenteditable=true>'+(++Count)+' : TEST</span>';
var oldHTML = $('#div1').html();
$('#div1').append(EditableContent);
if(IsDivOverFlow($('#div1'))){
$('#div1').html(oldHTML);
$('#div2').append(EditableContent);
}
});
Hope it helps....

If you want to use css columns you can use something like this, but only using one div instead of two:
.your_class{
-webkit-column-count: 3; /* Chrome, Safari, Opera */
-moz-column-count: 3; /* Firefox */
column-count: 3;
}

Related

set a newly created div on top of the older divs

I have a bunch of divs inside a container. The position of the content divs is relative, because I want them to appear one below the other and their height is unknown.
These divs are created dynamically (appendchild) inside the container div. Now, each div appears on the end (bottom) of the stack but my requirement is that the divs have a "newest first" option too, that is, each new div appears on top, not on bottom of the content divs (if the user selects the "newest first" in the settings).
html:
<div class="container">
<div id="div1" class="content">aaa<br>aaa</div>
<div id="div2" class="content">bbb<br><br>bbb</div>
<div id="div3" class="content">ccc</div>
<div id="div4" class="content">ddd</div>
</div>
css:
.container {
position: absolute;
top: 10px;
left: 10px;
right: 10px;
bottom: 10px;
border: 1px solid red;
}
.content {
position: relative;
top: 0px;
left: 5px;
width: 200px;
height: auto;
border: 1px solid blue;
margin: 3px;
}
http://jsfiddle.net/jk559/1/
so I'd like the end-user visible order to be: div4, div3, div2, div1.
How can I achieve this? (css/js)
preferrably no jquery.
thanks in advice!
Pure css solution:
Use flexbox to achieve this.
.container {
display:flex;
flex-direction:column-reverse;
justify-content: flex-end;
align-content: flex-end;
}
Updated fiddle here.
Read more information here.
try this
theParent = document.getElementById("theParent");
theKid = document.createElement("div");
theKid.setAttribute("id","div5");
theKid.setAttribute("class","content");
theKid.innerHTML = 'eee';
// append theKid to the end of theParent
theParent.appendChild(theKid);
// prepend theKid to the beginning of theParent
theParent.insertBefore(theKid, theParent.firstChild);
Demo Fiddle http://jsfiddle.net/jk559/4/
You can easily do it with JQuery with the following function.
$('.container > div').each(function() {
$(this).prependTo(this.parentNode);
});
UPDATED FIDDLE
As you mentioned in the question, I will try to attain the expected output with the pure javascript.
You can insert content in the beginning simply using .prepend() .
$(".container").prepend("<div id='div5' class='content'>eee</div>");
Demo
JS FIDDLE UPDATED DEMO
Use prepend() to add as first child of an element
/* $( ".container" ).prepend( "Your div with id here" ); */
/* Example */
$( ".container" ).prepend( "<div id='div5' class='content' >div5 on top </div>" );
Take a look at this answer about reordering dom items.
Basically, you have to maintain a state that decides the ordering. When you insert items (see insertItem below) you append or prepend based on the state. When the user selects the newest first option (see newFirst below), you first reverse the dom elements and then flip the state so that subsequent insert happen at the right place.
var newFirst = false;
var list = document.getElementById('my-list');
function newFirst() {
var items = list.childNodes;
var itemsArr = [];
for (var i in items) {
if (items[i].nodeType == 1) { // get rid of the whitespace text nodes
itemsArr.push(items[i]);
}
}
itemsArr.reverse();
for (i = 0; i < itemsArr.length; ++i) {
list.appendChild(itemsArr[i]);
}
newFirst = !newFirst;
}
function insertItem(content) {
var item = document.createElement("div");
item.setAttribute("class","content");
item.innerHTML = content;
if(newFirst) {
list.insertBefore(item, list.firstChild);
} else {
list.appendChild(item);
}
}
try this :
$("div[id*=div]").sort(function(a,b){
if(a.id > b.id) {
return -1;
} else {
return 1;
}
}).each(function() {
var elem = $(this);
$(".container").append(elem);
});
this will sort your divs inside container like this : div4, div3, div2, div1
if you want change the order to : div1, div2, div3, div4 just change if(a.id > b.id) to if(a.id < b.id)
you can add a link called change order then call this code when you click on it

How to set a div height according to another div height using javascript?

I have 2 divs. Since div 1 could be longer, i.e. infinite scroll div, I want to make div 2 the same height with div 1 using javascript. I tried to use the code below, but it does not work. Why?
javascript:
<script type="text/javascript">
document.getElementById("div2").setAttribute("height",document.getElementById("div1").clientHeight);
</script>
my divs:
#div1 {
width: 700px;
background: #FFF;
overflow: hidden;
float: left;
}
#div2 {
width: 300px;
background-image: url(../images/user_panel.png);
background-repeat:repeat-y;
}
What about this:
var div1 = document.getElementById("div1");
var div2 = document.getElementById("div2");
div2.style.height = div1.style.height; // Might have to add +"px" here.
Just from the top of my head.
This should do the trick:
document.getElementById("div2").style.height=document.getElementById("div1").clientHeight+'px';
the setAttribute function is a DOM function to add a new attribute to an HTML element. You are trying to add the height on a div. That would have the effect:
<div id="div2" height="...">...</div>
But HTML does not define such an height HTML element attribute.
What you are looking for is to set the style of the DOM element. That would be the style DOM element property. And inside the style you have the height property that you must set:
document.getElementById("div2").style.height = document.getElementById("div1").clientHeight + "px";
In the above code sample you might also think about div1's padding (probably bringing it into the computation). This is because clientHeight includes the padding but style.height does not.

How to get div's content height

My div has a styling position:absolute, and as a result, it doesn't expand if the content is higher than it's height.
Therefore, I thought that a solution would be if I find what the is the actual content's height, and assign the height to the div with the position:absolute styling.
Any idea how to do it? or maybe an idea how to make an absolute div to expand according to its content.
Thanks in advance!
Element.scrollHeight should do the job.
Here's an awful way to get the height of the container. We're basically cloning the whole div, setting the position so that it has height, checking that height, and then removing it:
$(function () {
var clone = null;
alert( clone = $('.test').clone().css('position', 'static').appendTo(".container").height());
clone.remove();
});
Here's the fiddle: http://jsfiddle.net/vPMDh/1/
It should expand even if being absolute.
check you don't have a height: xxpx
if so, change it to min-height
As you've said "it doesn't expand if the content is higher than it's height." I guess you have a fixed height set on it.. if you do need this for some reason try using min-height instead.
Have a look at this fiddle.
<div class="classname">
Some content....
<p style="clear:both">&nbsp</p>
</div>
use a clearfix hack. heres the link
and add clearfix to you div
example
in your style sheet
<style>
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
.clearfix {
display: inline-block;
}
html[xmlns] .clearfix {
display: block;
}
* html .clearfix {
height: 1%;
}
</style>
...
and in your div add clearfix the class
<div class="clearfix">
//some html tags
</div>
Thanks for contributing your question. If you use this:
$(document).ready(function(){
var x = $("#container").height();
alert(x);
//if not works then
var y = $("#container").outerHeight();
alert(y);
});
I think it is easy as clean code to find the height of any div if you do not apply the div's height too.
similar solution to #MattDiamant, but with vanilla JS and without creating a clone:
function getDivHeight(posAbsoluteDiv) {
const heightBackup = posAbsoluteDiv.style.height;
posAbsoluteDiv.style.height = 'auto';
const contentHeight = posAbsoluteDiv.getBoundingClientRect().height;
posAbsoluteDiv.style.height = heightBackup;
return contentHeight;
}

How to extend container when it has absolutely positioned elements in it?

Lets say I have
CSS:
.mainWrap { position: relative; overflow: hidden; }
.wrap-boxes { positon: relative; }
.box { position:absolute (position and height is generated by plugin isotope: http://isotope.metafizzy.co/custom-layout-modes/centered-masonry.html }
HTML:
<div class"mainWrap">
<div class="wrap-boxes">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
clearfix applied to wrap-boxes won't work as it has elements with absolute position in it.
therefore i'd need to use jQuery to calculate the height of the boxes in order to extend wrap-box. I don't know the height of these boxes as they have random height and I do not know the total number of boxes as they are constantly generated by the client. I'd need a general jQuery that solves that. If i don't extend the mainWrap the boxes will be cut off and i need to use overflow: hidden for other reasons.
Any help on this?
Something like this maybe?
$.fn.wrapHeight = function() {
return this.each(function() {
var height = 0;
$(this).children().each(function() {
height += $(this).height();
}).end().height(height);
});
};
$('.wrap-boxes').wrapHeight();
Absolutely-positioned elements are no longer part of the layout. You need to use JavaScript to measure the size and position of the child elements and set the size of the parent element accordingly.
In pure JavaScript you could use the following:
var wrapbox = document.getElementById('mainWrap').childNodes[1],
els = wrapbox.childNodes,
i,
height = 0;
for (i in els) {
if(els[i].nodeType == 1) {
height += parseInt(els[i].offsetHeight);
}
wrapbox.style.height = height + 'px';
}
http://jsfiddle.net/AJLe7/1/
Notice I changed the class="mainWrap" to id="mainWrap" to simplify the answer...

Positioning a "reel" div properly in jQuery when total width is dynamic

I'm writing my own small pager control in Javascript and jQuery and having trouble positioning it properly.
The pager is set to only be a specific width (340px in this case) which allows it to display roughly ten page buttons. If the user has selected a higher page, I'd like the reel to slide to the left and show the selected page in the center. Since the number of pages is set dynamically (I build the pager in js when the page is loaded) and their width is not constant (double-digit page number buttons are wider than single-digit buttons) how can I determine and then set the pager to the correct position?
I was attempting to use the following code:
(where my buttons are labeled "#Nav1", "#Nav2", etc...)
if (currentPage < 7) {
newPos = 0;
}
else {
newPos = $('#Nav' + (currentPage-5)).position().left;
}
$('#reel').animate({left: newPos*-1}, 700);
But the #reel div is wrapping so position().left doesn't return the position I need.
Suggestions?
Here is my HTML/CSS markup:
<style type="text/css">
div#pager div
{
display: inline-block;
}
#navContainer
{
width: 340px;
height: 28px;
overflow: hidden;
position: relative;
}
#reel
{
position: absolute;
top: 0;
left: 0;
}
</style>
<div id="pager" class="buttons">
<div id="preButtons"></div>
<div id="navContainer">
<div id="reel">
</div>
</div>
<div id="postButtons"></div>
</div>
You'll need to manually give #reel a width equivalent to the number of items * the width of each item.
A dynamic way to do this is to load in all of the items, place them in a hidden, unbounded div, then set the width of #reel equal to the width of that div.
Try this before your carousel code:
var dummyDiv = $('<div id="dummy" class="buttons" style="position:absolute;display:none"></div>');
dummyDiv.appendTo('body');
dummyDiv.html($('#reel').html());
var reelWidth = dummyDiv.css('width');
$('#reel').css({'width':reelWidth});
This will allow you to dynamically set the width of the #reel div so it doesn't wrap without knowing the exact size of the contents statically.

Categories

Resources