Covering the entire div's with HTMl divs - javascript

Supoose the screen size is 1920by1080, then I want div of user input suppose say 200by200
then these div's of this dimensions should create the entire screen. How can i do that using HMTL, CSS and javascript.
CSS CODE
div {
height: 200px;
width: 200px;
background-color: red;
padding-bottom: 20px;
box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3);
border-style: solid;
display: inline-block;
}
HTML CODE
<input type="number" placeholder="enter height of div" id="div_height" />
<input type="number" placeholder="enter width of div" id="div_width" />
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
JAVASCRIPT
function myFunction() {
let height_div = document.getElementById('div_height').value;
let width_div = document.getElementById('div_width').value;
var xy = '',
i,
size = 20;
var x = screen.availHeight;
var y = screen.availWidth;
while (x > height_div) {
while (y > width_div) {
xy = xy + '<div>' + '</div>';
y = y - width_div;
}
x = x - height_div;
}
document.getElementById('demo').innerHTML = xy;
console.log(height_div + ' ' + width_div);
document.getElementsByTagName('div').style.height = height_div + 'px';
document.getElementsByTagName('div').style.width = width_div + 'px';
OUTPUT

Try using this code:
div
{
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
Then it would cover entire screen.

function myFunction(e) {
e.preventDefault()
let height_div = document.getElementById("div_height").value;
let width_div = document.getElementById("div_width").value;
var xy = "";
const xi = Math.floor(window.innerWidth / width_div);
const yi = Math.floor(window.innerHeight / height_div);
for (let i = 0; i < yi; i++) {
xy += "<div class='row'>";
for (let j = 0; j < xi; j++) {
xy += "<div></div>"
}
xy += '</div>'
}
console.log(xy)
document.getElementById("demo").innerHTML = xy;
console.log(height_div + " " + width_div);
Array.from(document.getElementsByTagName("div")).map(el => (el.style.height = height_div + "px"));
Array.from(document.getElementsByTagName("div")).map(el => (el.style.width = width_div + "px"));
}
document.querySelector("form").addEventListener('submit', myFunction);
div {
box-sizing: border-box;
height: 200px;
width: 200px;
background-color: red;
box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3);
border-style: solid;
flex-grow: 0;
flex-shrink: 0;
}
.row {
display: flex;
}
p#demo {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
margin: 0;
z-index: 1;
}
.form {
background: blue;
position: relative;
z-index: 2;
}
<form class="form">
<input type="number" placeholder="enter height of div" id="div_height" />
<input type="number" placeholder="enter width of div" id="div_width" />
<button>Try it</button>
</form>
<p id="demo"></p>
Try something like this,
you can use Math.ceiling if you want to fill the white gaps and have a little hangover

Related

Optimized solution for filling entire page with DIVs

