I am trying to crrate a chessboard using HTML and JS. I'm using HTML tables for that purpose. but I'm not sure why but there is are empty spaces around each cells.
I've tried cell-spacing:0; but it doesn't seems to work.\
see the red background around cells.
Here is the code
var table = document.createElement("table");
table.id = "board";
table.classList.add = "div2";
for (var i = 1; i < 9; i++) {
var tr = document.createElement('tr');
for (var j = 1; j < 9; j++) {
var td = document.createElement('td');
if (i % 2 == j % 2) {
td.className = "white";
} else {
td.className = "black";
}
tr.appendChild(td);
td.innerHTML += td.cellIndex + 1;
}
table.appendChild(tr);
}
document.body.appendChild(table);
* {
margin: 0;
padding: 0;
}
body {
background: red;
display: flex;
width: 100vw;
height: 100vh;
align-items: center;
justify-content: center;
overflow: scroll;
}
.black {
background: #769656;
}
.white {
background: #eeeed2;
}
table {
border: 2px solid red;
width: 95vw;
cell-spacing: 0;
cell-padding: 0;
height: 95vw;
}
.div2 {
width: 95vw;
height: 95vw;
}
I'm prefering javascript or css solutions to this. Thanks.
Set table.cellSpacing = 0; before adding the table to the document :
var table = document.createElement("table");
table.id = "board";
table.cellSpacing = 0;
table.classList.add = "div2";
for (var i = 1; i < 9; i++) {
var tr = document.createElement('tr');
for (var j = 1; j < 9; j++) {
var td = document.createElement('td');
if (i % 2 == j % 2) {
td.className = "white";
} else {
td.className = "black";
}
tr.appendChild(td);
td.innerHTML += td.cellIndex + 1;
}
table.appendChild(tr);
}
document.body.appendChild(table);
* {
margin: 0;
padding: 0;
}
body {
background: red;
display: flex;
width: 100vw;
height: 100vh;
align-items: center;
justify-content: center;
overflow: scroll;
}
.black {
background: #769656;
}
.white {
background: #eeeed2;
}
table {
border: 2px solid red;
width: 95vw;
cell-spacing: 0;
cell-padding: 0;
height: 95vw;
}
.div2 {
width: 95vw;
height: 95vw;
}
Just add border-collapse: collapse to your table CSS:
var table = document.createElement("table");
table.id = "board";
table.classList.add = "div2";
for (var i = 1; i < 9; i++) {
var tr = document.createElement('tr');
for (var j = 1; j < 9; j++) {
var td = document.createElement('td');
if (i % 2 == j % 2) {
td.className = "white";
} else {
td.className = "black";
}
tr.appendChild(td);
td.innerHTML += td.cellIndex + 1;
}
table.appendChild(tr);
}
document.body.appendChild(table);
* {
margin: 0;
padding: 0;
}
body {
background: red;
display: flex;
width: 100vw;
height: 100vh;
align-items: center;
justify-content: center;
overflow: scroll;
}
.black {
background: #769656;
}
.white {
background: #eeeed2;
}
table {
border: 2px solid red;
border-collapse: collapse;
width: 95vw;
height: 95vw;
}
td {
text-align: center;
}
.div2 {
width: 95vw;
height: 95vw;
}
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
</head>
<body>
</body>
</html>
Related
This question already has answers here:
How to addEventListener to multiple elements in a single line
(15 answers)
Closed 1 year ago.
So basically I have functions that creates a grid.
When I hover over a particular cell I want the cell to be filled black. But the fill should remain in the cell after the hover.
How do I do that using JS?
I'm new to JS and this is my first time asking a programming related question so I apologize if my question is not clear enough.
const container = document.querySelector('#container');
let rows = document.getElementsByClassName('grid-row');
let cells = document.getElementsByClassName('grid-column');
defaultGrid();
function defaultGrid() {
createRow(18);
createColumn(18);
}
function createRow(rowNum) {
for (let i = 0; i < rowNum; i++) {
let row = document.createElement('div');
container.appendChild(row).className = 'grid-row';
}
}
function createColumn(cellNum) {
for (let i = 0; i < rows.length; i++) {
for (let j = 0; j < cellNum; j++) {
let newCell = document.createElement('div');
rows[j].appendChild(newCell).className = 'grid-column';
}
}
}
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.grid-column {
display: inline-block;
border: 1px solid black;
min-height: 20px;
min-width: 20px;
margin-left: 2px;
margin-top: 2px;
}
#container {
border: 5px solid chartreuse;
}
.fill {
background: black;
}
<h2>test</h2>
<div id="container">
</div>
Like this:
Delegate from the container
Test the target
I use mouseover for the delegation and add your already defined class that way there is no need to add eventlisteners to each cell
container.addEventListener("mouseover",function(e) {
const tgt = e.target;
if (tgt.classList.contains("grid-column")) tgt.classList.add("fill")
})
const container = document.querySelector('#container');
let rows = document.getElementsByClassName('grid-row');
let cells = document.getElementsByClassName('grid-column');
defaultGrid();
function defaultGrid() {
createRow(18);
createColumn(18);
}
function createRow(rowNum) {
for (let i = 0; i < rowNum; i++) {
let row = document.createElement('div');
container.appendChild(row).className = 'grid-row';
}
}
function createColumn(cellNum) {
for (let i = 0; i < rows.length; i++) {
for (let j = 0; j < cellNum; j++) {
let newCell = document.createElement('div');
rows[j].appendChild(newCell).className = 'grid-column';
}
}
}
container.addEventListener("mouseover",function(e) {
const tgt = e.target;
if (tgt.classList.contains("grid-column")) tgt.classList.add("fill")
})
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.grid-column {
display: inline-block;
border: 1px solid black;
min-height: 20px;
min-width: 20px;
margin-left: 2px;
margin-top: 2px;
}
#container {
border: 5px solid chartreuse;
}
.fill {
background: black;
}
<h2>test</h2>
<div id="container">
</div>
Since you already declared a fill class, just need to add this line to your createColumn function.
function createColumn(cellNum) {
for (let i = 0; i < rows.length; i++) {
for (let j = 0; j < cellNum; j++) {
let newCell = document.createElement('div');
newCell.onmouseenter = () => newCell.classList.add("fill"); ----> Add this line
rows[j].appendChild(newCell).className = 'grid-column';
}
}
}
This will append the class name to the cell element.
Add the event listener to your cell creation loop:
const container = document.querySelector('#container');
let rows = document.getElementsByClassName('grid-row');
let cells = document.getElementsByClassName('grid-column');
defaultGrid();
function defaultGrid() {
createRow(18);
createColumn(18);
}
function createRow(rowNum) {
for (let i = 0; i < rowNum; i++) {
let row = document.createElement('div');
container.appendChild(row).className = 'grid-row';
}
}
function createColumn(cellNum) {
for (let i = 0; i < rows.length; i++) {
for (let j = 0; j < cellNum; j++) {
let newCell = document.createElement('div');
/**
* add eventlistener
*/
newCell.addEventListener('mouseover',function() {
newCell.classList.add('fill');
});
rows[j].appendChild(newCell).className = 'grid-column';
}
}
}
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.grid-column {
display: inline-block;
border: 1px solid black;
min-height: 20px;
min-width: 20px;
margin-left: 2px;
margin-top: 2px;
}
#container {
border: 5px solid chartreuse;
}
.fill {
background: black;
}
<h2>test</h2>
<div id="container">
</div>
I am creating a chessboard with Javascript. I already managed to create the board itself, but I'm having trouble giving every field its fitting class (black or white).
I managed to correctly assign the classes for the first row, but am having trouble with the rest of the board. I know there are probably easier solutions to this.
<!DOCTYPE html>
<html>
<head>
<title>Chess</title>
<link rel="stylesheet" type="text/css" href="assets/css/chess.css">
<script type="text/javascript" src="assets/js/lib/jquery.js"></script>
</head>
<body onload="initGame()">
<h1>Chess</h1>
<div id="board">
</div>
<script type="text/javascript" src="assets/js/chess.js"></script>
</body>
</html>
body{
text-align: center;
background-color: rgb(30, 30, 30);
}
#board{
margin: 0 auto;
width: 800px;
height: 800px;
background-color: white;
}
#board div{
width: 100px;
height: 100px;
float: left;
}
.white{
background-color: white;
border: 1px solid black;
}
.black{
background-color: black;
border: 1px solid white;
}
const board = [];
const boardElement = document.getElementById("board");
function initGame(){
for(var y = 0; y < 8; y++){
var row = [];
for(var x = 0; x < 8; x++){
var cell = {};
cell.element = document.createElement("div")
boardElement.appendChild(cell.element);
row.push(cell);
}
board.push(row);
}
$("#board div").addClass("field white");
for(var i = 0; i < board.length * 8; i++){
if((i % 7) == 0 && i != 0){
$(".field")[i].className = "field black";
i++;
}
else if((i % 7) == 0){
i++;
}
$(".field")[i].className = "field black";
i++;
}
startGame();
}
function startGame(){
}
The current output:
You can cut down your initGame logic to just add white class when y and x are either both odd or both even. You can do this by y%2 == x%2. You won't need the extra for loop.!
function initGame(){
for(var y = 0; y < 8; y++){
var row = [];
for(var x = 0; x < 8; x++){
var cell = {};
cell.element = document.createElement("div")
if(y%2 == x%2)
{
cell.element.className = "field white";
}
else
{
cell.element.className = "field black";
}
boardElement.appendChild(cell.element);
row.push(cell);
}
board.push(row);
}
startGame();
}
Not sure what other functionality you'd need, but for generating the board you could do something like this:
const md = () => document.createElement('div');
function makeBoard (container, length = 8) {
for ( let i = 0; i < length; i++) {
const row = md();
Array.from({length}).forEach(() => row.appendChild(md()));
container.appendChild(row);
}
}
makeBoard(document.getElementById('board'));
#board > div {
display: flex;
min-height: 32px;
}
#board > div > div {
flex: 0 0 32px;
background: tomato;
}
#board > div:nth-child(even) > div:nth-child(even) {
background: bisque;
}
#board > div:nth-child(odd) > div:nth-child(odd) {
background: bisque;
}
<div id="board"></div>
A solution with swapping array:
var colors = ['white', 'black'];
$("#board div").each(function(i) {
if((i % 2) == 0)
$(this).addClass(colors[0]);
else
$(this).addClass(colors[1]);
if([8,16,24,32,40,48,56,64].indexOf((i + 1)) > -1)
colors = colors.reverse();
});
const board = [];
const boardElement = document.getElementById("board");
function initGame(){
for(var y = 0; y < 8; y++){
var row = [];
for(var x = 0; x < 8; x++){
var cell = {};
cell.element = document.createElement("div")
boardElement.appendChild(cell.element);
row.push(cell);
}
board.push(row);
}
$("#board div").addClass('field');
var colors = ['white', 'black'];
$("#board div").each(function(i) {
if((i % 2) == 0)
$(this).addClass(colors[0]);
else
$(this).addClass(colors[1]);
if([8,16,24,32,40,48,56,64].indexOf((i + 1)) > -1)
colors = colors.reverse();
});
// startGame();
}
body{
text-align: center;
background-color: rgb(30, 30, 30);
}
#board{
margin: 0 auto;
width: 400px;
height: 400px;
background-color: white;
}
#board div{
width: 50px;
height: 50px;
float: left;
box-sizing: border-box;
}
.white{
background-color: white;
border: 1px solid black;
}
.black{
background-color: black;
border: 1px solid white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>Chess</title>
<link rel="stylesheet" type="text/css" href="assets/css/chess.css">
<script type="text/javascript" src="assets/js/lib/jquery.js"></script>
</head>
<body onload="initGame()">
<h1>Chess</h1>
<div id="board">
</div>
<script type="text/javascript" src="assets/js/chess.js"></script>
</body>
</html>
I am trying to create a pattern of 5 rows of div tags using for loops in javascript. The first row should have 1 div, the second 2 divs and so on until there the last row has 5 divs. What I currently end up with is 1 row of 15 divs.
<script>
for (var i = 0; i < 5; i++) {
for(var j = 0; j <= i; j++) {
var div = document.createElement("div");
document.body.appendChild(div);
}
var p = document.createElement("p");
document.body.appendChild(p);
}
</script>
CSS
<style>
div {
width: 20px;
height: 20px;
border: 1px solid black;
display: inline-block;
position: relative;
float: left;
}
</style>
You can simply consider br tag to create the separation and no need to use float because you will have to clear it after each row:
for (var i = 0; i < 5; i++) {
for (var j = 0; j <= i; j++) {
var div = document.createElement("div");
div.classList.add('box');
document.body.appendChild(div);
}
var br = document.createElement("br");
document.body.appendChild(br);
}
div.box {
width: 20px;
height: 20px;
border: 1px solid black;
display: inline-block;
}
With float you will need something like this:
for (var i = 0; i < 5; i++) {
for (var j = 0; j <= i; j++) {
var div = document.createElement("div");
div.classList.add('box');
document.body.appendChild(div);
}
var br = document.createElement("br");
document.body.appendChild(br);
}
div.box {
width: 20px;
height: 20px;
border: 1px solid black;
float:left;
}
br {
clear:both; /*This is mandatory !!*/
}
Or like this:
for (var i = 0; i < 5; i++) {
var p = document.createElement("div"); /*Create the row*/
p.classList.add('clear'); /*add the clear class*/
for (var j = 0; j <= i; j++) {
var div = document.createElement("div");
div.classList.add('box');
p.appendChild(div); /*Append blocks to the row and not the body*/
}
document.body.appendChild(p); /*Append the row to the body */
}
div.box {
width: 20px;
height: 20px;
border: 1px solid black;
float:left;
}
div.clear {
clear:both; /*This is mandatory !!*/
}
there are a bug on IE 11 when i empty the html in a DIV and I remove class in the list with JavaScriptS.
The DIV loses the syle CSS "Overflow:auto" and guard is a great height
There is no bug on another navigator.
Sample:
<!DOCTYPE html>
<html>
<head>
<title>CSS</title>
<style>
div {
margin: 5px;
}
ul {
margin: 5px;
max-height: 200px;
overflow: auto;
}
ul li.selected {
font-weight: bold;
}
.dest {
width: 500px;
min-height: 21px;
max-height: 120px;
overflow: auto;
border: 1px solid #ccc;
background-color: #f9f9f0;
padding: 3px;
}
.dest span {
display: block;
background-color: #fff;
float: left;
border-radius: 2px;
border: 1px solid #ccc;
margin: 2px;
padding: 0px 2px 0px 2px;
line-height: 21px;
height: auto;
}
</style>
<script>
window.onload = function(){
document.getElementById("btclear").onclick = function(){
document.getElementById("dest").innerHTML = "";
};
document.getElementById("btclearplus").onclick = function(){
document.getElementById("dest").innerHTML = "";
var ul = document.getElementById("list");
var lis = ul.getElementsByTagName("li");
for (var i = 0; i < lis.length; i++) {
lis[i].className = "";
}
};
document.getElementById("btall").onclick = function(){
for(var i = 0; i < 50; i++) {
var span = document.createElement("span");
span.innerHTML = "first name " + i + " last name " + i;
document.getElementById("dest").appendChild(span);
}
var ul = document.getElementById("list");
var lis = ul.getElementsByTagName("li");
for (var i = 0; i < lis.length; i++) {
lis[i].className = "selected";
}
};
for(var i = 0; i < 50; i++) {
for(var i = 0; i < 50; i++) {
var li = document.createElement("li");
li.innerHTML = "nom" + i + " prenom" + i;
document.getElementById("list").appendChild(li);
}
}
}
</script>
</head>
<body>
<div id="dest" class="dest"></div>
<div>
<ul id="list"></ul>
</div>
<div>
<button id="btall">Select all</button>
<button id="btclear">Clear all</button>
<button id="btclearplus">Clear all and deselect</button>
</div>
</body>
</html>
Thank you, Jean-Pierre
change the one of the loops variable i to j because you have same variable in both loops
for(var i = 0; i < 50; i++) {
for(var j = 0; j < 50; j++) {
// do you logic
}
}
I deleted the double loop, the problem was not that here.
In Internet Explorer, you must click the "Select All" button and then the button "Clear all and deselect" to reproduce the problem.
<!DOCTYPE html>
<html>
<head>
<title>CSS</title>
<style>
div {
margin: 5px;
}
ul {
margin: 5px;
max-height: 200px;
overflow: auto;
}
ul li.selected {
font-weight: bold;
}
.dest {
width: 500px;
min-height: 21px;
max-height: 120px;
overflow: auto;
border: 1px solid #ccc;
background-color: #f9f9f0;
padding: 3px;
}
.dest span {
display: block;
background-color: #fff;
float: left;
border-radius: 2px;
border: 1px solid #ccc;
margin: 2px;
padding: 0px 2px 0px 2px;
line-height: 21px;
height: auto;
}
</style>
<script>
window.onload = function(){
document.getElementById("btclear").onclick = function(){
document.getElementById("dest").innerHTML = "";
};
document.getElementById("btclearplus").onclick = function(){
document.getElementById("dest").innerHTML = "";
var ul = document.getElementById("list");
var lis = ul.getElementsByTagName("li");
for (var i = 0; i < lis.length; i++) {
lis[i].className = "";
}
};
document.getElementById("btall").onclick = function(){
for(var i = 0; i < 50; i++) {
var span = document.createElement("span");
span.innerHTML = "first name " + i + " last name " + i;
document.getElementById("dest").appendChild(span);
}
var ul = document.getElementById("list");
var lis = ul.getElementsByTagName("li");
for (var i = 0; i < lis.length; i++) {
lis[i].className = "selected";
}
};
for(var i = 0; i < 50; i++) {
var li = document.createElement("li");
li.innerHTML = "nom" + i + " prenom" + i;
document.getElementById("list").appendChild(li);
}
}
</script>
</head>
<body>
<div id="dest" class="dest"></div>
<div>
<ul id="list"></ul>
</div>
<div>
<button id="btall">Select all</button>
<button id="btclear">Clear all</button>
<button id="btclearplus">Clear all and deselect</button>
</div>
</body>
</html>
Thank you, Jean-Pierre
Overflow: Auto problem / bug in IE
.element { overflow-y: auto; overflow-x: visible; width: 450px; }
DEMO
I have to create a table with button inside each cell. However, I cannot remove the white space between cells. Any idea to do it? Sorry for poor presentation. Please comment if any information required?
var table = document.createElement('table');
table.className="table";
for (var i = 1; i < 5; i++){
var tr = document.createElement('tr');
for (var j = 1; j < 5; j++){
var td = document.createElement('td');
var but = document.createElement("BUTTON");
but.className = "table_but";
td.appendChild(but);
tr.appendChild(td);
}
table.appendChild(tr);
}
document.getElementById("table").appendChild(table);
table {
border-collapse: collapse;
border-spacing: 0;
}
tr{
padding: 0px;
margin: 0px;
}
td {
height: 20px;
width: 20px;
padding: 0;
margin: 0;
}
.table_but{
height: 100%;
width: 100%;
margin : 0;
padding : 0;
}
<div id="table">
</div>
There is a problem with the button's borders. First, you should set the buttons to display: block.
One simple solution is to explicitly set the button's height to the cell's height (20px). See this snippet:
var table = document.createElement('table');
table.className="table";
for (var i = 1; i < 5; i++){
var tr = document.createElement('tr');
for (var j = 1; j < 5; j++){
var td = document.createElement('td');
var but = document.createElement("BUTTON");
but.className = "table_but";
td.appendChild(but);
tr.appendChild(td);
}
table.appendChild(tr);
}
document.getElementById("table").appendChild(table);
table {
border-collapse: collapse;
border-spacing: 0;
}
tr{
padding: 0px;
margin: 0px;
}
td {
height: 20px;
width: 20px;
padding: 0;
margin: 0;
}
.table_but{
height: 20px;
width: 100%;
margin : 0;
padding : 0;
display: block;
}
<div id="table">
</div>
If you don't need the buttons' borders, removing them solves the problem too (I've added a hover color to help distinguish the buttons):
var table = document.createElement('table');
table.className="table";
for (var i = 1; i < 5; i++){
var tr = document.createElement('tr');
for (var j = 1; j < 5; j++){
var td = document.createElement('td');
var but = document.createElement("BUTTON");
but.className = "table_but";
td.appendChild(but);
tr.appendChild(td);
}
table.appendChild(tr);
}
document.getElementById("table").appendChild(table);
table {
border-collapse: collapse;
border-spacing: 0;
}
tr{
padding: 0px;
margin: 0px;
}
td {
height: 20px;
width: 20px;
padding: 0;
margin: 0;
}
.table_but{
height: 100%;
width: 100%;
margin : 0;
padding : 0;
display: block;
border: none;
}
.table_but:hover {
background-color: yellow;
}
<div id="table">
</div>
If I understand correctly, you should use in your css:
// cellpadding
th, td { padding: 0px; }
// cellspacing
table { border-collapse: collapse; border-spacing: 0; } // cellspacing="0"
// valign
th, td { vertical-align: top; }
// align (center)
table { margin: 0 auto; }
Font: In HTML5, with respect to tables, what replaces cellpadding, cellspacing, valign, and align?
If I understood, you just need to set your "line-height" to 0, see the result.
var table = document.createElement('table');
table.className="table";
for (var i = 1; i < 5; i++){
var tr = document.createElement('tr');
for (var j = 1; j < 5; j++){
var td = document.createElement('td');
var but = document.createElement("BUTTON");
but.className = "table_but";
td.appendChild(but);
tr.appendChild(td);
}
table.appendChild(tr);
}
document.getElementById("table").appendChild(table);
table {
border-collapse: collapse;
border-spacing: 0;
}
tr{
padding: 0px;
margin: 0px;
}
td {
height: 20px;
width: 20px;
padding: 0;
margin: 0;
line-height: 0;
}
.table_but{
height: 100%;
width: 100%;
margin : 0;
padding : 0;
}
<div id="table">
</div>