Loop to fill empty remaining space within a div - javascript

I am creating a battleship game for my next project to learn javascript and I am attempting to create divs to fill up a container wrapper. I do not want the divs to overflow, only to fill up the remaining space until it is filled. How do I test for the empty space remaining within a div to continue adding in my loop until the container is filled?
My container I am trying to fill is the #wrapper. My loop in javascript is creating the divs. I want to create a condition for the loop to stop filling when the container is full (i = 0; i < ?; i++). How do I test for this?
const body = document.querySelector('body');
const wrapper = document.querySelector('#wrapper')
const box = document.getElementsByClassName('.box');
const div = document.querySelector('div');
for (i = 0; i < 250; i++) {
let div = document.createElement('div');
div.classList = 'squares';
wrapper.appendChild(div);
}
const destroyer1 = document.querySelector('#destroyer1');
const destroyer2 = document.querySelector('#destroyer2');
destroyer1.addEventListener("drag", function(event) {}, false);
destroyer1.addEventListener("dragstart", function(event) {}, false);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body,
html {
height: 100%;
width: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
background-color: rgb(0, 0, 0);
}
h1 {
color: white;
}
#messageBoard {
color: white;
}
#shipContainer {
width: 100%;
height: 15rem;
top: 0;
left: 0;
background-color: rgb(41, 25, 25);
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#wrapper {
width: 100%;
height: 30rem;
padding: 5rem;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-content: flex-start;
}
.squares {
border: 1px solid blue;
width: 5%;
height: 5%;
}
.destroyer {
border: 1px solid blue;
width: 30%;
height: 30%;
display: flex;
flex-direction: row;
}
.destroyerSquare {
border: 1px solid orange;
width: 33%;
height: 100%;
}
<h1>BattleShip!</h1>
<p id="messageBoard">Place Your Ships!</p>
</div>
<div id="shipContainer" draggable="true">
<div class='destroyer' id='destroyer1'>
<div class='destroyerSquare'></div>
<div class='destroyerSquare'></div>
<div class='destroyerSquare'></div>
</div>
<div class='destroyer' id='destroyer2'>
<div class='destroyerSquare'></div>
<div class='destroyerSquare'></div>
<div class='destroyerSquare'></div>
</div>
<div class="battleship"></div>
<div class="cruiser"></div>
<div class="spyShip"></div>
</div>
<div id="wrapper">
</div>

Related

Why do my grid is not placed in a container?