I want to have a webpage whose entire viewable area is filled with divs. I am currently using the following code:
var wh= window.innerHeight;
var ww= window.innerWidth;
var area= wh * ww;
i= 1;
while(area > 0) {
document.getElementById("map").innerHTML+= "<div class='map-box' id='box" + i + "'></div>";
area-= 20 * 20;
i+=1;
}
.map-box {width: 20px; height: 20px; border-color: grey; border-width: 1px; border-style: solid; display: inline-block; margin: 0; padding: 0;}
<body>
<div id='map'></div>
</body>
If you try to use this code is your browser, you will see that there are two flaws in this:
First, it creates too many extra divs which go outside the viewable screen.
Second, this code is also somewhat slow.
Can someone here help me address both of these flaws and also optimize this code for faster performance?
1.) That <div> is not 20x20, because of the border:
let d = document.getElementById("test");
console.log(d.offsetWidth, d.offsetHeight);
.map-box {
width: 20px;
height: 20px;
border-color: grey;
border-width: 1px;
border-style: solid;
display: inline-block;
margin: 0;
padding: 0;
}
<div id="test" class="map-box"></div>
2.) There's still the default border around the entire thing, and also some spacing between the lines:
var wh = window.innerHeight;
var ww = window.innerWidth;
var area = wh * ww;
i = 1;
while (area > 0) {
document.getElementById("map").innerHTML += "<div class='map-box' id='box" + i + "'></div>";
area -= 22 * 22; // hardcoding is not that nice
i += 1;
}
.map-box {
width: 20px;
height: 20px;
border-color: grey;
border-width: 1px;
border-style: solid;
display: inline-block;
margin: 0;
padding: 0;
}
#map {
background: blue;
}
body {
background: red;
}
<div id='map'></div>
3.) Half cells are evil, so the width/height should be rounded downwards to a multiple of 22. Suddenly the grid is becoming an actual rectangle, at least in Chrome/Edge. The between-spacing is still a problem:
var wh = Math.floor(window.innerHeight / 22) * 22; // <--!!
var ww = Math.floor(window.innerWidth / 22) * 22; // <--!!
var area = wh * ww;
i = 1;
while (area > 0) {
document.getElementById("map").innerHTML += "<div class='map-box' id='box" + i + "'></div>";
area -= 22 * 22;
i += 1;
}
.map-box {
width: 20px;
height: 20px;
border-color: grey;
border-width: 1px;
border-style: solid;
display: inline-block;
margin: 0;
padding: 0;
}
#map {
background: blue;
}
body {
background: red;
margin: 0; // <--!!
padding: 0; // <--!!
}
<div id='map'></div>
I don't actually know how to use line-height properly, this one works on my machine with my scaling/DPI, in Chrome/Edge, but that's all I can say about it. The 22-s are cut back, area now simply stores the number of <div>s to generate.
var wh = Math.floor(window.innerHeight / 22);
var ww = Math.floor(window.innerWidth / 22);
var area = wh * ww;
i = 1;
while (area > 0) {
document.getElementById("map").innerHTML += "<div class='map-box' id='box" + i + "'></div>";
area--;
i += 1;
}
.map-box {
width: 20px;
height: 20px;
border-color: grey;
border-width: 1px;
border-style: solid;
display: inline-block;
margin: 0;
padding: 0;
}
#map {
line-height: 0.6;
}
body {
margin: 0;
padding: 0;
}
<div id='map'></div>
Instead of accessing dom element's inner html on each loop iteration - do it once after the loop with "prepared" data to set there
const wh = window.innerHeight;
const ww = window.innerWidth;
let area = wh * ww;
i = 1;
const ms = Date.now();
const divs = [];
while (area > 0) {
divs.push("<div class='map-box' id='box" + i + "'></div>");
area -= 20 * 20;
i += 1;
}
document.getElementById("map").innerHTML = divs.join("");
console.log("done fast", Date.now() - ms);
js fiddle with comparison https://jsfiddle.net/aL7zqwy9/
The final solution, not ideal but
<html>
<body>
<div id='map'></div>
</body>
<style>
body {
margin: 0;
padding: 0;
/* Overflow appears when last row is added and shrinks the "width" */
overflow-y: hidden;
}
#map {
/* To exclude space between rows */
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.map-box {
width: 20px;
height: 20px;
border: 1px solid grey;
display: block;
margin: 0;
padding: 0;
/* So border thickness will not affect element size */
box-sizing: border-box;
}
</style>
<script>
const cellSize = 20; // px
const wh = window.innerHeight;
const ww = window.innerWidth;
// not always divisible by cell size without a remainder
const columnsCount = Math.floor(ww / cellSize);
const rowsCount = Math.floor(wh / cellSize);
const cellsCount = columnsCount * rowsCount;
console.log(`wh: ${wh}, ww: ${ww}, cols: ${columnsCount}, rows: ${rowsCount}`);
const divs = [];
for (let i = 0; i < cellsCount; i++) {
divs.push(`<div class='map-box' id='box${i}'></div>`);
}
document.getElementById("map").innerHTML = divs.join("");
</script>
</html>

My HTML, CSS and JS progress bar doesn't work

