Unresponsive button in a modified hoverboard for a HTML file - javascript

I'm trying to create a modified hoverboard from an Udemy project. The original included a set of 500 squares generated via a JavaScript file where a for loop was called in order to generate them.
What I want to do here is add an input and a button in order to be able to select the number of squares directly from the input (any value from 1 to 999 squares), and generate it via JS. However, when I click OK nothing happens
This is the code from the JS file below:
const container = document.getElementById('container');
const colors = ['white', 'grey', 'rebeccapurple', 'steelblue', 'darkred', 'darkgreen', 'lightblue'];
const SQUARES = document.getElementById('input');
const button = document.getElementById('button');
button.addEventListener('click', () => clickButton(SQUARES));
function clickButton() {
for (let i = 0; i < SQUARES; i++) {
if (SQUARES < 1000) {
const square = document.createElement('div');
square.classList.add('square');
square.addEventListener('mouseover', () => setColor(square));
square.addEventListener('mouseout', () => removeColor(square));
container.appendChild(square);
}
else {
alert('The input is out of bounds.');
}
}
}
function setColor(element) {
const color = getRandomColor();
element.style.background = color;
element.style.boxShadow = `0 0 2px ${color}, 0 0 10px ${color}`;
}
function removeColor(element) {
element.style.background = '#1d1d1d';
element.style.boxShadow = '0 0 2px #000';
}
function getRandomColor() {
return colors[Math.floor(Math.random() * colors.length)];
}
What should I try? I'm thinking that the button event listener is incorrectly defined, mainly that the ClickButton function should have something else in place of SQUARES, but I'm not sure at all what I should use instead.

Related

How could I restart this current function