I created a 16 x 16 grid where I can etch a sketch on that grid. It's working well. However, the problem now is that, my 16x16 grid is not hold in a container where I append it. Isn't it supposed to contain in the container where I append it ? I want to display the grid in a way like it's in a big squared box and empty on the inside. Only the most outer border is displayed. So that way, the user will know intuitively they'll have to hover over the box to sketch.
let container = document.querySelector('.container');
let rows = document.getElementsByClassName('gridRow');
let columns = document.getElementsByClassName('gridColumn');
function createGrid(number) {
makeRow(number);
makeColumn(number);
}
function makeRow(numberOfRow) {
for (let i = 0; i < numberOfRow; i++) {
let row = document.createElement('div');
container.appendChild(row);
row.classList.add('gridRow');
}
}
function makeColumn(numberOfColumn) {
for (let i = 0; i < rows.length; i++) {
for (let j = 0; j < numberOfColumn; j++) {
let column = document.createElement('div');
column.addEventListener('mouseenter', () => {
column.classList.add('colored');
});
// column.addEventListener('mouseleave', () => {
// column.classList.remove('colored');
// })
rows[j].appendChild(column);
column.classList.add('gridColumn');
}
}
}
createGrid(16);
#import url('https://fonts.googleapis.com/css2?family=Asap:wght#400;600;700&display=swap');
body {
display: flex;
flex: 1;
height: 100%;
flex-direction: column;
background-color: beige;
font-family: Asap, sans-serif;
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
.header {
display: flex;
flex: 1;
justify-content: center;
}
#setGridSize {
display: inline-flex;
justify-content: center;
flex: 1;
gap: 12px;
}
#guide {
text-align: center;
margin: 1px;
font-family: Asap, sans-serif;
color: red;
font-size: 13px;
;
}
.container {
display: flex;
flex: 1;
border: 2px solid grey;
justify-content: center;
align-content: center;
}
.gridColumn {
display: inline-flex;
flex: 1;
border: 1px solid beige;
margin: -2px 0px;
width: 100%;
height: 10%;
}
.colored {
background: red;
}
.buttons {
display: flex;
flex: 1;
gap: 20px;
}
<h1 class="header"> Let's sketch ! </h1>
<div id="setGridSize">
<p> Grid size </p> <input type="text" placeholder="Size of Board" class="size-box">
<button id="submit"> Submit </button>
</div>
<p id="guide"> Enter a number between 2 to 99</p>
<div class="container"></div>
<div class="buttons">
<button id="white"> White </button>
<button id="eraser"> Eraser </button>
<button id="black"> Black </button>
<button id="rainbow"> Rainbow </button>
<button id="reset"> Reset</button>
</div>
Try it: change height to fixed value.
.gridColumn {
display: inline-flex;
flex: 1;
border: 1px solid beige;
margin: -2px 0px;
width: 100%;
height: 20px;
}
let container = document.querySelector('.container');
let rows = document.getElementsByClassName('gridRow');
let columns = document.getElementsByClassName('gridColumn');
function createGrid(number) {
makeRow(number);
makeColumn(number);
}
function makeRow(numberOfRow) {
for (let i = 0; i < numberOfRow; i++) {
let row = document.createElement('div');
container.appendChild(row);
row.classList.add('gridRow');
}
}
function makeColumn(numberOfColumn) {
for (let i = 0; i < rows.length; i++) {
for (let j = 0; j < numberOfColumn; j++) {
let column = document.createElement('div');
column.addEventListener('mouseenter', () => {
column.classList.add('colored');
});
// column.addEventListener('mouseleave', () => {
// column.classList.remove('colored');
// })
rows[j].appendChild(column);
column.classList.add('gridColumn');
}
}
}
createGrid(16);
#import url('https://fonts.googleapis.com/css2?family=Asap:wght#400;600;700&display=swap');
body {
display: flex;
flex: 1;
height: 100%;
flex-direction: column;
background-color: beige;
font-family: Asap, sans-serif;
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
.header {
display: flex;
flex: 1;
justify-content: center;
}
#setGridSize {
display: inline-flex;
justify-content: center;
flex: 1;
gap: 12px;
}
#guide {
text-align: center;
margin: 1px;
font-family: Asap, sans-serif;
color: red;
font-size: 13px;
;
}
.container {
display: flex;
flex: 1;
border: 2px solid grey;
justify-content: center;
align-content: center;
}
.gridColumn {
display: inline-flex;
flex: 1;
border: 1px solid beige;
margin: -2px 0px;
width: 100%;
height: 20px;
}
.colored {
background: red;
}
.buttons {
display: flex;
flex: 1;
gap: 20px;
}
<h1 class="header"> Let's sketch ! </h1>
<div id="setGridSize">
<p> Grid size </p> <input type="text" placeholder="Size of Board" class="size-box">
<button id="submit"> Submit </button>
</div>
<p id="guide"> Enter a number between 2 to 99</p>
<div class="container"></div>
<div class="buttons">
<button id="white"> White </button>
<button id="eraser"> Eraser </button>
<button id="black"> Black </button>
<button id="rainbow"> Rainbow </button>
<button id="reset"> Reset</button>
</div>

How can I make these divs grow to fill the size of their container?

