How to stack div elements using JavaScript - javascript

I am trying to create a checker board using pure JavaScript, not jQuery.
I have created the first row, but cannot seem to "stack" the rows to create a full board. If there is a better way to go about this than the road I'm going down, please enlighten me.
<!DOCTYPE html>
<html>
<head>
<title>Checkerboard</title>
<style>
.box {
height: 50px;
width: 50px;
border: 1px solid black;
display: inline-block;
}
</style>
</head>
<body>
<div class="box"></div>
</body>
<script type="text/javascript">
var row = function (node, count) {
for (var i = 1; i < count; i++) {
if (i % 2 === 0) {
copy = node.cloneNode(true);
node.parentNode.insertBefore(copy, node).style.backgroundColor = "white";
} else {
copy = node.cloneNode(true);
node.parentNode.insertBefore(copy, node).style.backgroundColor = "red";
}
}
}
row(document.querySelector('.box'), 8);
</script>
</html>

Your code works fine, you just need to actually run the function you've created:
row(document.getElementsByClassName("box")[0], 50);
JSFiddle: http://jsfiddle.net/63dcjsk4/
Edit
If you're talking about the gap that appears between rows, fix this by using float and removing the inline-block display:
.box {
border: 1px solid black;
height: 50px;
float: left;
width: 50px;
}
JSFiddle: http://jsfiddle.net/63dcjsk4/1/

Related

Is there a way I can get the table to not resize in height when I innerHtml something in the "td"?

I am sorry for the norwegian variable names in the js file, but if u try to click a cell, you will see that the height of it will resize, I am wondering if anyone have an easy and quick change!
<!doctype html>
<html lang="no">
<head>
<title> Standardoppsett </title>
<meta charset="utf-8">
</head>
<style>
.board {
table-layout: fixed;
width: 360px;
height: 360px;
border: 32px solid;
border-color: darkslategray;
border-radius: 5px;
}
.firkant {
border: 1px black solid;
}
.hvit{
background:white;
}
.svart{
background:grey;
}
td:hover {
background: lightgreen;
cursor: pointer
}
</style>
<body>
<div>
<table class="board"></table>
</div>
<script>
let tableEl = document.querySelector("table")
for(let i = 1; i < 9; i++) {
let trEl = document.createElement('tr');
for(let j = 1; j < 9; j++) {
let tdEl = document.createElement('td');
tdEl.setAttribute("id","rute"+i+j)
tdEl.addEventListener("click",plasserDronning)
trEl.appendChild(tdEl);
// Bare på grunn av css
tdEl.className = (i%2 === j%2) ? "hvit firkant" : "svart firkant";
}
tableEl.appendChild(trEl);
}
turTeller = 0
function plasserDronning(e){
let firkantTrykket = e.target
console.log(firkantTrykket.id)
if (turTeller == 0) {
if(firkantTrykket = e.target){
firkantTrykket.innerHTML = "a";
}
turTeller = 1
}
else if(turTeller == 1) {
if(firkantTrykket = e.target){
firkantTrykket.innerHTML = "b";
}
turTeller = 2
}
}
</script>
</body>
</html>
So far I have tried basically everything I am aware of, I have tried to set the table layout to fixed, I have tried to set the "td's" posistion to top and a lot more, if anyone knows what I can do, it would mean a lot!
In above code I suggest to add height properties in you td tag's class that will solve your issue.
if you want to more responsive and you can write media queries.or using other framework like bootstap.
.hvit{
background:white;
height:20px;
}
.svart{
background:grey;
height:20px;
}
You can add height:calc(100% / 8); to the firkant (td) class to prevent the cell from growing.
This way the cell will scale with the table if you decide to increase the table size or make it dynamic.

eventListener is not running after the page is updated