During the use of this function you click a button that will give you a square that will display a colour within a square. However when you click the button 60 times the programme stops working because all the colours have been used. How would I then restart this process so that I can continue clicking ?
<html>
<head>
<script>
var usedColors = [];
function randomColour(){
var colour=[];
colour[0]= '#edf2fb';
colour[1]= '#d7e3fc';
colour[3]= '#c1d3fe';
colour[4]= '#d1d1d1';
colour[5]= '#e1dbd6';
colour[6]= '#e2e2e2';
colour[7]= '#f9f6f2';
colour[8]='#ffc09f';
colour[9]='#ffee93';
colour[10]='#fcf5c7';
colour[11]='#a0ced9';
colour[12]='#adf7b6';
colour[13]='#809bce';
colour[14]='#95b8d1';
colour[15]='#b8e0d2';
colour[16]='#d6eadf';
colour[17]='#eac4d5';
colour[18]='#e8d1c5';
colour[19]='#eddcd2';
colour[20]='#fff1e6';
colour[21]='#f0efeb';
colour[22]='#eeddd3';
colour[23]='#e8dff5';
colour[24]='#fce1e4';
colour[25]='#fcf4dd';
colour[26]='#ddedea';
colour[27]='#daeaf6';
colour[28]='#d3ab9e';
colour[29]='#eac9c1';
colour[30]='#ebd8d0';
colour[31]='#ffe5ec';
colour[32]='#ffc2d1';
colour[33]='#ceb5b7';
colour[35]='#b5d6d6';
colour[36]='#f2f5ff';
colour[37]='#efcfe3';
colour[38]='#eaf2d7';
colour[39]='#b3dee2';
colour[40]='#f8ad9d';
colour[41]='#fbc4ab';
colour[42]='#ffdab9';
colour[43]='#cdb4db';
colour[44]='#ffc8dd';
colour[45]='#ffafcc';
colour[46]='#bde0fe';
colour[47]='#a2d2ff';
colour[48]='#fdffb6';
colour[49]='#caffbf';
colour[50]='#9bf6ff';
colour[51]='#a0c4ff';
colour[52]='#ffc6ff';
colour[53]='#a7bed3';
colour[54]='#c6e2e9';
colour[55]='#f1ffc4';
colour[56]='#ffcaaf';
colour[57]='#dab894';
colour[58]='#fec7bc';
colour[59]='#fcf5ee';
var pick= Math.floor(Math.random()*60);
if(usedColors.includes(pick)){
randomColour();
}
usedColors.push(pick); document.getElementById("colorpad").style.backgroundColor = colour[pick];
console.log(usedColors);
}
</script>
</head>
<body>
<div id="colorpad" style="height: 300px; width: 300px;">
<button onclick="randomColour()">btn</button>
</div>
</body>
</html>
Keep track of the current color:
let curr = 0;
On "Next" button click increment the curr index, and loopback with the help of the Modulo Operator %:
curr += 1;
curr %= colour.length; // On "next" loop back to 0 if we reached the end
Finally there's your color back at 0
console.log(colour[curr]); // '#edf2fb'
Demonstration:
const EL = (sel, EL) => (EL||document).querySelector(sel);
const colors = [
'#edf2fb',
'#d7e3fc',
'#c1d3fe',
'#d1d1d1',
'#e1dbd6',
'#e2e2e2',
'#f9f6f2',
'#ffc09f',
'#ffee93',
'#fcf5c7',
];
const tot = colors.length;
let curr = 0;
const curr_rand = () => curr = Math.floor(Math.random() * tot);
const curr_next = () => (curr += 1, curr %= tot);
const applyColor = () => EL("body").style.background = colors[curr];
EL("#rand").addEventListener("click", () => {
curr_rand();
applyColor();
console.log(curr);
});
EL("#next").addEventListener("click", () => {
curr_next();
applyColor();
console.log(curr);
});
<button type="button" id="rand">Generate</button>
<button type="button" id="next">Next</button>
Here's a snippet using a small factory function to be able to recolor infinitely. The recoloring is done using a randomly shuffled copy of the color array. This way you don't have to check each time if a color is already used.
Furthermore, see comments in the snippet. It uses event delegation for the handler, because it's generally not a good idea to use inline event handlers.
To keep the snippet lean, only 10 colors are used.
const colorize = randomColor(
['#edf2fb', '#d7e3fc', '#c1d3fe', '#d1d1d1', '#e1dbd6',
'#e2e2e2', '#f9f6f2', '#ffc09f', '#ffee93', '#fcf5c7'] );
document.addEventListener(`click`, evt => {
if (evt.target.id === `colorChange`) {
return colorize(document.querySelector(`.color`));
}
});
// randomColor is a factory function, it returns a function.
// The function can use the inner variables as well as the
// [colors] array from the parameter(they are 'closed over').
// The [colors] array is shuffled randomly (Fisher-Yates) and
// on every call (from click) the first color from that shuffled
// array is picked - until it's empty. If [shuffled] is empty
// the original [color] array is reshuffled (into [shuffled]).
// This way the coloring is restarted with a new set of
// random colors.
function randomColor(colors){
const shuffle = array =>
[...Array(array.length)]
.map((el, i) => Math.floor(Math.random() * i))
.reduce( (a, rv, i) =>
([a[i], a[rv]] = [a[rv], a[i]]) && a, array.slice());
// ^ slice copies the original
let shuffled = shuffle(colors);
// return a function
return colorDiv => {
const restarted = !shuffled.length;
shuffled = shuffled.length > 0 ? shuffled : shuffle(colors);
const nwColor = shuffled.shift();
colorDiv.style.backgroundColor = nwColor;
// for demo: color is displayed, and bold/red if [shuffled] is renewed
colorDiv.classList[restarted ? `add` : `remove`](`restart`);
colorDiv.dataset.color = nwColor;
}
}
.color {
width: 100px;
height: 100px;
border: 1px solid #777;
margin: 1rem 0;
text-align: center;
line-height: 100px;
}
.color:before {
content: attr(data-color);
}
.color.restart:before {
color: red;
font-weight: bold;
}
<div class="color"></div>
<button id="colorChange">change</button>

change background color with javascript if we click on the field