I'm trying to write a function that takes a users input to create a grid (16x16, 32x32 etc). The issue I'm having is getting the appended divs to scale properly to the container.
here is what it looks like:
function createGrid(input) {
const gridContainer = document.querySelector('.gridContainer');
for (let i = 0; i < input; i++) {
const row = document.createElement('div');
row.className = 'row';
for (let j = 1; j <= input; j++) {
const pixel = document.createElement('div');
pixel.className = 'pixel';
row.appendChild(pixel);
}
gridContainer.appendChild(row);
}
}
body {
height: 100vh;
}
.pixel {
flex: 1;
min-width: 8px;
min-height: 8px;
border: 0.1px solid black;
}
.gridContainer {
display: flex;
flex-direction: row;
width: 600px;
height: 600px;
border: 2px solid red;
flex-wrap: wrap;
justify-content: center;
align-content: center;
align-items: stretch;
}
<div class="gridContainer">
</div>
<input class="gridSize" type="number">
I thought adding flex 1 with a minimum width and height to the divs would do the trick so I must be missing something here. (I'm a noob so I apologize in advance if it's a super easy fix).
I believe this is the CSS you are looking for:
body {
height: 100vh;
}
.row {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.pixel {
flex: 1;
min-width: 8px;
min-height: 8px;
border: 0.1px solid black;
}
.gridContainer {
display: flex;
flex-direction: row;
width: 600px;
height: 600px;
border: 2px solid red;
flex-wrap: nowrap;
justify-content: space-between;
align-content: stretch;
}
In short, there are some adjustments regarding the .gridContainer and the .row classes.

How do I change the div size by clicking multiple button?

I want to change the div size when someone clicks the corresponding button. For example, clicking the small button will make the div width 30%, and clicking the medium button will make the div width 50%.
I found this Javascript: Change Div size on button click, but it's not working for me because I don't know his HTML structure, and he is using ID instead of class.
Below is my code. Please help me:
body {
display: flex;
flex-direction: column;
justify-content: center;
height: 300px;
}
.Button_Container {
display: flex;
flex-direction: row;
justify-content: center;
}
.Medium {
margin: 0 15px;
}
.Content_Container {
width: 100%;
height: 150px;
background-color: blue;
margin-top: 30px;
}
<div class="Button_Container">
<button class=">FULL" onclick="myFunction">FULL</button>
<button class="Medium" onclick="myFunction">Medium</button>
<button class="Small" onclick="myFunction">Small</button>
</div>
<div class="Content_Container"></div>
function myFunction(width){
var all = document.getElementsByClassName('Content_Container');
for (var i = 0; i < all.length; i++) {
all[i].style.width = width;
}
}
body {
display: flex;
flex-direction: column;
justify-content: center;
height: 300px;
}
.Button_Container {
display: flex;
flex-direction: row;
justify-content: center;
}
.Medium {
margin: 0 15px;
}
.Content_Container {
width: 100%;
height: 150px;
background-color: blue;
margin-top: 30px;
}
<div class="Button_Container">
<button class=">FULL" onclick="myFunction('100%')">FULL</button>
<button class="Medium" onclick="myFunction('70%')">Medium</button>
<button class="Small" onclick="myFunction('50%')">Small</button>
</div>
<div class="Content_Container"></div>

Resizable Sidebar - Drag To Resize

I am trying to create a layout which allows you to resize the sidebar by dragging one edge of it. This behavior can be seen in CodePen/CodeSandbox, etc.. - you can drag each 'code window' to resize it. I am looking for this same behavior but with the page layout.
What I have come up with allows me to drag to resize, but if there is a lot of content within the 'main' area (area that is not the sidebar) it throws off the drag.
I want to be able to drag all the way to the edge of the screen, regardless of the content within.
I think the best way to show this issue is by a demo:
Original Demo:
const resizer = document.querySelector("#resizer");
const sidebar = document.querySelector("#sidebar");
resizer.addEventListener("mousedown", (event) => {
document.addEventListener("mousemove", resize, false);
document.addEventListener("mouseup", () => {
document.removeEventListener("mousemove", resize, false);
}, false);
});
function resize(e) {
const size = `${e.x}px`;
sidebar.style.width = size;
}
/**
* Helpers
*/
sidebar.style.width = '325px';
const mainContent = document.querySelector("#main-content");
function addContent() {
const mainContentStr = [...Array(10).keys()].map(i => "Main Content");
mainContent.innerHTML += mainContentStr.join(' ') + '<br /><br /><h1>Now drag to see how difficult it is, remove content to see how easy it is</h1>';
}
function removeContent() {
mainContent.innerHTML = '';
}
document.querySelector("#add-content")
.addEventListener('click', () => addContent())
document.querySelector("#remove-content")
.addEventListener('click', () => removeContent())
body {
position: relative;
height: auto;
min-height: 100vh;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
overflow: hidden;
margin: 0;
}
#wrapper {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
flex-direction: column;
overflow: hidden;
position: absolute;
height: 100%;
width: 100%;
display: flex;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
flex-shrink: 0;
position: relative;
display: flex;
overflow: hidden;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#sidebar {
height: 100%;
position: relative;
margin 0;
padding: 0;
box-sizing: border-box;
background: lightgray;
border: 2px solid darkgray;
}
#resizer {
position: relative;
z-index: 2;
width: 18px;
cursor: col-resize;
border-left: 1px solid rgba(255, 255, 255, 0.05);
border-right: 1px solid rgba(0, 0, 0, 0.4);
background: #333642;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#main {
background: lightblue;
height: 100%;
flex-grow: 1;
flex-direction: row;
position: relative;
display: flex;
margin: 0;
padding: 0;
}
#add-content {
width: 80px;
float: right;
background-color: forestgreen;
}
#remove-content {
width: 80px;
float: right;
background-color: salmon;
}
<div id="wrapper">
<div id="container">
<div id="sidebar">
<p>Sidebar content</p>
<button id="add-content">Add Content</button>
<button id="remove-content">Remove Content</button>
</div>
<div id="resizer"></div>
<div id="main">
<p id="main-content"></p>
</div>
</div>
</div>
Updated Demo:
After adding buttons, they appear stretched vertically 100%
const resizer = document.querySelector("#resizer");
const sidebar = document.querySelector("#sidebar");
resizer.addEventListener("mousedown", (event) => {
document.addEventListener("mousemove", resize, false);
document.addEventListener("mouseup", () => {
document.removeEventListener("mousemove", resize, false);
}, false);
});
function resize(e) {
const size = `${e.x}px`;
sidebar.style.flexBasis = size;
}
/**
* Helpers
*/
sidebar.style.flexBasis = '325px';
const mainContent = document.querySelector("#main-content");
function addContent() {
const mainContentStr = [...Array(10).keys()].map(i => "Main Content");
mainContent.innerHTML += mainContentStr.join(' ') + '<br /><br /><h1>Now drag to see how difficult it is, remove content to see how easy it is</h1>';
}
function removeContent() {
mainContent.innerHTML = '';
}
document.querySelector("#add-content")
.addEventListener('click', () => addContent())
document.querySelector("#remove-content")
.addEventListener('click', () => removeContent())
body {
position: relative;
height: auto;
min-height: 100vh;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
overflow: hidden;
margin: 0;
}
#wrapper {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
flex-direction: column;
overflow: hidden;
position: absolute;
height: 100%;
width: 100%;
display: flex;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
flex-shrink: 0;
position: relative;
display: flex;
overflow: hidden;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#sidebar {
height: 100%;
position: relative;
margin 0;
padding: 0;
box-sizing: border-box;
background: lightgray;
border: 2px solid darkgray;
min-width: 0;
}
#resizer {
flex-basis: 18px;
position: relative;
z-index: 2;
cursor: col-resize;
border-left: 1px solid rgba(255, 255, 255, 0.05);
border-right: 1px solid rgba(0, 0, 0, 0.4);
background: #333642;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#main {
flex-basis: 0;
flex-grow: 1;
min-width: 0;
background: lightblue;
height: 100%;
flex-direction: row;
position: relative;
display: flex;
margin: 0;
padding: 0;
}
#add-content {
width: 80px;
float: right;
background-color: forestgreen;
}
#remove-content {
width: 80px;
float: right;
background-color: salmon;
}
<div id="wrapper">
<div id="container">
<div id="sidebar">
<p>Sidebar content</p>
</div>
<div id="resizer"></div>
<div id="main">
<button id="add-content">Add Content</button>
<button id="remove-content">Remove Content</button>
<p id="main-content"></p>
</div>
</div>
</div>
To set a fixed invariable width in Flexbox, use flex-basis instead of width. From that fixed size, a flex item can then shrink or grow depending on the available space and the properties of flex-grow and flex-shrink.
Furthermore, the default min-width value of a flex item is auto. This means that the item cannot have a width smaller than its content size, even when you set its flex-basis to 0px. This means that we have to override the default min-width value to 0px so that upon dragging the #resizer element, it can shrink itself completely.
Here's a working example. I merely tweaked your width property to flex-basis in both JS and CSS. And then, I also added a min-width property of 0px to both #main and #sidebar.
const resizer = document.querySelector("#resizer");
const sidebar = document.querySelector("#sidebar");
resizer.addEventListener("mousedown", (event) => {
document.addEventListener("mousemove", resize, false);
document.addEventListener("mouseup", () => {
document.removeEventListener("mousemove", resize, false);
}, false);
});
function resize(e) {
const size = `${e.x}px`;
sidebar.style.flexBasis = size;
}
/**
* Helpers
*/
sidebar.style.flexBasis = '325px';
const mainContent = document.querySelector("#main-content");
function addContent() {
const mainContentStr = [...Array(10).keys()].map(i => "Main Content");
mainContent.innerHTML += mainContentStr.join(' ') + '<br /><br /><h1>Now drag to see how difficult it is, remove content to see how easy it is</h1>';
}
function removeContent() {
mainContent.innerHTML = '';
}
document.querySelector("#add-content")
.addEventListener('click', () => addContent())
document.querySelector("#remove-content")
.addEventListener('click', () => removeContent())
body {
position: relative;
height: auto;
min-height: 100vh;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
overflow: hidden;
margin: 0;
}
#wrapper {
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
flex-direction: column;
overflow: hidden;
position: absolute;
height: 100%;
width: 100%;
display: flex;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
flex-shrink: 0;
position: relative;
display: flex;
overflow: hidden;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#sidebar {
height: 100%;
position: relative;
margin 0;
padding: 0;
box-sizing: border-box;
background: lightgray;
border: 2px solid darkgray;
min-width: 0;
}
#resizer {
flex-basis: 18px;
position: relative;
z-index: 2;
cursor: col-resize;
border-left: 1px solid rgba(255, 255, 255, 0.05);
border-right: 1px solid rgba(0, 0, 0, 0.4);
background: #333642;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#main {
flex-basis: 0;
flex-grow: 1;
min-width: 0;
background: lightblue;
height: 100%;
flex-direction: row;
position: relative;
display: flex;
margin: 0;
padding: 0;
}
#add-content {
width: 80px;
float: right;
background-color: forestgreen;
}
#remove-content {
width: 80px;
float: right;
background-color: salmon;
}
<div id="wrapper">
<div id="container">
<div id="sidebar">
<p>Sidebar content</p>
<button id="add-content">Add Content</button>
<button id="remove-content">Remove Content</button>
</div>
<div id="resizer"></div>
<div id="main">
<p id="main-content"></p>
</div>
</div>
</div>

