how to get height of an element using .offsetHeight? - javascript

I created a div element
let divContainer = document.createElement("div");
divContainer.style.height = "70%";
divContainer.id = "container";
Then, I am doing something like this...
labels.forEach(label => {
let labelDiv = document.createElement("div");
labelDiv.className = "label";
labelDiv.style.height = divContainer.offsetHeight / labels.length; // here I want to retrieve the length of the divContainer in pixels.
divContainer.appendChild(labelDiv);
});
label is an array.
When I run this code labelDiv.style.height comes out to be 0px.
I was looking for a reason for this behaviour and I found this question Element offsetHeight always "0".
As suggested in one of the answers, I used the following code
requestAnimationFrame(() => {
/* should be able to get offsetHeight here */
console.log(divContainer.offsetHeight);
};
and indeed I got the correct height for the label element inside the requestAnimationFrame but labelDiv.style.height is still 0 in the code given below.
I believe labelDiv.style.height is still being calculated before the code in requestAnimationFrame runs.
let divContainer = document.createElement("div");
divContainer.style.height = "70%";
divContainer.id = "container";
requestAnimationFrame(() => {
/* should be able to get offsetHeight here */
console.log(divContainer.offsetHeight);
});
labels.forEach(label => {
let labelDiv = document.createElement("div");
labelDiv.className = "label";
labelDiv.style.height = divContainer.offsetHeight / labels.length;
divContainer.appendChild(labelDiv);
});
Then. I changed the above code to this but still, I am not getting the correct output. In this case I am not again getting 0px for divContainer.offsetHeight
let divContainer = document.createElement("div");
divContainer.style.height = "70%";
divContainer.id = "container";
requestAnimationFrame(() => {
/* should be able to get offsetHeight here */
console.log(divContainer.offsetHeight);
labels.forEach(label => {
let labelDiv = document.createElement("div");
labelDiv.className = "label";
labelDiv.style.height = divContainer.offsetHeight / labels.length;
divContainer.appendChild(labelDiv);
});
});
What is wrong with the above code? What's the proper way to get the height of that element?

Three things:
you need to give body a height, since by default that's 0 (70% of 0 is 0)
you need to append the container to the body before iterating (70% of no parent is 0)
you need to add a unit to the label heights (right now it's just a number)
let labels = ["A", "B", "C"];
document.body.style.height = "500px";
let divContainer = document.createElement("div");
divContainer.style.height = "70%";
divContainer.style.backgroundColor = "red";
divContainer.id = "container";
document.body.append(divContainer)
labels.forEach(label => {
console.log(divContainer.offsetHeight)
let labelDiv = document.createElement("div");
labelDiv.className = "label";
labelDiv.style.height = divContainer.offsetHeight / labels.length + "px";
labelDiv.style.background = "blue";
divContainer.appendChild(labelDiv);
});

To follow up on my comment.
document.getElementById("app").innerHTML = `
<h1>Label Boxes!</h1>
`;
let labels = ["label1", "label2", "label3", "label4", "label5"];
let divContainer = document.createElement("div");
divContainer.style.height = "70%";
divContainer.style.border = "2px solid palevioletred";
divContainer.id = "container";
document.body.appendChild(divContainer);
requestAnimationFrame(() => {
/* should be able to get offsetHeight here */
console.log(divContainer.getBoundingClientRect().height);
labels.forEach(label => {
let labelDiv = document.createElement("div");
labelDiv.className = "label";
labelDiv.style.height = divContainer.getBoundingClientRect().height / labels.length + "px";
labelDiv.style.border = "1px solid palegreen";
divContainer.appendChild(labelDiv);
});
});
html, body {
height: 100%;
}
<div id="app"></div>

Related

Can't seem to find a way to clear my divs back to default (Etch a Sketch project)

I don't know if I'm doing the project "wrong" but so far this has been working. I'm basically just creating a JavaScript version of Etch a Sketch, where you hover your mouse over a div and it changes color. I need to create a button that resets the main div back to default, effectively "clearing" the page but nothing I try seems to work. Any suggestions?
const mainDev = document.createElement("div");
mainDev.style.width = "200px";
mainDev.style.height = "200px";
mainDev.style.display = "grid";
mainDev.id = "divId";
mainDev.style.gridTemplateColumns = "repeat(16, 1fr)";
let addMain = document.getElementById("main");
addMain.appendChild(mainDev);
for (let i = 0; i < 240; i++) {
const sixteenDivs = document.createElement("div");
sixteenDivs.classList.add("sixteen");
sixteenDivs.style.backgroundColor = "white";
sixteenDivs.style.width = "45px";
sixteenDivs.style.height = "45px";
sixteenDivs.style.border = "1px solid #000"
sixteenDivs.style.display = "grid";
sixteenDivs.style.margin = "5px 5px";
let mouseOver = function() { sixteenDivs.style.backgroundColor = "rgb(20, 20, 20)" };
sixteenDivs.onmouseover = mouseOver;
mainDev.appendChild(sixteenDivs);
}
function clearDiv() {
/// this is where I'm struggling
}
<div class="button">
<button class="clearBtn" onclick="clearDiv()">CLEAR</button>
</div>
<div id="main"></div>
const mainDev = document.createElement("div");
mainDev.style.width = "200px";
mainDev.style.height = "200px";
mainDev.style.display = "grid";
mainDev.id = "divId";
mainDev.style.gridTemplateColumns = "repeat(16, 1fr)";
let addMain = document.getElementById("main");
addMain.appendChild(mainDev);
for (let i = 0; i < 240; i++) {
const sixteenDivs = document.createElement("div");
sixteenDivs.classList.add("sixteen");
sixteenDivs.style.backgroundColor = "white";
sixteenDivs.style.width = "45px";
sixteenDivs.style.height = "45px";
sixteenDivs.style.border = "1px solid #000"
sixteenDivs.style.display = "grid";
sixteenDivs.style.margin = "5px 5px";
let mouseOver = function() {
sixteenDivs.style.backgroundColor = "rgb(20, 20, 20)"
};
sixteenDivs.onmouseover = mouseOver;
mainDev.appendChild(sixteenDivs);
}
function clearDiv() {
mainDev.childNodes.forEach((child) =>
child.style.backgroundColor = "white"
)
}
<div class="button">
<button class="clearBtn" onclick="clearDiv()">CLEAR</button>
</div>
<div id="main">
</div>

Divs created in Javascript don't appear

I'm making an rgb guesser game for school, and the stretch goal I'm trying to reach is "making divs in javascript". For some reason, my divs aren't appearing when I'm making them. Here's the javascript code snippers
dothething()
function dothething(){
divs = MakeDivs(4);
var randomcolor = Math.floor(Math.random()*4);
WinningDiv = divs[randomcolor];
}
function MakeDivs(X){
for(i = 0;i<=X;i++){
var div = (document.createElement("div"));
div.style.borderRadius = "50%";
div.height = "100px";
div.width = "125px";
}
console.log(divs)
var container = document.getElementById("container")
container.appendChild(div);
return divs
}
and here's some filler html
<body>
<div> FillerDiv</div>
</body>
You need to include the append inside the loop and use a correct control to append your DIV. Also in case you want to return your DIVs elements, add them to array and return them as in below code:
function MakeDivs(X){
var divs = [];
for(i = 0;i<=X;i++){
var div = (document.createElement("div"));
div.style.borderRadius = "50%";
div.height = "100px";
div.width = "125px";
document.body.appendChild(div);
divs.push(div);
}
console.log(divs)
return divs
}
You have to embed container.appendChild(div); inside the loop. In your original code, you have just appended the last div.
function MakeDivs(X){
var container = document.getElementById("container");
var divs = [];
for(i = 0;i<=X;i++){
var div = (document.createElement("div"));
div.style.borderRadius = "50%";
div.height = "100px";
div.width = "125px";
divs.push(div);
container.appendChild(div);
}
console.log(divs);
return divs;
}
You forgot to append the div to the container.
var div = (document.createElement("div"));
div.style.borderRadius = "50%";
div.height = "100px";
div.width = "125px";
container.appendChild(div);
Missing array of divs.
Incorrect way to apply width and height.
div.height = "100px";
^
div.width = "125px";
^
dothething()
function dothething() {
divs = MakeDivs(4)
var randomcolor = Math.floor(Math.random() * 4)
WinningDiv = divs[randomcolor]
}
function MakeDivs(X) {
var container = document.getElementById("container");
var divs = [];
for (i = 0; i <= X; i++) {
var div = (document.createElement("div"));
div.style.borderRadius = "50%";
div.style.height = "100px";
div.style.width = "125px";
container.appendChild(div);
divs.push(div);
}
//console.log(divs)
return divs
}
#container div {
background-color: lightgreen;
}
<div>
FillerDiv
<div id='container'></div>
</div>
This is helpful for you. Without defining HTML tag ID you are getting Id container. The variable should be defined before use anywhere.
You missed divs array to define. You should add every div in the loop.
dothething()
function dothething(){
var divs = MakeDivs(4)
var randomcolor = Math.floor(Math.random()*4)
WinningDiv = divs[randomcolor]
}
function MakeDivs(X){
var container = document.getElementById("container");
var divs = [];
for(i = 0;i<=X;i++){
var div = document.createElement("div");
div.style.borderRadius = "50%";
div.height = "100px";
div.width = "125px";
div.innerHTML = 'Test'+i;
divs.push(div);
container.appendChild(div);
}
console.log(divs);
return divs
}
<body>
<div id="container"> FillerDiv</div>
</body>
You can use documentFragment for creating a block which contains all the colored divs. I've refactored a little bit your code. You can check the solution on jsfiddle - https://jsfiddle.net/2zcg59sd/ or you can run the snippet here.
dothething()
function dothething(){
var divs = MakeDivs(4) ;
document.getElementById("randomColors").appendChild(divs);
}
function MakeDivs(X){
var docFragment = document.createDocumentFragment();
for(i = 0;i<=X;i++){
var randomcolor = Math.floor(Math.random()*900000) + 100000;
var newDiv = document.createElement("div");
newDiv.style.borderRadius = "50%";
newDiv.style.height = "100px";
newDiv.style.float = "left";
newDiv.style.width = "125px";
newDiv.style.backgroundColor = "#" + randomcolor;
docFragment.appendChild(newDiv);
}
return docFragment
}
<div> FillerDiv</div>
<div id="randomColors"></div>

Some div(s) not displaying when using createElement and appendChild

I am trying to create 4 div(s) that are supposed to have a width of 5px and sit at the top, bottom, left and right margins of the viewport, essentially acting all together as a frame or border to the page.
Here is my code:
function border () {
edgeT = document.createElement('div');
edgeT.style.position = "fixed"
edgeT.style.left = 0;
edgeT.style.top = 0;
edgeT.style.right = 0;
edgeT.style.width = "5px";
edgeT.style.backgroundColor= "black";
document.body.appendChild(edgeT);
edgeB = document.createElement('div');
edgeB.style.position = "fixed"
edgeB.style.left = 0;
edgeB.style.right = 0;
edgeB.style.bottom = 0;
edgeB.style.width = "5px";
edgeB.style.backgroundColor= "black";
document.body.appendChild(edgeB);
edgeL = document.createElement('div');
edgeL.style.position = "fixed"
edgeL.style.left = 0;
edgeL.style.top = 0;
edgeL.style.bottom = 0;
edgeL.style.width = "5px";
edgeL.style.backgroundColor= "black";
document.body.appendChild(edgeL);
edgeR = document.createElement('div');
edgeR.style.position = "fixed"
edgeR.style.top = 0;
edgeR.style.bottom = 0;
edgeR.style.right = 0;
edgeR.style.width = "5px";
edgeR.style.backgroundColor= "black";
document.body.appendChild(edgeR);
}
For some reason, when calling the function, the left and right divs (i.e. edgeL and edgeR) are displayed properly, but there is no trace of edgeT and edgeB (top and bottom ones). I cannot understand why since the code is exactly the same for all four of them. FYI the problem is relevant in both Chrome and Firefox.
I know I could use CSS to achieve the same result, but since this is mostly a learning exercise I would still like to understand what is causing the issue in this case.
Thank you all in advance for your help.
Regards,
You should define for the top and bottom divs width: 100% and height: 5px (they're aligned horizontally) and for the left and right divs width: 5px and height: 100% (aligned vertically).
var edgeT = document.createElement('div');
edgeT.style.position = "fixed"
edgeT.style.top = 0;
edgeT.style.left = 0;
edgeT.style.width = "100%";
edgeT.style.height = "5px";
edgeT.style.backgroundColor= "black";
document.body.appendChild(edgeT);
var edgeB = document.createElement('div');
edgeB.style.position = "fixed"
edgeB.style.bottom = 0;
edgeB.style.left = 0;
edgeB.style.width = "100%";
edgeB.style.height = "5px";
edgeB.style.backgroundColor= "black";
document.body.appendChild(edgeB);
var edgeL = document.createElement('div');
edgeL.style.position = "fixed"
edgeL.style.left = 0;
edgeL.style.top = 0;
edgeL.style.width = "5px";
edgeL.style.height = "100%";
edgeL.style.backgroundColor= "black";
document.body.appendChild(edgeL);
var edgeR = document.createElement('div');
edgeR.style.position = "fixed"
edgeR.style.right = 0;
edgeR.style.top = 0;
edgeR.style.width = "5px";
edgeR.style.height = "100%";
edgeR.style.backgroundColor= "black";
document.body.appendChild(edgeR);
If you want to see the top and the bottom then you need to give them a height, not a width.

Turning off opacity on centered div

I am writing a box that appears in the center of a website. To do that I dynamically (js) create two elements - overlay that covers whole page and has 0.5 opacity to show some website, and a box that should have no opacity.
The problem is that both the overlay and the box are a bit transparent.
this.createOverlay = function () {
handler = document.createElement('div');
handler.style.display = 'hidden';
handler.style.width = '100%';
handler.style.height = '100%';
handler.style.top = 0;
handler.style.left = 0;
handler.style.position = 'absolute';
handler.style.background = 'black';
handler.style.color = "#aaaaaa";
handler.style.opacity = "0.5";
handler.style.filter = "alpha(opacity = 5)";
return this;
};
this.createCenteredBox = function (width, height, url) {
var data = JSON.parse(data);
handler = document.createElement('a');
handler.href = data.product_feed_deep_link;
handler.target = "_blank";
handler.style.display = "block";
handler.style.width = width + "px";
handler.style.height = height + "px";
handler.style.position = "absolute";
handler.style.color = "black";
handler.style.backgroundColor = "#ffffff";
handler.style.opacity = "1";
handler.style.top = "50%";
handler.style.left = "50%";
handler.style.marginTop = "-" + height / 2 + "px";
handler.style.marginLeft = "-" + width / 2 + "px";
handler.style.padding = "0 10px 10px 10px";
handler.style.borderRadius = "4px";
var div = document.createElement('div');
handler.appendChild(div);
return this;
};
This is the code, I can't turn off box'es opacity no matter if I set opacity to 1 on it, or opacity filter, or whatever.
How can I solve this?
Opacity isn't inherited (see here), however, all elements that reside inside (descendants) of that elements that the opacity property is applied to will be effected.
The best way to get around this is to use rgba.
handler.style.background = "rgba(0, 0, 0, .5)"; // RGB 0,0,0 is #000 (black).
//handler.style.opacity = "0.5";
//handler.style.filter = "alpha(opacity = 5)";
See 2nd and 3rd answer here as well

Remove div's with almost the same id once a certain top value is reached

So I've got this code to create a rectangular div every 800ms which falls down the screen.
Now I'd like to be able to remove a div once it reaches a certain top value, otherwise it'll
get too cluttered with div's. Now I have no idea how to exactly do that, considering the id's I've given them. I'd also like to know how I could end up removing every single one of those div's once it's game over. This is what I have so far all together: http://student.howest.be/pieter-jan.vandenb1/crossdodger/Game.html. I'm pretty new at javascript so thanks in advance!
var idNumber = 0;
SpawnBlock();
function SpawnBlock()
{
UpdateBlock();
setTimeout(SpawnBlock, 800);
}
function UpdateBlock()
{
var block = document.createElement("div");
block.style.width = "25px";
block.style.height = "25px";
block.style.background = "lightgrey"
block.style.top = "-25px";
block.style.left = Math.random() * 455 + "px";
block.style.position = "absolute";
block.id = "block" + ++idNumber;
//block.speed = 0.5;
sym.$("Stage").append(block);
sym.$("#block"+idNumber).transition({top:"800px"},8000,"linear");
}
It's made in Adobe Edge, hence the "sym." namespace.
This worked for me in a similar environment:
var bl = document.getElementById("block" + (idNumber));
bl.parentNode.removeChild(bl);
var idNumber = 0;
SpawnBlock();
var divblocks = [];
function SpawnBlock()
{
UpdateBlock();
setTimeout(SpawnBlock, 800);
}
function UpdateBlock()
{
var block = document.createElement("div");
block.style.width = "25px";
block.style.height = "25px";
block.style.background = "lightgrey"
block.style.top = "-25px";
block.style.left = Math.random() * 455 + "px";
block.style.position = "absolute";
block.id = "block" + ++idNumber;
//block.speed = 0.5;
sym.$("Stage").append(block);
sym.$("#block"+idNumber).transition({top:"800px"},8000,"linear");
divblocks.push(block.id);
if (divblocks.length > 800)
{
$(divblocks[0]).Remove();
}
}

Categories