I'm trying to do a progress bar so that the users can know when will their file be downloaded. I don't know what I did wrong, but the progress bar style doesn't update in the for loop.
var filesize = 1000 //this is not the final value
var progressbar = document.getElementById("progress");
function myFunction(){
for(var i = 0; i <= filesize; i++){
x = i/ filesize * 100;
x = parseInt(x.toString().slice(0, 3));
console.log(x + "%")
progressbar.style.width = x + "%";
}
}
#bar{
width: 35%;
background-color: rgba(0,0,0,0.17);
border-radius: 130px;
margin: auto;
}
#progress{
width: 0%;
height: 30px;
background-color: rgb(255, 0, 0);
border-radius: 130px;
}
<button onclick="myFunction()">Click me</button>
<div id="bar">
<div id="progress"></div>
</div>
You can make the progress bar move smoothly by adding the transition property in CSS.
A higher transition time will result in the progress bar moving slower.
var filesize = 1000 //this is not the final value
var progressbar = document.getElementById("progress");
function myFunction() {
for (var i = 0; i <= filesize; i++) {
x = i/ filesize * 100;
x = parseInt(x.toString().slice(0, 3));
console.log(x + "%")
progressbar.style.width = x + "%";
}
}
#bar {
width: 35%;
background-color: rgba(0,0,0,0.17);
border-radius: 130px;
margin: auto;
}
#progress {
width: 0%;
height: 30px;
background-color: rgb(255, 0, 0);
border-radius: 130px;
transition: 0.2s;
}
<button onclick="myFunction()">Click me</button>
<div id="bar">
<div id="progress">
</div>
</div>

customize the look of dynamically created DIVs

The script creates a random number of divs (in range 20-40) and puts some text in every single div. The script calculates the width of divs so that they fit in a single row. The height should be equal to the width - every div must be a square. Here's the code:
var quantity = Math.floor(Math.random() * (40 - 20 + 1)) + 20;
for (var i = 0; i < quantity; i++) {
var elem = document.createElement("div");
elem.className = "part";
elem.id = 'p' + i;
document.getElementById("scale").appendChild(elem);
}
var parts = document.getElementsByClassName("part");
for (var i = 0; i < parts.length; i++) {
parts[i].style.fontSize = (500 / quantity) + 'px';
parts[i].style.lineHeight = (460 / quantity) + 'px';
parts[i].textContent = ("block #" + (i + 1));
}
for (var i = 0; i < parts.length; i++) {
parts[i].style.height = parts[i].style.width;
}
let text = document.getElementById('txt');
text.textContent = 'BLOCKS: ' + quantity;
body {
margin: 0;
}
#scale {
position: absolute;
display: table;
width: 100%;
top: 50%;
transform: translateY(-100%);
table-layout: fixed;
border-spacing: 1px;
}
.part {
display: table-cell;
background-color: #a9cce3;
padding: 3px;
box-sizing: border-box;
border: 1px solid black;
border-radius: 2px;
overflow: hidden;
}
#txt {
position: absolute;
top: 50%;
left: 50%;
margin-top: 20px;
transform: translateX(-50%);
font-size: 18px;
font-family: 'Arial', sans-serif;
}
<div id="scale"> </div>
<div id='txt'> </div>
The first problem is the divs are not always square. The second problem is I can't properly set the font size depending on a div size, so text fits a div. I think that's the worst solution
parts[i].style.fontSize = (500 / quantity) + 'px';
parts[i].style.lineHeight = (460 / quantity) + 'px';
There were two problems with the code:
To get element with use .clientWidth because style.width can be accessed when you have set that but in your code, I couldn't see you are doing so.
Second use font size in per cent, I don't think line-height is required. To make it centre use CSS as in example follows.
Use following:
var quantity = Math.floor(Math.random() * (40 - 20 + 1)) + 20;
for (var i = 0; i < quantity; i++) {
var elem = document.createElement("div");
elem.className = "part";
elem.id = 'p' + i;
document.getElementById("scale").appendChild(elem);
}
var parts = document.getElementsByClassName("part");
for (var i = 0; i < parts.length; i++) {
parts[i].style.fontSize = (500 / quantity) + '%';
parts[i].style.lineHeight = (460 / quantity) + '%';
parts[i].textContent = ("block #" + (i + 1));
}
for (var i = 0; i < parts.length; i++) {
parts[i].style.height = parts[i].clientWidth + "px";
}
let text = document.getElementById('txt');
text.textContent = 'BLOCKS: ' + quantity;
body {
margin: 0;
}
#scale {
position: absolute;
display: table;
width: 100%;
top: 50%;
transform: translateY(-100%);
table-layout: fixed;
border-spacing: 1px;
}
.part {
display: table-cell;
background-color: #a9cce3;
padding: 3px;
box-sizing: border-box;
border: 1px solid black;
border-radius: 2px;
overflow: hidden;
vertical-align: middle;
text-align: center;
}
#txt {
position: absolute;
top: 50%;
left: 50%;
margin-top: 20px;
transform: translateX(-50%);
font-size: 18px;
font-family: 'Arial', sans-serif;
}
<div id="scale"> </div>
<div id='txt'> </div>
Or if you don't want to use your text font to be reduced like this use following:
.part {
display: table-cell;
background-color: #a9cce3;
padding: 3px;
box-sizing: border-box;
border: 1px solid black;
border-radius: 2px;
overflow: hidden;
vertical-align: middle;
text-align: center;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}