while scrolling element stop specific point

How can I stop element at the specific point while scrolling?
Here is my source code that I using.
body {
height: 100vh;
margin: 0;
padding: 0;
}
.s1, .s2, .s3 {
height: 100vh;
}
.s1 {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid green;
}
.s2 {
display: flex;
justify-content: center;
align-items: center;
background-color: aqua;
border: 1px solid aqua;
}
.s3 {
background-color: beige;
}
.s1 .p1 {
position: fixed;
}
<html>
<body>
<div class="s1">
<p class="p1">TEST</p>
</div>
<div class="s2">
<p class="p2">STOP HERE</p>
</div>
<div class="s3">
</div>
</body>
</html>
Just simple code. I defined position: fixed to .s1's <p> tag.
So <p> always floating on center of screen while scrolling down or up.
While scrolling down, if .s1's <p> tag meet .s2's <p> tag, it have to stop.
Also if scrolling up, .s1's <p> tag have to move up.
I want to implement this issue with pure html/css/js.
But it is possible, it's ok to use library.
(Maybe it have to use parallax scrolling or other else..I don't know exactly)
Is there any solution here?
Thanks.
I have added a console log so that you can see when .s1 p touches .s2 p while scrolling.
window.onload = function() {
let s1P = document.querySelector('.s1 p');
let s2P = document.querySelector('.s2 p');
let scroll = () => {
let coordS1P = s1P.getBoundingClientRect();
let coordS2P = s2P.getBoundingClientRect();
// touched while scrolling down condition
if(coordS1P.bottom > coordS2P.top && coordS1P.top < coordS2P.bottom) console.log('touched!');
// touched while scrolling up condition
else if(coordS1P.bottom > coordS2P.top && coordS1P.top < coordS2P.bottom) console.log('touched!');
};
window.addEventListener('scroll', scroll, true);
}
body {
height: 100vh;
margin: 0;
padding: 0;
}
.s1, .s2, .s3 {
height: 100vh;
}
.s1 {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid green;
}
.s2 {
display: flex;
justify-content: center;
align-items: center;
background-color: aqua;
border: 1px solid aqua;
}
.s3 {
background-color: beige;
}
.s1 .p1 {
position: fixed;
}
<html>
<body>
<div class="s1">
<p class="p1">TEST</p>
</div>
<div class="s2">
<p class="p2">STOP HERE</p>
</div>
<div class="s3">
</div>
</body>
</html>
You mean like this?
let stop = $('#stop').offset().top - $(window).innerHeight() / 2;
$(window).on('scroll', function(){
let depth = $(window).scrollTop();
if ( stop <= (depth) ) {
$('.p1').css('position', 'absolute');
$('#stop').text('TEST');
} else {
$('.p1').css('position', 'fixed');
$('#stop').text('');
}
});
body {
height: 100vh;
margin: 0;
padding: 0;
}
.s1, .s2, .s3 {
height: 100vh;
}
.s1 {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid green;
}
.s2 {
display: flex;
justify-content: center;
align-items: center;
background-color: aqua;
border: 1px solid aqua;
}
.s3 {
background-color: beige;
}
.s1 .p1 {
position: fixed;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="s1">
<p class="p1">TEST</p>
</div>
<div class="s2">
<p class="p2" id="stop"></p>
</div>
<div class="s3"></div>

Categories

Resources