if we have in my page index.html :
<span class="token-label" style="max-width: 1072px;">Hello world</span>
<span class="token-label" style="max-width: 1072px;">Bye world</span>
in the page, we have a form that contains fields :
Hello world Bye world
i want to : when i clik on one of this two fields i will get a small list below : lit of 3 colors and i choose a color to color the background of this field with this color , in javascript please
i am a beginner in javascript, i don t know how we can do this, please help, i just tried to get a value of "Hello world" like this :
document.getElementsByClassName('token-label')[0].textContent
i search on the internet and i find : container toggle tag with color...
but i dont understand.
the most simple solution in vanilla javascript should look like the snippet bellow
did I understood your question well?
// obtain elements
const htmlCollection = document.getElementsByClassName("token-label");
const array = [...htmlCollection];
// add listener to show the palette
array.forEach(span => span.addEventListener("click", modifyColor, false));
function modifyColor(mouseEvent) {
const target = mouseEvent.currentTarget;
const x = mouseEvent.clientX;
const y = mouseEvent.clientY;
function colorChosen(color) {
target.style.backgroundColor = color;
}
showPalette({ x, y }, colorChosen);
}
function createDiv(style) {
const div = document.createElement("div");
Object.entries(style)
.forEach(([property, value]) => div.style[property] = value);
return div;
}
function showPalette({ x, y }, callback) {
// palette itself
const paletteElement =
createDiv({
position: "absolute",
left: `${x}px`,
top: `${y}px`
});
document.body.append(paletteElement);
// here you can redefine html colors
const colors = ["LightSalmon", "LightGreen", "LightBlue"];
// each color creation and adding click listeners
colors.forEach(colorValue => {
const colorElement = createDiv({
width: "40px",
height: "20px",
backgroundColor: colorValue
});
colorElement.addEventListener("click", () => {
cleanup();
callback(colorValue);
}, false);
paletteElement.append(colorElement);
});
// don't forget to remove palette from document
function cleanup() {
document.body.removeChild(paletteElement);
}
}
<span class="token-label" style="max-width: 1072px;">Hello world</span>
<span class="token-label" style="max-width: 1072px;">Bye world</span>
I can provide a script, it works for me so it should work.
#token-label {
background-color: ; /* Set your background color */
}
javascript:
var colors = ["#"]; // Set the background color you want to change
var colorIndex = 0;
function changeColor() {
var col = document.getElementById("token-label");
if( colorIndex >= colors.length ) {
colorIndex = 0;
}
if (colors[colorIndex] == col.getAttribute("currentColor")){
col.style.backgroundColor = null;
col.setAttribute("currentColor",col.style.backgroundColor);
}
else {
col.style.backgroundColor = colors[colorIndex];
col.setAttribute("currentColor",colors[colorIndex]);
}
colorIndex++;
}
And change class="token-label" to id="token-label" Let me know if it works if not maybe I got something wrong so I can change it.

How can I change or add a class of an element created in JavaScript? (Pacman change theme ghosts)

I am developing a simple Pac-man game for school. (HTML, CSS, Vanilla JavaScript) I would like to be able to change the theme of the game (From space to a floral-theme). Changing the background already works, but now I want that the ghost's also get another look when you switch from theme.
I've started with a simple grid in html, and added all the functions in Javascript. The Ghost are made in an array.
<div class="grid"></div>
const grid = document.querySelector('.grid');
class Ghost {
constructor(className, startIndex, speed) {
this.className = className
this.startIndex = startIndex
this.speed = speed
this.currentIndex = startIndex
this.timerId = NaN
}
}
const ghosts = [
new Ghost('alien1', 212, 650),
new Ghost('alien2', 212, 700),
new Ghost('alien3', 212, 830),
new Ghost('alien4', 212, 900)
];
const moveGhost = ghost => {
const directions = [-1, +1, width, -width]
let direction = directions[Math.floor(Math.random() * directions.length)]
ghost.timerId = setInterval(function () {
//Check if the next box does not contains 'wall' or another ghost
if (!squares[ghost.currentIndex + direction].classList.contains('wall') && !squares[ghost.currentIndex + direction].classList.contains('ghost')) {
//If it does not contains one of these to, the ghost can move here
//Delete all related ghost classes
squares[ghost.currentIndex].classList.remove(ghost.className, 'ghost', 'scared-alien', 'flower')
//Change the currentIndex to the next box
ghost.currentIndex += direction
//Draw the ghost in the nex/new box
squares[ghost.currentIndex].classList.add(ghost.className, 'ghost')
//If it contains 'ghost' or 'wall' move into another direction
} else direction = directions[Math.floor(Math.random() * directions.length)]
//If ghost is scared
if (ghost.isScared) {
squares[ghost.currentIndex].classList.add('scared-alien')
}
//If ghost is scared and bumps into
if (ghost.isScared && squares[ghost.currentIndex].classList.contains('pac-man')) {
squares[ghost.currentIndex].classList.remove(ghost.className, 'ghost', 'scared-alien')
ghost.currentIndex = ghost.startIndex
score += 100
squares[ghost.currentIndex].classList.add(ghost.className, 'ghost')
}
checkForGameOver()
}, ghost.speed)
}
To change a theme you must click a button, and there for i have these functions;
const init = () => {
buttonSpace.addEventListener('click', themeSpace)
buttonFlower.addEventListener('click', themeFlower)
}
const buttonSpace = document.querySelector('.btnSpace');
const buttonFlower = document.querySelector('.btnFlower');
const body = document.getElementsByTagName('body');
const themeSpace = () => {
body[0].style.backgroundImage = "url(../assets/back-space.jpg)";
}
const themeFlower = () => {
body[0].style.backgroundImage = "url(../assets/back-leaves.jpg)";
}
init();
How can I add a className or change the className of Ghost (alien.1, alien2, ... change to flowre1, flower 2, ...) when I click the button? So I can add another css-styling to change the appearance of the ghost on the grid.

