How to flow text from DIV to DIV? - javascript

I have two DIVs with absolute position on two sides of a HTML page such as (EXAMPLE)
<div class="left">
</div>
<div class="right">
</div>
with CSS
.left{
position:absolute;
left:10px;
top:10px;
width:100px;
height:100px;
background:red;
}
.right{
position:absolute;
right:10px;
top:10px;
width:100px;
height:100px;
background:blue;
}
Is there a way to add text to the left DIV and flow excess text to the right one? I am not stuck to this two DIV, and I'm just looking for a solution to flow excess text to another position.
NOTE: I hope to find a pure CSS solution, though, it seems to be improbable; then, I am looking for a pure javascript solution (not using JS libraries).

CSS Regions (still a 'draft', but) is aiming to fix this problem:
The CSS regions module allows content to flow across multiple areas
called regions. The regions are not necessarily contiguous in the
document order. The CSS regions module provides an advanced content
flow mechanism, which can be combined with positioning schemes as
defined by other CSS modules such as the Multi-Column Module [CSS3COL]
or the Grid Layout Module [CSS3-GRID-LAYOUT] to position the regions
where content flows.
More info and tutorials at https://www.adobe.com/devnet/archive/html5/articles/css3-regions.html

Here is one for fixed-width approach. The gap between two columns will equal to width of main div.
Fiddle
<div class="container">
<div class="sides">The big text here.<div>
<div class="main"></div>
</div>
For variable width you need JS or jQuery.
Update:
I have used jQuery for this purpose as I have found pure JS difficult to find solution of this.
function setGap() {
var width = $(".main").width();
$(".sides").css({
"-moz-column-gap": width + "px",
"-webkit-column-gap": width + "px",
"column-gap": width + "px"
});
}
$(window).resize(setGap);
setGap();
Fiddle
Update 1:
function setGap() {
var width = document.getElementsByClassName("main")[0].offsetWidth;
var elem = document.getElementsByClassName("sides")[0];
var style = elem.getAttribute("style");
if (typeof style != "null") {
style =
"-moz-column-gap:" + width + "px; -webkit-column-gap:" + width + "px; column-gap:" + width + "px";
elem.setAttribute("style", style);
}
else {
style +=
"-moz-column-gap:" + width + "px; -webkit-column-gap:" + width + "px; column-gap:" + width + "px";
elem.setAttribute("style", style);
}
}
window.onresize = setGap;
setGap();
Fiddle

so far (2012) It's not possible using CSS, CSS3 (with 2 separate elements)
but using JS You can clone the content and use scrollTop on the right element :
LIVE DEMO
var d = document,
$left = d.getElementById('left'),
$right = d.getElementById('right'),
leftH = $left.offsetHeight;
$right.innerHTML = $left.innerHTML +'<p style="height:'+ leftH +'px;" />';
$right.scrollTop = leftH;
As you can see I'm appending also an empty paragraph, to fix the right element need to scrollTop some amount of px
Note: add overflow:hidden; to your ID elements #left and #right

Related

How to dynamically get the length of a div using JQuery and JavaScript?

I am developing a web application using AngularJS. I find myself in a situation where I have a bar (with the css I created a line) that must dynamically lengthen and shorten.
I know that JQuery scripts are sufficient to do this. For example, if my css is like this:
.my_line{
display:block;
width:2px;
background: #FFAD0D;
height: 200px; /*This is the part that needs to dynamically change*/
}
I could in the controller resize the line (of my_line class) simply with:
$(".my_line").css("height", someExpression*100 + 'px');
The thing is, I would like to dynamically resize the line based on the size of another div element (Or, in general, any HTML element of my choice).
I don't know how to get (at run-time) the size of a certain page element in terms of height.
Only in this way I would be able to create a line that dynamically lengthens or shortens as the size of a div (or some other element) changes!
How do you do this? So I will avoid writing hard-coded the measures but I want make sure that they vary as the dimensions of other elements on the page vary
I hope this is helping:
$(".my_line").css("height", $("#referenceElement").height()*5 + 'px');
.my_line{
display:inline-block;
width:2px;
background: #FFAD0D;
}
#referenceElement {
display:inline-block;
background: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="my_line"></div>
<div id="referenceElement">Hi, I'm 5 time smaller than the orange line!</div>
Here I am using the setInterval to track the div's height (you can do width as well) and storing it in a previousHeight variable and comparing it every interval
Then according to the comparison, it will determine if the height of the div has changed. If it has then it will change the height of the other div according to the height of the first div
You can create multiple variables and track multiple elements in the same setInterval
$(document).ready(function(){
var previousHeight = parseInt($("#my-div").css("height"));
setInterval(function(){ checkHeight(); }, 100);
function checkHeight() {
// Check height of elements here
var currentHeight = parseInt($("#my-div").css("height"));
if(currentHeight != previousHeight) {
previousHeight = currentHeight;
$("#dynamic-div").css("height", parseInt(currentHeight) + "px");
}
}
$("#button").click(function() {
$("#my-div").css("height", parseInt(previousHeight) + 5 + "px");
})
})
#my-div{
background: #000000;
height: 20px;
width: 20px;
}
#dynamic-div{
background: teal;
height: 20px;
width: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="my-div">
</div>
<button id="button">Increase div height</button>
<div id="dynamic-div">
</div>