splitting div into multiple divs in javascript

Hi I am trying to make the columns and rows in the mainContent div but the problem is the it is getting out of the mainContent after 2-3 clicks. I want it to remain inside and should create equally sized columns and rows inside of it. here is my code.
var test2 = document.getElementById('btn');
test2.addEventListener('click', function() {
console.log('clicked');
var contain = document.getElementById('contentArea'); // for selecting id
var newGriding = document.createElement('div');
newGriding.setAttribute('id', 'grid');
contain.appendChild(newGriding);
});
#contentArea {
background-color: #babab3;
height: 74vh;
margin: 0 auto;
}
#grid {
margin: 0;
padding: 0;
border: none;
outline: 5px dashed #aba4a4;
display: inline-block;
height: 100%;
width: 50%;
}
<div id="contentArea">
</div>
<button id="btn">
create
</button>
Because you are using fixed height for the appending element.
You should resize the element after every click using some logic or you can use the display of your parent as flex and flex wrap true.
var test2 = document.getElementById('btn');
test2.addEventListener('click', function() {
var contain = document.getElementById('contentArea'); // for selecting id
var newGriding = document.createElement('div');
newGriding.setAttribute('id', 'grid');
contain.appendChild(newGriding);
});
#contentArea {
background-color: #babab3;
height: 74vh;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
}
#grid {
margin: 0;
padding: 0;
border: none;
outline: 5px dashed #aba4a4;
display: inline-block;
width: 50%;
}
<div id="contentArea">
</div>
<button id="btn">create</button>
or
var test2 = document.getElementById('btn');
test2.addEventListener('click', function() {
var contain = document.getElementById('contentArea'); // for selecting id
var newGriding = document.createElement('div');
newGriding.setAttribute('id', 'grid');
contain.appendChild(newGriding);
resizeDiv();
});
var maxInRow = 2;
function resizeDiv() {
var allGrids = document.querySelectorAll("#contentArea > #grid");
var width = 100 / maxInRow;
var len = allGrids.length;
var colNo = Math.floor(len / maxInRow);
colNo = colNo - (len / maxInRow) == 0 ? colNo : colNo + 1;
var height = 100 / colNo;
for (var i = 0; i < len; i++) {
allGrids[i].style.width = width + "%";
//"calc(" + width + "% - 10px)"; --- if doesn't want box-sizing to be borderbox
allGrids[i].style.height = height + "%";
//"calc(" + height + "% - 10px)"; --- if doesn't want box-sizing to be borderbox
//reduce the size of box which increased due to outline
}
}
#contentArea {
background-color: #babab3;
height: 74vh;
margin: 0 auto;
position: relative;
}
#grid {
margin: 0;
padding: 0;
border: 5px dashed #aba4a4;
display: inline-block;
height: 100%;
width: 50%;
position: relative;
box-sizing: border-box;
}
<div id="contentArea">
</div>
<button id="btn">
create
</button>

Html5 resizing object by dragging