I have written this code to get the squares of a grid to change their background color to black upon a mouseover event. It works when the page initially loads, but if I create a new grid the mouseover event no longer works.
I updated the original post with a snippet. Sorry I didn't do that from the beginning.
let number = 16;
makeGrid(number);
function makeGrid(number) {
for (let i=0; i < number; i++) {
for (let j=0; j < number; j++) {
const rows = document.createElement('div');
const container = document.getElementById('container')
rows.setAttribute('class', 'rows');
container.appendChild(rows);
}
}
container.style.gridTemplateColumns = `repeat(${number}, 1fr)`;
container.style.gridTemplateRows = `repeat(${number}, 1fr)`;
}
//create new grid with on button
let newGrid = document.getElementById('newGrid');
newGrid.addEventListener('click', () => {
let number = prompt('Enter a number');
let container = document.getElementById('container');
container.textContent = '';
makeGrid(number);
})
//change background color to black
let changeClass = document.querySelectorAll('.rows');
changeClass.forEach((item) => {
item.addEventListener('mouseover', e => {
item.style.backgroundColor = 'black';
})
})
body {
background-color: rgb(5, 51, 5) ;
}
#container {
margin: auto;
width: 500px;
height: 500px;
display: grid;
border-style: solid;
border-width: thin;
border-color: lightslategray;
background-color: white;
}
.rows{
}
.black { background-color: black;
}
#header {
text-align: center;
}
#button {
text-align: center;
}
#footer {
text-align: center;
}
#newGrid {
background-color: lightgray;
color: darkcyan;
font-size: 20px;
padding: 12px 28px;
border-radius: 0px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Etch-a-Sketch</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1 id='header'>Etch-a-Sketch</h1>
<br>
<div id='button'>
<button id='newGrid' class='button'>New Grid</button>
</div>
<br>
<br>
<div id='container'></div>
<br>
<footer id='footer'>Made by: Joe Maniaci</footer>
<script src="main.js"></script>
</body>
</html>
When you query the DOM with document.querySelectorAll('.rows') and add the event listeners, there is only one "grid" in the DOM at that time. When a "grid" is subsequently added to the DOM, as triggered by the user's click event, you must instantiate event listeners on the newly added DOM nodes too.
A way to avoid this problem and a better approach overall in your situation is to use delegated event listeners. For example:
document.addEventListener('mouseover', e=>{
if(e.target.matches(‘.myClickableItemClass’){
e.target.style.backgroundColor = 'black';
}
}
Learn more about event delegation here: https://medium.com/#bretdoucette/part-4-what-is-event-delegation-in-javascript-f5c8c0de2983

Trouble dynamically creating elements with JS

I'm working on a bootcamp and some guys and I have created a group. We are trying to dynamically create html elements using pure JavaScript. The elements are there but we get an error running and we want to be able to go back and use/grab those elements later. Any advice on what we are doing wrong would be much appreciated.
The HTML:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript Grid</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="grid"></div>
<script src="js/script.js" type="text/javascript"></script>
</body>
</html>
The js:
(function() {
var grid = document.getElementById("grid");
for (var i = 0; i < 5; i++) {
var temp = document.createElement("DIV");
temp.className = "row";
grid.appendChild(temp);
}
var row = grid.getElementsByClassName("row");
})();
The CSS:
.grid {
height: 100%;
width: 100%;
overflow: auto;
background-color: black;
}
.row {
overflow: auto;
}
.box {
padding: 0;
box-sizing: border-box;
background-color: white;
height: 100px;
float: left;
}
Thanks!
I see no error on your code.
your divs are collected and you can play with them around. take a look to the jsfiddle and open your console. (press F12 or inspect element on right mouse click).
(function() {
var grid = document.getElementById("grid");
for (var i = 0; i < 5; i++) {
var temp = document.createElement("DIV");
temp.className = "row";
grid.appendChild(temp);
}
var row = grid.getElementsByClassName("row");
row[row.length - 1].style.borderColor = "blue";
row[0].style.borderColor = "red";
})();
and the css
.row {
background.color:#f2f2f2;
border: 1px solid #dadada;
margin-bottom:10px;
height:20px;
}
http://jsfiddle.net/hu7a7k0s/

$(".grid").mouseenter doesn't run after I create new divs

My $(".grid").mouseenter doesn't run after I press my new button, which deletes old divs (.grid) and creates new ones. So, what can I change to make it work after that. Also, why are there empty spaces above all .grid divs?
$(document).ready(function(){
createGrid();
$(".grid").mouseenter(function(){
$(this).addClass("hovered")
});
$("#new").click(function(){
clear();
createGrid(prompt("How big would you like your new grid to be (x<64)?"));
});
$("#clear").click(function(){
clear();
});
});
function clear(){
$(".grid").removeClass("hovered");
};
function gridSize(measuring, howBig){
if (howBig==null){
howBig = 16;
}
switch(measuring){
case "height":
return parseInt($("#surface").height()/howBig);
case "width":
return parseInt($("#surface").width()/howBig);
}
};
function createGrid(howBig){
$("#surface").empty();
if(howBig == null || howBig == ""){
for(var i=0; i < 16; i++){
$("#surface").prepend("<div class = 'grid' style = 'width: " +gridSize('width')+"px ; height:"+gridSize('height')+ "px;'></div>");
for(var j=0; j < 15; j++){
$("#surface").prepend("<div class = 'grid' style = 'width: " +gridSize('width')+"px ; height:"+gridSize('height')+ "px;'></div>");
}
}
}
else {
for(var i=0; i < howBig; i++){
$("#surface").prepend("<div class = 'grid' style = 'width: " +gridSize('width', howBig)+"px ; height:"+gridSize('height', howBig)+ "px;'></div>");
for(var j=0; j < howBig-1; j++){
$("#surface").prepend("<div class = 'grid' style = 'width: " +gridSize('width', howBig)+"px ; height:"+gridSize('height', howBig)+ "px;'></div>");
}
}
}
};
* { margin:0; padding:0; }
.wrapper {
width: 800px;
margin: 0px auto;
}
#reset {
width: 60px;
margin : 15px auto;
}
#surface {
margin: 0px auto;
width: 800px;
height: 800px;
}
.grid {
background-color: #D3D3D3;
margin: 0px;
display: inline-block;
}
.hovered {
background-color: black;
}
<!DOCTYPE html>
<html>
<head>
<link rel = "stylesheet" href = "css/styles.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src = "js/script.js"></script>
</head>
<body>
<div class = "wrapper">
<button id ="new">New</button>
<button id ="clear">Clear</button>
<div id = "surface"></div>
</div>
</body>
</html>
Replace:
$(".grid").mouseenter(function(){
$(this).addClass("hovered")
});
with
$("#surface").on('mouseenter','.grid',function(){
$(this).addClass("hovered")
});
This is required because your original code was attaching event handlers to the .grid elements, which you delete and create new elements (which don't have the handlers attached). You could just re-run your original code to attach new handlers when you create new elements, but using event delegation is a much better approach as you only attaching an event handler on one element (#surface) rather than on each individual .grid element, and of course, since you aren't removing and recreating the #surface element, you don't need to detach/re-attach it when you create a new grid.
You can read more about jQuery's on method and event delegation here: http://api.jquery.com/on/
As for the spacing issue, it is because you are using inline-block elements, and inline-elements will preserve atleast one space if present between elements. You can either remove all spaces (and line breaks) between the elements, or you can place font-size:0; on the #surface element to shrink the space size to nothing.
maxSize=16;
$(document).ready(function(){
createGrid(16);
$("#surface").on('mouseenter','div',function(){
$(this).addClass("hovered")
});
$("#new").click(function(){
createGrid(prompt("How big would you like your new grid to be (x<" + maxSize + ")?"));
});
$("#clear").click(function(){
$("#surface>div").removeClass("hovered");
});
});
function gridSize(measuring, howBig){
switch(measuring){
case "height":
return parseInt($("#surface").height()/howBig);
case "width":
return parseInt($("#surface").width()/howBig);
}
};
function createGrid(howBig){
howBig=parseInt(howBig);
if(howBig == NaN || howBig<1 || howBig>maxSize){
howBig=16;
}
$("#surface").empty();
for(var i=0; i < howBig*howBig; i++){
$("#surface").append("<div style='width:" +gridSize('width', howBig)+"px; height:"+gridSize('height', howBig)+ "px;'></div>");
}
};
* { margin:0; padding:0; }
.wrapper {
width: 800px;
margin: 0 auto;
}
#reset {
width: 60px;
margin : 15px auto;
}
#surface {
margin: 0 auto;
width: 800px;
height: 800px;
font-size: 0;
}
#surface>div {
background-color: #D3D3D3;
margin: 0;
display: inline-block;
}
#surface>div.hovered {
background-color: black;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/styles.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="js/script.js"></script>
</head>
<body>
<div class="wrapper">
<button id="new">New</button>
<button id="clear">Clear</button>
<div id="surface"></div>
</div>
</body>
</html>
I've also taken the liberty to clean up some of the javascript for you.
You will need to use event delegation to work with dynamically created elements
$("#surface").on('mouseenter','.grid',function(){
$(this).addClass("hovered");
});
---> https://learn.jquery.com/events/event-delegation/
it does not work because the divs created after you attach the action to it so you must to use one of this statements :
Example 1:
$("body").on('mouseenter','.grid',function(){
$(this).addClass("hovered");
})
http://api.jquery.com/on/
Example 2:
$("body").live('mouseenter','.grid',function(){
$(this).addClass("hovered");
})
http://api.jquery.com/live/
Example 3:
$("body").delegate('mouseenter','.grid',function(){
$(this).addClass("hovered");
})
http://api.jquery.com/delegate/