Having an image fill a container after transform(90deg)

I would like to have an image rotate and fill the container after it's been loaded. The issue I'm having is the height is automatically set when loaded and then not resetting after rotation. Here is a JSFiddle of the issue:
$('.load').on("click", function () {
var image = $('.image');
image.attr("src", "https://s-media-cache-ak0.pinimg.com/736x/f5/a0/62/f5a0626a80fe6026c0ac65cdc2d8ede2.jpg");
image.addClass('rotate-image');
});
.image {
max-width: 100%;
max-height: 100%;
}
.rotate-image {
transform: rotate(90deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="img-container" style="background:black; height:100px; width: 200px; text-align:center">
<img class="image" src="" />
</div>
<br />
<button class="load">Load</button>
This requires the max-width and max-height styles to be removed, though.
To fit the image, it has to be made larger so that it width (height, when rotated) becomes as big as the container's height. However, it's rotated only visually and the browser doesn't care about that because transform doesn't change the flow of the website. For it, there is an "unrotated" picture whose height is now bigger than its container. Visually rotating the image doesn't change anything. For that purpose, the image needs to be pulled up with a number of pixels equal to how much its bigger than the parent. Those pixels are divided by two because the image overflows at the bottom only.
Play with the fiddle to see what I mean.
$('.load').on("click", function() {
var image = $('.image');
image.attr("src", "https://s-media-cache-ak0.pinimg.com/736x/f5/a0/62/f5a0626a80fe6026c0ac65cdc2d8ede2.jpg");
image.addClass('rotate-image');
var parentHeight = image.parent().height();
image.css("width", parentHeight + "px");
image.css("position", "relative");
image.css("bottom", ((image.height() - parentHeight) / 2) + "px");
});
.rotate-image {
transform: rotate(90deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="img-container" style="background:black; height:100px; width: 200px; text-align:center">
<img class="image" src="" />
</div>
<br />
<button class="load">Load</button>
Edit: Beware, if you load the image from an external source by setting its src and immediately rotate it, image.height() might return 0 and the image might be displaced. Then, if you click again, its height is now correct and it gets placed right.
I'm not absolutely sure, but I think that's because when you load the image, the browser needs to download it first, meaning that you don't yet know what its dimensions are.
To see that in action, paste some image URLs from Google in the fiddle I provided.
You need to do this by javascript or jquery. Your goal is:
.Rotated_Img ...
width = 100 % of parent height
height = 100 % of parent width
And i do not think css has any think for this, until the parent width and height have related to view port vw and vh.
jquery:
$('.Rotated_Img').each(function(){
$(this).css('width', $(this).parent().height() + 'px');
$(this).css('height', $(this).parent().width() + 'px');
});

Avoid Height Overflow by resizing objects

I am expriementing phonegap in order to develop some multi platform apps for phones with HTML5 and Java Script.
I want an object I'm having in my web page (its a table or div) to shirink to exact size of displays as each phone may have different display, hence I used java script and html like below to get the size of screen (the available size of course) and set it as the height and width of my div, or whatever object I want.
it works till width but when it goes to height I still have a scroll bar. I have no idea where this comes from but I tried many ways to limit the height by even giving a exact size to a parent div.
<style>
.dummy {
width:100px;
height:100px;
background-color:#900;
}
</style>
<script>
var width = window.screen.availWidth + "px";
var height = window.screen.availHeight + "px";
function load() {
document.getElementById("dummy").style.height = height;
document.getElementById("dummy").style.width = width;
}
</script>
<style>
body {
margin:0px;
}
.cont {
height:100px;}
</style>
</head>
<body onload="load()">
<div class="cont">
<div class="dummy" id="dummy" onclick="load();"></div>
</div>
</body>
</html>
what's wrong with this code? why my red div is bigger than the screen height?
thanks.
Ok, this is not wrong in your code. You should known exactly about window.screen.availWidth: is full height device + status bar(not correct with several document, but it is truth). You screen available exactly is use:
var width = window.innerWidth + "px";
var height = window.innerHeight + "px";

Created div elements' random margins not working

Problem and source code
I'm trying to create <div>s within another <div> at the click of a button. When the button is clicked, a new inner <div> is created (within the outer <div>) with a unique id. I have this part working but here's where I'm running into an issue: I want each inner <div> to have a random margin-top.
Javascript
function pressButton() {
number += 1;
makeDiv(number);
};
function makeDiv(x) {
var innerDiv = document.createElement("innerDiv" + x);
outer.appendChild(innerDiv);
innerDiv.setAttribute("style", "margin-top:" + Math.floor(Math.random()*51) + ";display:inline-block;width:48px;height:48px;background-color:#000;");
};
CSS:
#outer {
position:absolute;
white-space:nowrap;
height:118px;
overflow:auto;
width:100%;
padding:2px;
}
Result (after button is clicked 4 times)
<div id="outer">
<innerDiv1 style="margin-top:15;display:inline-block;width:48px;height:48px;background-color:#000;"></innerDiv1>
<innerDiv2 style="margin-top:23;display:inline-block;width:48px;height:48px;background-color:#000;"></innerDiv2>
<innerDiv3 style="margin-top:37;display:inline-block;width:48px;height:48px;background-color:#000;"></innerDiv3>
<innerDiv4 style="margin-top:0;display:inline-block;width:48px;height:48px;background-color:#000;"></innerDiv4>
</div>
The result (which I got from inspecting the inner elements in my browser) looks like everything worked - all the margin-tops are random like I wanted. However, the visual result is this:
As you can see, the black inner <div>s all have the same margin-top. What am I doing wrong? How can I make the created <div>s all have random margin-tops?
The CSS spec requires that a length (other than zero) that is missing a unit be treated as an error (and thus ignored). Therefore, add px to the end of your generated margin number, and all should be well.
Live Demo
Description
This happens, because you set the display:inline-block; property. This makes them all to be in one line, so they will allign to the innerDivx that has the highest margin-top.
Delete the display:inline-block; property and give them float:left;. If you want to keep the gap between them, also add margin-left:5px;. And don't forget that margin-top's value needs a unit. I think you wanted to use px.
Also <innerDivx> is not a valid HTML tag. You should change them to a <div> and use innerDivx as an id attribute. Also your tags use almost the same CSS styles so you should put the same ones to a class and add the class instead.
Full solution code
HTML
<button id="button1">Add box</button>
<div id="outer"></div>
JavaScript
var number = 0;
document.getElementById("button1").addEventListener("click", pressButton, false);
function pressButton() {
++number;
makeDiv(number);
};
function makeDiv(x) {
var innerDiv = document.createElement("div");
outer.appendChild(innerDiv);
innerDiv.className += " box";
innerDiv.setAttribute("id", "innerDiv" + x);
innerDiv.setAttribute("style", "margin-top:" + Math.floor(Math.random()*51) + "px;");
};
CSS
#outer {
position: absolute;
white-space: nowrap;
height: 118px;
overflow: auto;
width: 100%;
padding: 2px;
}
.box {
float: left;
width: 48px;
height: 48px;
background-color: #000;
margin-left: 5px;
}
This is likely caused by the position model used for inline-block elements - they're all being vertically-aligned at their bottom line in a row.
I suggest that you simplify this and use position: block with float: left
http://jsfiddle.net/2y5bJ/4/
I also suggest that you stick to standard elements to ensure cross-browser compatibility - don't create your own elements called innerDiv1 etc, but use div elements with unique IDs.
function makeDiv(x) {
var innerDiv = document.createElement("div");
outer.appendChild(div);
innerDiv.setAttribute('id', 'innerDiv' + x);
innerDiv.setAttribute("style", "margin-top:" + Math.floor(Math.random()*51) + "px;");
};
I think there is no tag available with name
<innerDiv1>
This may be the cause.

Can't calculate element's size

I'm trying to calculate width and height of elements, to set precise position in CSS with jQuery, but for some reason calculation for some IDs doesn't work (alert shows 0 or nothing) while working for other IDs and classes. Here's the jQuery code:
$(document).ready(function () {
$("#img1").each(function () {
var maxtop = $('.pattern').outerHeight() - $('#mimg1').outerHeight() - 20,
maxleft = $('.pattern').outerWidth() - $('#mimg1').outerWidth() - 20,
randomtop = getRandomInt(20, maxtop),
randomleft = getRandomInt(20, maxleft),
randomzindex = getRandomInt(1, 30);
$(this).css({
"top": randomtop,
"left": randomleft,
"z-index": randomzindex
});
});
$("#img13").each(function () {
var maxtop = $('.pattern').outerHeight() - $('#mimg13').outerHeight() - 20,
maxleft = $('.pattern').outerWidth() - $('#mimg13').outerWidth() - 20,
randomtop = getRandomInt(20, maxtop),
randomleft = getRandomInt(20, maxleft),
randomzindex = getRandomInt(1, 30);
alert ($('#mimg13').outerHeight());
$(this).css({
"top": randomtop,
"left": randomleft,
"z-index": randomzindex
});
});
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
});
CSS:
html {width:100vw; height:100vh;}
body {margin:0; width:100vw; height:100vh; overflow:hidden;}
.pattern {width:100%; height:100%; margin:0; padding:0;}
.drag {overflow: visible; padding-bottom: 0px; cursor: move; position: absolute;}
.mood-img {position:absolute; display:none; margin:0; padding:0;}
HTML:
<body class="pattern-2">
<div class="pattern"></div>
<div id="img1" class="drag mood-img">
<img class="shadow moodimg1" src="mood/brick-mood-1.png">
<span class="mood-name shadow">
<nobr>A. Brickwork I</nobr>
</span>
</div>
<div id="img13" class="drag mood-img">
<img id="moodimg13" class="shadow moodimg" src="mood/brick-graphic-4.png">
<span class="mood-name shadow">
<nobr>6. Untitled</nobr><br>
<small>digital</small>
</span>
</div>
</body>
I have tried lot of different options but none of them worked and the problem is always (as it seems) is that JS doesn't calculate elements' sizes, so positions are also calculated wrong.
And also may be there's some more simple way to make all these calculation, cause I have 13 elements with different IDs (from img1 to img13 and from mimg1 to mimg13. May be I could use JS to get IDs by itself, with no need for me to write all IDs into JS?
IDEA
I have a page with a few div elements, one of them is visible, others are set to display:none. When particular span element is clicked, JS sets certain hidden div visible, changing its CSS to display:block. The div I have this problem with at first was an invisible container for several other divs with images and text elements and I wanted to position these contained elements against the container div (which had width and height set to 0 and margin top and left set to 50%) with margin-top and margin-left. Then I set the container to have 100% width and height and tried to position container's content with top and left. Then I removed the container and set its former inner elements to have position:absolute and tried to still position it with top and left properties calculated and set with jQuery. Actually those elements are images with some pop-up text, which should be randomly placed all over the page (overflow:hidden), and have z-index set randomly as well. I've spent three days trying to find the solution, but got no result — either it's not working at all (elements are placed all on top of one another in the same position (top left corner) either calculations are done wrong and some (or all) divs are positioned out of the page which creates scroll or hiding images when overflow is hidden. Hope I'm explaining it fine, so anyone could be able to understand what have I wanted to do.
You're calculating dimensions on page load - $(document).ready(... but unfortunately it doesn't mean the images are ready at this point. It's a common issue.
Since you already have your images wrapped with .each function, simply replace it with the load event handler
$("#img1").on('load', function () {
...
});
http://jsbin.com/iLIWOfa/2/edit
If the CSS of a parent element of a image is display: none, the image is not loaded and there is no width or height.
Just set opacity: 0 instead.

Categories