I need to resize notes in my little application, but I don't know how. They have to be resized by dragging their bottom right corner and it must be done in pure java script.
Div with "+" adds new note and empty div is something like counter of all notes.
Code:
document.addEventListener("onload", Load());
var index = 0;
var cnt = 0;
var x = 0;
var y = 0;
var xx = 0;
var yy = 0;
var clicked = false;
var dragged = false;
var counter = 0;
var numberOfPapers = 0;
var state = 0;
function Load(){
var adder = document.querySelector("#add");
adder.setAttribute("onclick", "addClick()");
}
function addClick(){
cnt++;
numberOfPapers++;
document.querySelector("#counter").innerHTML = "Przebieg = " + cnt + "<br>" + "Liczba kartek = " + numberOfPapers;
var paper = document.createElement("div");
var paperX = document.createElement("div");
var paperR = document.createElement("div");
var paperS = document.createElement("div");
//papierek xD
paper.setAttribute("class", "paper");
paper.setAttribute("onmousedown", "movePaper(this,event)");
paper.setAttribute("onmouseup", "stop(this)");
paper.setAttribute("onmouseleave", "stop(this)");
paper.setAttribute("id", "id_" + cnt);
paper.style.top = "100px";
paper.style.left = "100px";
paper.style.zIndex = cnt;
//niszczyciel papierków
paperX.setAttribute("class", "deleter");
paperX.setAttribute("onclick", "deletePaper(this)");
//zmieniacz rozmiarów
paperR.setAttribute("class", "resizer");
paperR.ondragstart = function(e){
e.preventDefault();
};
paperR.setAttribute("onmousedown", "resize(this,event)");
//edytor tekstu tini emce
paperS.setAttribute("class", "txtEditor");
paperS.setAttribute("onclick", "editTxt()");
paper.appendChild(paperX);
paper.appendChild(paperR);
paper.appendChild(paperS);
document.body.appendChild(paper);
}
function stop(e){
e.setAttribute("onmousemove", null);
state = 1;
}
function resize(e,event){
state = 2;
}
function deletePaper(e){
e.parentElement.id = "del";
var del = document.querySelector("#del");
del.parentNode.removeChild(del);
numberOfPapers--;
document.querySelector("#counter").innerHTML = "Przebieg = " + cnt + "<br>" + "Liczba kartek = " + numberOfPapers;
}
function movePaper(e, event){
index++;
e.style.zIndex = index;
x = event.clientX;
y = event.clientY;
xx = e.style.left;
yy = e.style.top;
xx = xx.slice(0,xx.search("px"));
yy = yy.slice(0,yy.search("px"));
x = x - xx;
y = y - yy;
e.setAttribute("onmousemove","moreMove(this,event)");
}
function moreMove(e,event){
e.style.top = event.clientY - y + "px";
e.style.left = event.clientX - x + "px";
}
body{
margin: 0;
padding: 0;
}
#add{
position: absolute;
width: 45px;
height: 35px;
top: 25px;
right: 25px;
background-color: #F5574E;
text-align:center;
padding-top:10px;
border: solid black 1px;
}
#counter{
position: absolute;
width: 200px;
height: 45px;
top: 25px;
right: 80px;
background-color: #F5574E;
text-align:center;
border: solid black 1px;
}
.paper{
position: absolute;
width: 100px;
height: 100px;
top: 25px;
left: 25px;
background-color: #E3D67F;
border: solid black 1px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.deleter{
position: absolute;
width: 10px;
height: 10px;
top: 0px;
right: 0px;
background-color: red;
}
.resizer{
position: absolute;
width: 10px;
height: 10px;
bottom: 0px;
right: 0px;
background-color: green;
}
.txtEditor{
position: absolute;
width: 10px;
height: 10px;
top: 10px;
right: 0px;
background-color: yellow;
}
<body>
<div id="add">+
</div>
<div id="counter">
</div>
</body>
You can simply take replicate your move functions and instead of targeting top and left you target width and height of the parent node. Like this:
function resize(e, event) {
event.stopPropagation();//this to prevent move behavior to be triggered when clicking resize handle
state = 2;
index++;
e.style.zIndex = index;
x = event.clientX;
y = event.clientY;
xx = e.parentNode.style.width;
yy = e.parentNode.style.height;
xx = xx.slice(0, xx.search("px"));
yy = yy.slice(0, yy.search("px"));
x = x - xx;
y = y - yy;
e.setAttribute("onmousemove", "resizeMove(this,event)");
}
function resizeMove(e, event) {
console.log('resixe')
e.parentNode.style.height = event.clientY - y + "px";
e.parentNode.style.width = event.clientX - x + "px";
}
You'll have to declare width and height of your parentNode for it to work, you can add it to your paper section.
paper.style.width = "100px";
paper.style.height = "100px";

Categories