Unresponsive elements after button click

Background:
I started Javascript the other day and built this sketch pad:
http://frankpeelen.github.io/sketch-pad/
following alongside the instructions on:
http://www.theodinproject.com/web-development-101/javascript-and-jquery
Problem:
It's basically finished, and works fine except for when creating a new grid with the "New" button. All of a sudden the 'squares' stop responding to 'hover' events. I've searched, but have been unable to find any similar problems. Any ideas?
Code:
$(document).ready(function() {
var build = function(h, w) {
var height = h;
var width = w;
//Loop through height to create rows
for (i = 1; i <= height; i++) {
$("#sketchpadcontainer").append("<div class='row'></div>");
//Loop through width to create divs in each row
for (j = 1; j <= width; j++) {
$(".row:last-child").append("<div class='sqrcontainer'><div class='square'></div></div>");
}
}
};
//Build default 16x16 grid
build(16, 16);
$("button").click(function() {
var size = parseInt(prompt("How many squares per side would you like? Please enter a number."));
//In case the number entered > 50
if (size > 50) {
$(".row").remove();
build(50, 50);
alert("The number you entered was too large. The number 50 has been used instead.")
}
//In case a non-number is entered
else if (isNaN(size)) {
$(".row").remove();
build(16, 16);
alert("You didn't enter a number. The default of 16 has been used.")
}
//In case a number <= 50 is entered
else {
$(".row").remove();
build(size, size);
}
})
$(".square").hover(
//Mouse in
function () {
$(this).css("background-color", "blue");
},
//Mouse out
function () {} );
});
html, body, #sitecontainer {
height: 100%;
width: 100%;
margin: 0px;
}
#sketchpadcontainer {
}
button {
display: block;
margin: 0 auto;
margin-top: 2em;
margin-bottom: 1em;
}
#sketchpadcontainer {
}
.row {
text-align: center;
}
.sqrcontainer {
height: 1.5em;
width: 1.5em;
display: inline-block;
}
.square {
width: 1em;
height: 1em;
margin: .1em;
border-color: black;
border-style: solid;
border-radius: .1em;
}
<!DOCTYPE html>
<head>
<title>Sketch Pad</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type='text/javascript' src="js/javascript.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="sitecontainer">
<div id="buttoncontainer">
<button type="button">New</button>
</div>
<div id="sketchpadcontainer">
</div>
</div>
</body>
You are deleting the divs before the build method. That means the hover listeners will be deleted to. You have to add them to the .sqare elements again.
Just move
$(".square").hover(
//Mouse in
function () {
$(this).css("background-color", "blue");
},
//Mouse out
function () {} );
inside your build method
change $(".square").hover(
to $(document).on("hover" ,".square", function(){ . . . })
Ur problem in $(".square").hover( - work after $(document).ready, but after u appending new rows - document ready dont triggering, and ur elements have not events, and trigger .on work on every elems on page, even on dynamically added.

Categories