Button that assigns different color to text in javascript

I am new to javascript. I have a problem but I don't know what it could be. Iam supposed to link my javascript to my html. There are three buttons that should turn the text to a diffrent color on clicking. But it is not working.
// this is the red button
const header = document.querySelector("#header");
const clicker = document.querySelector(".clicker-red");
clicker.addEventListener("click", () => {
header.style.backgroundColor = "red";
header.classList.add("large");
});
// this is the green button
const clicker = document.querySelector(".clicker-green");
clicker.addEventListener("click", () => {
header.style.backgroundColor = "green";
header.classList.add("large");
});
// this is the purple button
const clicker = document.querySelector(".clicker-pruple");
clicker.addEventListener("click", () => {
header.style.backgroundColor = "purple";
header.classList.add("large");
});
As I have said in the comments, You cannot declare variable with same name in the same Lexical Environment (i.e, in the same block).
So, you need to change the variable name.
Here is the working example.
const header = document.querySelector("#header");
const clickerRed = document.querySelector(".clicker-red");
clickerRed.addEventListener("click", () => {
header.style.backgroundColor = "red";
});
// //this is the green button
const clickerGreen = document.querySelector(".clicker-green");
clickerGreen.addEventListener("click", () => {
header.style.backgroundColor = "green";
});
// // this is the purple button
const clickerPurple = document.querySelector(".clicker-purple");
clickerPurple.addEventListener("click", () => {
header.style.backgroundColor = "purple";
});
<div id="header">
Header</div>
<button class="clicker-red" type="button">Red</button>
<button class="clicker-green" type="button">Green</button>
<button class="clicker-purple" type="button">Purple</button>

Quill Editor - get total number of lines / dynamically set editor height

I need to get a number of lines of text entered into editor by user, because initial height of the editor is small, but after user enters some text and it wraps into a new line, I need to increase the height of the editor.
I managed to get the number only if user presses enter, because then Quill adds a new <p> tag. Otherwise, if he just types text and it breaks into a new line, I can't find a way to get the total number of text lines. Here is an example:
var quill = new Quill('#editor-container', {
theme: 'snow'
});
quill.root.style['max-height'] = '81px';
quill.root.style['border-bottom'] = '1px solid grey';
trackHeight = () => {
let length = quill.getLength();
let lines = quill.getLines(0, length);
if (lines.length < 2) {
quill.root.style['min-height'] = '101px';
}
if (lines.length > 2) {
quill.root.style['min-height'] = '120px';
}
if (lines.length > 3) {
quill.root.style['min-height'] = '140px';
}
if (lines.length > 4) {
quill.root.style['min-height'] = '160px';
}
};
quill.on('text-change', this.trackHeight);
You can just copy/paste code above into a quill playground.
Note that if you press enter, size increases, but if you just type until text wraps into a separate line, editor height remains the same, because lines.length property doesn't increase.
Any advice here?
Solution:
var quill = new Quill('#editor-container', {
theme: 'snow'
});
quill.root.style['max-height'] = '81px';
quill.root.style['border-bottom'] = '1px solid grey';
trackHeight = () => {
let length = quill.getLength();
let scrollHeight = quill.root.scrollHeight;
quill.root.style['min-height'] = Math.min(scrollHeight, 500) + 'px';
if(length < 50) {
quill.root.style['min-height'] = '41px';
}
};
quill.root.style['min-height'] = '41px';
quill.on('text-change', this.trackHeight);
You can simply do:
const numberOfLines = this.quill.getLines().length;
Just set overflow to visible and it will handle automatically.
.ql-editor {
overflow-y: visible !important;
}

Categories