Pure Javascript- Change class of onclick element generated by function - javascript

I'm new in coding and have been around a problem for a few days but found no solution.
I'm trying to build a canvas with a grid made out of squares and, when a square is clicked, it changes its background color.
I'm learning pure javascript and my problem is that I can't find a way to refer to the clicked element and change only its class, because my grid is generated by a function. I am doing it this way because I want to be able to change the canvas size in future.
Any suggestions on how to proceed?
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Square Canvas Game</title>
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/css2?family=Merriweather:ital,wght#0,300;0,400;0,700;0,900;1,300;1,400;1,700;1,900&display=swap" rel="stylesheet">
</head>
<body onload="javascript:setInitialCanvas()">
<header>
<h1>Square artist</h1>
</header>
<div id="gameInterfaceContainer">
<button id="clearCanvas" onclick="clearAllSquares()">Clear All</button>
<div id="canvas">
</div>
</div>
<script src="script.js"></script>
</body>
</html>
JS
function setInitialCanvas(){
for (let i =0; i<400; i++){
let initialSquare = document.createElement("div");
document.getElementById("canvas").appendChild(initialSquare);
initialSquare.className = "canvasSquare clearSquare";
initialSquare.onclick = changeSquareColor(this);
initialSquare.style.backgroundColor = "white";
initialSquare.id = "square" + i;
}
}
function changeSquareColor(this){
let squareColor = ["white","blue","black","green","red","yellow","gray","brown"];
let colorIndex = 0;
while (squareColor[colorIndex] != this.style.backgroundColor){
colorIndex += 1;
}
if(this.style.backgroundColor == squareColor[squareColor.length]){
this.style.backgroundColor = squareColor[0];
}else
colorIndex += 1;
this.style.backgroundColor = squareColor[colorIndex];
}
Thank you!
*Edit: Adding codepen (that doesn't work) https://codepen.io/ccue92/pen/qBNKLQY

The reason it's not working is you're not binding the changeSquareColor function to onclick event, you are binding the result of it.
You need to change onclick binding like this:
initialSquare.onclick = function(event) {
changeSquareColor(event.target);
}
And do not use "this" as a variable name, because it's a reserved word for the current scope:
function changeSquareColor(square) {
let squareColor = ["white","blue","black","green","red","yellow","gray","brown"];
let colorIndex = 0;
while (squareColor[colorIndex] != square.style.backgroundColor){
colorIndex += 1;
}
if(square.style.backgroundColor == squareColor[squareColor.length]){
square.style.backgroundColor = squareColor[0];
} else {
colorIndex += 1;
}
square.style.backgroundColor = squareColor[colorIndex];
}

Related

How can I get the next and previous buttons working on my javascript code

I'm a new programmer learning and working on an image gallery with a full-screen popup using vanilla javascript and the console keep saying: Cannot set property 'src' of undefined at nextPic (app.js:35) at HTMLAnchorElement.onclick (Imagegallery.html:18).
The HTML code. I have the script running at the end. I am wondering if I need to remove the last popup event listener?? So the user can just keep clicking through using the next and previous buttons. Then, I would like for it once the user gets to the end of the gallery it automatically returns back or could press and X put to exit. I hope this helps to get my problem figured out.
const popup = document.getElementById('popup'); //reference to popup
const selectedImage = document.getElementById('selectedImage'); //reference to selected image
const imageIndexes = [1,2,3]; //array of images
const selectedIndex = null;
var currPic = 0;
var pics= '';
//to show image gallery
imageIndexes.forEach((i)=>{
const image = document.createElement('img'); //reference to image
image.src=`images/logo${i}.PNG`; //updated the source with number dynamically
image.classList.add('galleryImg'); // adding a css class
image.addEventListener('click',() =>{
//popup stuff
popup.style.transform =`translateY(0)`; //image slide down when clicked
selectedImage.src=`images/logo${i}.PNG`;
})
gallery.appendChild(image);
});
function nextPic(e){
e.preventDefault();
if (currPic < imageIndexes.length -1){
currPic++;
document.getElementById('prev').style.display = 'block';
}
else {
document.getElementById('next').style.display = 'none';
document.getElementById('prev').style.display = 'block';
}
document.popup.src = imageIndexes[currPic];
}
function prevPic(e){
e.preventDefault();
if (currPic > 0){
currPic--;
document.getElementById('next').style.display = 'block';
}
else {
document.getElementById('prev').style.display = 'none';
}
document.popup.src = imageIndexes[currPic];
}
popup.addEventListener('click', ()=>{
popup.style.transform =`translateY(-100%)`; //image slides back up
popup.src ='';
});```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Gallery</title>
<link rel="stylesheet" href="image.css">
</head>
<body>
<div class="container">
<h1>Image Gallery</h1>
<div id="gallery"></div>
</div>
<div id="popup">
<img src="" alt="" id="selectedImage">
Prev Next
</div>
<script src="app.js"></script>
</body>
</html>

How to make a function that creates toggle buttons for a setTimeout loop?

I am trying to create a function that lets me create an on/off toggle button for setTimeout loops and I am having difficulty figuring out how to get this to work the way I want it. The only way I was able to get the loop to stop was by declaring a variable in the global scope that stores the Id value for the setTimeout loop but which defeats the purpose. This also causes an issue if I try to create a second toggle button for a different loop as all the buttons access the same variable. Help would be appreciated. Thank you
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="mainContainer">
<h1 id='pointA'>Point A</h1>
<p id='pointB'>Point B</p>
</div>
</body>
<script>
function createCustomToolbar(){
var myToolbarCustom = document.createElement('div');
var targetPage= document.querySelector('body');
var myCSS=myToolbarCustom.style;
myToolbarCustom.id='myToolbarCustom';
targetPage.append(myToolbarCustom);
targetPage.style.padding='transform 0.4s ease';
targetPage.style.padding='40px';
myCSS.position='fixed';
myCSS.top=0;
myCSS.left=0;
myCSS.width='100%';
myCSS.height='35px';
myCSS.border=0;
myCSS.background='#e3e3e3'
myCSS.zIndex=9999999;
}
var x;
function toggleCreator(bttnName,callback,targetEle){
var state=false;
var mybttn=document.createElement('button');
mybttn.className='myCustomTog';
mybttn.innerHTML=bttnName;
var bttnTarget=document.getElementById('myToolbarCustom');
bttnTarget.appendChild(mybttn)
mybttn.onclick = function() {
state = !state;
if (state) {
mybttn.innerHTML = bttnName + " ON";
x = callback(targetEle);
} else {
mybttn.innerHTML = bttnName + " OFF";
clearTimeout(x);
}}
}
createCustomToolbar();
toggleCreator("start",testToggle,document.getElementById('pointA'));
toggleCreator("start",testToggle,document.getElementById('pointB'));
var i=0;
function testToggle(myTarget){
x= setTimeout(function(){
myTarget.innerHTML=i;
i++;
testToggle(myTarget);
},1000)
}
</script>
</html>
You're going to have multiple buttons and multiple timeOuts (one for each).
I'd create an empty array to store the timeOuts and use x as an index for this array.
var x = 0;
var timeouts_arr = [];
Inside testToggle...
x++;
myTarget.setAttribute('timeout_index', x);
timeouts_arr[x] = setTimeout(function(){...
inside mybttn.onclick...
state = !state;
if (state) {
mybttn.innerHTML = bttnName + " ON";
callback(targetEle); // don't use the x variable here
} else {
mybttn.innerHTML = bttnName + " OFF";
var timeout_index = mybttn.getAttribute('timeout_index');
clearTimeout(timeout_arr[timeout_index]);
}}

what happens if I call 2 functions inside a single script tag in javascript?

Here is my code :
<script>
function handleClick(){
document.body.style.color = "blue";
}
const secondButton = document.getElementById('second');
secondButton.onclick = handleClick;
function handleClick(){
document.body.style.backgroundColor = "tomato";
}
const thirdButton = document.getElementById('three');
thirdButton.onclick = handleClick;
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Add Event Handler</title>
</head>
<body>
<h1 onclick="console.log('hero programmer')">event handler</h1>
<button onmouseout="handleClick()">click me</button>
<button id="second">click me-1</button>
<button id="three">click me-2</button>
<button>click me-3</button>
</body>
</html>
what i want is that when I click on the second button the text color will be blue & the background color of the full page will be tomato when I click on the third button. But upon clicking the second & third buttons the result is the same! The background color becomes tomato but the text color doesn't change to blue. Why is it so? What can I do get my desired output?
you're redefining your function by using the same name. Try using different functions or just use an anonymous function if it's not being used elsehwere like:
const thirdButton = document.getElementById('three');
thirdButton.onclick = function(){
// do something.
};

Trying to change the id of an element with Javascript

I am trying to change the id of a div whenever I hover over a selection in my navbar. I just can't see where my problem is. When I inspect the page and hover over the navbar selections, the div id is not changing.
This is my javascript:
// Run JS after contents are loaded
document.addEventListener("DOMContentLoaded", initialiseWebPage);
function initialiseWebPage() //Loads DOM content
{
var navImage = document.getElementById("picture");
// Variables for each Nav Selection
const home = document.getElementById("Home");
const portfolio = document.getElementsById("Portfolio");
const services = document.getElementsById("Services");
const achievements = document.getElementsById("Achievements");
const hobbies = document.getElementsById("Hobbies");
// Event listeners
home.addEventListener("mouseover", changeIdHome);
portfolio.addEventListener("mouseover", changeIdPortfolio);
services.addEventListener("click", changeIdServices);
achievements.addEventListener("mouseover", changeIdAchievements);
hobbies.addEventListener("mouseover", changeIdHobbies);
function changeIdHome()
{
navImag.id = "Home";
}
function changeIdPortfolio()
{
navImage.id = "Portfolio";
}
function changeIdServices()
{
navImage.id = "Services";
}
function changeIdAchievements()
{
navImage.id = "Achievements";
}
function changeIdHobbies()
{
navImage.id = "Hobbies";
}
}
This is the beginning of my HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My Website</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="https://use.fontawesome.com/releases/v5.0.8/js/all.js"></script>
<script src="Script.js"></script> <!-- Link document to javascript file -->
<link href="style.css" rel="stylesheet">
<link rel="stylesheet" href="https://m.w3newbie.com/you-tube.css">
</head>
<body>
<!-- Navigation -->
<div class="container-fluid">
<div id="picture">
I am pretty sure I linked my js correctly to my html.
as you can see at the bottom of the HTML, the div that im trying to play around has the id of "picture".
I can't 100% confirm this, however, on many of your constants you used document.getElementsById and it's supposed to be document.getElementById.
Heres the changed JavaScript code
document.addEventListener("DOMContentLoaded", initialiseWebPage);
function initialiseWebPage() //Loads DOM content
{
var navImage = document.getElementById("picture");
// Variables for each Nav Selection
const home = document.getElementById("Home");
const portfolio = document.getElementById("Portfolio");
const services = document.getElementById("Services");
const achievements = document.getElementById("Achievements");
const hobbies = document.getElementById("Hobbies");
// Event listeners
home.addEventListener("mouseover", changeIdHome);
portfolio.addEventListener("mouseover", changeIdPortfolio);
services.addEventListener("click", changeIdServices);
achievements.addEventListener("mouseover", changeIdAchievements);
hobbies.addEventListener("mouseover", changeIdHobbies);
function changeIdHome()
{
navImag.id = "Home";
}
function changeIdPortfolio()
{
navImage.id = "Portfolio";
}
function changeIdServices()
{
navImage.id = "Services";
}
function changeIdAchievements()
{
navImage.id = "Achievements";
}
function changeIdHobbies()
{
navImage.id = "Hobbies";
}
}
I hope this helps!
Every element should have unique id.
You can't get array from one element:
document.getElementsById()
So just replace it with:
document.getElementById()

Javascript onclick functions do not work

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script language="javascript" type="text/javascript">
function setFont() {
var i;
for ( i = 0; i < document.all.length; i++) {
document.all[i].style.fontFamily = "Verdana";
document.all[i].style.fontSize = "16";
document.all[i].style.color="black";
}
};
function abc(a) {
alert(a);
ansArray = ['a'];
for (i = 1; i <= a; i++) {
document.write('<input type = "button" value = "a">');
document.write('<input type = "button" value = "b">');
}
var myButton = document.getElementsByTagName("input");
//alert(myButton.length);
myButton[0].onclick = function() {
if (ansArray[0] == 'a') myButton[0].style.backgroundColor = "green";
else myButton[0].style.backgroundColor = "red";
};
myButton[1].onclick = function() {
if (ansArray[0] == 'b') myButton[1].style.backgroundColor = "green";
else myButton[1].style.backgroundColor = "red";
};
};​
setFont();
</script>
</head>
<body onload="Javascript:abc(2)">
hello
</body>
</html>
The onclick functions do not work in IE but work fine in chrome and firefox. I could not find the mistake. Why a normal function does not work. function loads the contents but onclicking the first two buttons for which event handelers are writen does not change the button colour in IE only. Please help me... Thanks in advance
The problem here is that using document.write apparently overwrites JavaScript as well. If you switch your document.write() to document.body.innerHTML += your problem is solved. Your latter two buttons won't work with that code because you are calling button 0 and 1 exclusively, while those second two are 3 and 4.
quick googling suggests that the problem is that you are using document.write after the page has been loaded so it is erasing the dom as well. you should avoid using that in functions that are called after page loading.
source : http://sitr.us/2012/09/04/monkey-patching-document-write.html
I dont have IE so couldn't test it.

Categories

Resources