Function keeps executing piece of code even if changed - javascript

I'm currently having a problem making a Tic-Tac-Toe game where even if i change the "state" variable it keeps executing the code inside it, how can i solve this problem? Is there a easy way to keep executing constant code for making a game?
$(document).ready(function() {
gameManager();
});
$(document).ready(function() {
gameManager();
});
var playerSelect, aiSelect = "";
var state = "choose";
var turn = "player";
var gameOn = true;
function gameManager() {
if (state == "choose") {
chooseSide();
} else if (state == "play") {
createGrid();
if (turn == "player") {
playerChoose();
console.log("Player's turn");
} else {
playerChoose();
console.log("Enemy's turn");
}
}
}
function playerChoose() {
$('.gridElement').click(function() {
$(this).html('<div class="gridElement">' + playerSelect + '</div>');
});
}
function chooseSide() {
console.log(state);
$('#textContainer').html('<p> Choose Side: </p> <div class="chooseButton">X</div> <div class="chooseButton">O</div>');
$('.chooseButton').click(function() {
console.log(state);
playerSelect = $(this).html();
if (playerSelect == "X") {
aiSelect = "O";
} else {
aiSelect = "X";
}
state = "play"
console.log(state);
});
}
function createGrid() {
for (var i = 0; i < 9; i++) {
$('#gridContainer').append('<div class="gridElement"> </div>');
}
var gridElementSize = $('#gridContainer').width() / 3;
$('.gridElement').css({
'width': gridElementSize,
"height": gridElementSize
});
}
#gridContainer {
border: 2px solid blue;
width: 200px;
height: 200px;
margin-left: auto;
margin-right: auto;
margin-top: 40px;
}
.gridElement {
display: inline-block;
vertical-align: top;
border: 1px solid black;
}
#textContainer {
margin-left: auto;
margin-right: auto;
}
.chooseButton {
display: inline-block;
}
<!DOCTYPE>
<!DOCTYPE html>
<html>
<head>
<!-- INITIALIZE -->
<link href="https://fonts.googleapis.com/css?family=Bungee+Shade" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Black+Ops+One" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="https://use.fontawesome.com/ca5f7b6f9a.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="stylesheet.css">
<script src="script.js"></script>
<!--CONTENT-->
<title>TicTacToe</title>
</head>
<body>
<div id="textContainer">
</div>
<div id="gridContainer">
</div>
</body>
</html>

As Bamar said, Javascript web applications are event-driven, meaning you need to create event handlers for user interactions with the web page. Events occur when the user interacts with the browser (clicks an element on the page, scrolls the view, etc.). Event handlers are Javascript functions. When binding event handlers, you should only bind them once to an event type. There are only two events in your application that need handling: choosing X or O, and clicking on a square in the grid.
I refactored your code to illustrate a better approach. The choosing of sides is bound once in initGame, and the grid-square-click is bound to the squares when they are created (each time the game is reset by choosing sides again). Note that it is necessary to bind the square click handler again each time the game is reset, because the previous gridElements are removed at the top of resetGrid, and the event handler binding to those removed elements is lost.
$(document).ready(function() {
initGame();
});
var playerSelect, aiSelect = "";
var turn;
var gameOn;
function initGame() {
$('#textContainer').html('<p> Choose Side: </p> <div class="chooseButton">X</div> <div class="chooseButton">O</div>');
$('.chooseButton').click(function(){
playerSelect = $(this).html();
if(playerSelect == "X"){
aiSelect = "O";
} else {
aiSelect = "X";
}
resetGame();
});
}
function resetGame(){
gameOn = true;
turn = "player";
resetGrid();
}
function resetGrid(){
// remove any existing grid elements
$('.gridElement').remove();
for(var i = 0; i < 9; i++){
$('#gridContainer').append('<div class="gridElement"></div>');
}
var gridElementSize = $('#gridContainer').width()/3;
$('.gridElement').css({'width': gridElementSize, "height": gridElementSize});
// bind the click handler to the new elements
$('.gridElement').click(function(e){ // e is the event
handlePlayerClick(e);
});
}
function checkForWinOrDraw() {
// check for win or draw
gameOn = true; // set to false if game is over
}
function handlePlayerClick(e) { // e is the click event
if( gameOn == false ) {
// the current game is over, so do nothing
return;
}
if(turn == "player"){
square = $(e.target);
if( square.html() == "") { // if the square is empty
$(e.target).html(playerSelect); // e.target is the grid element
turn = "enemy";
console.log("Player has made a move");
// the player has made a move
checkForWinOrDraw();
makeEnemyMove();
} else {
console.log("Square has already been taken.");
}
} else {
console.log("Player can't play. It's the enemy's turn");
}
}
function makeEnemyMove() {
if( gameOn == false ) {
// the current game is over, so do nothing
return;
}
// dumb AI picks first empty square. Replace with smart AI
els = $('.gridElement').toArray();
var i;
for( i = 0; i < els.length; i++ ) {
var el = $(els[i]);
if( el.html() == "" ) {
el.html(aiSelect);
console.log("Enemy has made a move");
turn = "player";
break;
}
}
checkForWinOrDraw();
}
#gridContainer{
border: 2px solid blue;
width: 200px;
height: 200px;
margin-left: auto;
margin-right: auto;
margin-top: 40px;
}
.gridElement{
display: inline-block;
vertical-align:middle;
text-align: center;
padding-top: 20px;
border: 1px solid black;
}
#textContainer{
margin-left: auto;
margin-right: auto;
}
.chooseButton{
display: inline-block;
}
<!DOCTYPE>
<!DOCTYPE html>
<html>
<head>
<!-- INITIALIZE -->
<link href="https://fonts.googleapis.com/css?family=Bungee+Shade" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Black+Ops+One" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="https://use.fontawesome.com/ca5f7b6f9a.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="stylesheet.css">
<script src="script.js"></script>
<!--CONTENT-->
<title>TicTacToe</title>
</head>
<body>
<div id="textContainer">
</div>
<div id="gridContainer">
</div>
</body>
</html>

Related

Weird bug occurring for Event listeners( I think)

Whenever I click either 'Reset', 'Color Black', or 'Erase' randomly the entire grid will color in black. If that happens and I click Erase I can clear them off and then sometimes randomly the excess black that was randomly created will disappear. Not really sure what the issue is. I THINK it may be an issue with how the Event Listeners are set up, but this is the only configuration of them that gets the buttons to work. Any ideas what the issue might be?
let blackBtn = document.querySelector('#black');
let eraseBtn = document.querySelector('#eraser');
let resetBtn = document.querySelector('#reset');
let resize = document.querySelector('.resize');
let value = 16; // For default 16x16 grid size
//Create grid
function createGrid(size = value) {
grid.style["grid-template-rows"] = `repeat(${size}, 1fr)`;
grid.style["grid-template-columns"] = `repeat(${size}, 1fr)`;
for (let i = 0; i < size * size; i++) {
const block = document.createElement('div');
block.className = 'block';
grid.appendChild(block);
}
grid.addEventListener("mouseover", colorBlack);
resize.addEventListener("click", resizeGrid);
resetBtn.addEventListener("click", clearGrid);
eraseBtn.addEventListener("click", eraseColor);
blackBtn.addEventListener("click", blackPaint);
}
//Resize the grid
function resizeGrid() {
const newSize = parseInt(prompt("New Size: ", 16));
grid.innerHTML = '';
resize.removeEventListener("click", resizeGrid);
grid.removeEventListener("mouseover", colorBlack);
createGrid(newSize);
}
//Fill in background color of black
function colorBlack(e) {
if (e.target.className !== "block") return false;
e.target.style.backgroundColor = 'black';
}
//Clear background color from grid
function clearGrid(size, newSize) {
grid.innerHTML = '';
resize.removeEventListener("click", resizeGrid);
grid.removeEventListener("mouseover", colorBlack);
createGrid();
}
//Colors divs black after clicking 'Color Black'
function blackPaint(e) {
grid.removeEventListener("mouseover", eraseColor);
grid.addEventListener("mouseover", (e) => {
e.target.style.backgroundColor = 'black';
})
}
//Colors over black divs with white to 'erase' it
function eraseColor(e) {
grid.removeEventListener("mouseover", colorBlack);
grid.addEventListener("mouseover", (e) => {
e.target.style.backgroundColor = 'white';
})
}
createGrid();
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
#grid {
width: 20rem;
height: 20rem;
border: 1px solid #333;
display: grid;
flex-wrap: grid;
}
.block {
border: 1px solid black;
}
<!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>Etch-A-Sketch</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<p>Etch-A-Sketch</p>
</header>
<div class="gameBoard">
<div id="actions">
<button class="resize">Resize</button>
<button id="reset">Reset</button>
<button id="black">Color Black</button>
<button id="eraser">Eraser</button>
</div>
<div id='grid'></div>
<div class="block"></div>
</div>
<script src="script.js"></script>
</body>
</html>
When you click on Black or Erase, you add event listeners that call anonymous functions. These can't be removed with removeEventListener() when you switch modes. So these old event listeners continue to run, erasing and filling in elements.
You should have two functions, colorBlack() and colorWhite(), and switch between them in the mouseover event listener. Also, when you reset or resize, you should go back to black.
The problem with Clear is that it calls createGrid(), which adds all the event listeners again. You remove some of the old listeners before you call it, but not all, so you get duplication. You should separate creating the grid and adding the event listeners, so you don't repeat the listeners, and then you wouldn't need to remove them.
let blackBtn = document.querySelector('#black');
let eraseBtn = document.querySelector('#eraser');
let resetBtn = document.querySelector('#reset');
let resize = document.querySelector('.resize');
let value = 16; // For default 16x16 grid size
//Create grid
function createGrid(size = value) {
grid.style["grid-template-rows"] = `repeat(${size}, 1fr)`;
grid.style["grid-template-columns"] = `repeat(${size}, 1fr)`;
for (let i = 0; i < size * size; i++) {
const block = document.createElement('div');
block.className = 'block';
grid.appendChild(block);
}
}
function addListeners() {
grid.addEventListener("mouseover", colorBlack);
resize.addEventListener("click", resizeGrid);
resetBtn.addEventListener("click", clearGrid);
eraseBtn.addEventListener("click", eraseColor);
blackBtn.addEventListener("click", blackPaint);
}
//Resize the grid
function resizeGrid() {
const newSize = parseInt(prompt("New Size: ", 16));
grid.innerHTML = '';
createGrid(newSize);
blackPaint();
}
//Fill in background color of black
function colorBlack(e) {
if (e.target.className !== "block") return false;
e.target.style.backgroundColor = 'black';
}
//Fill in background color of white
function colorWhite(e) {
if (e.target.className !== "block") return false;
e.target.style.backgroundColor = 'white';
}
//Clear background color from grid
function clearGrid(size, newSize) {
grid.innerHTML = '';
createGrid();
blackPaint();
}
//Colors divs black after clicking 'Color Black'
function blackPaint(e) {
grid.removeEventListener("mouseover", colorWhite);
grid.addEventListener("mouseover", colorBlack);
}
//Colors over black divs with white to 'erase' it
function eraseColor(e) {
grid.removeEventListener("mouseover", colorBlack);
grid.addEventListener("mouseover", colorWhite);
}
createGrid();
addListeners();
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
#grid {
width: 20rem;
height: 20rem;
border: 1px solid #333;
display: grid;
flex-wrap: grid;
}
.block {
border: 1px solid black;
}
<!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>Etch-A-Sketch</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<p>Etch-A-Sketch</p>
</header>
<div class="gameBoard">
<div id="actions">
<button class="resize">Resize</button>
<button id="reset">Reset</button>
<button id="black">Color Black</button>
<button id="eraser">Eraser</button>
</div>
<div id='grid'></div>
<div class="block"></div>
</div>
<script src="script.js"></script>
</body>
</html>

how to reset color grid?

I am creating a simple etch-a-sketch game. currently on hover it colors in black. I am trying to use a button to reset the colors back to white. However, i can't get the button to function with an event listener, if i add an alert it displays the alert but nothing else. Please guide me and supply a documentation that I can reference as I want to learn and fixing it without explaining will be counterproductive at this point.
Thank you !
const containerGrid = document.getElementById("mainGrid");
function makeGrid(col) {
for (let i = 0; i < col * col; i++) {
const gridAdd = document.createElement("div");
gridAdd.classList.add("box");
gridAdd.textContent = "";
containerGrid.appendChild(gridAdd);
}
}
makeGrid(16); // make grid 16*16
const btnClear = document.getElementById("clear");
//mouseover event black - need to link to button (well done :)
const boxes = document.querySelectorAll('.box').forEach(item => {
item.addEventListener('mouseover', event => {
item.style.backgroundColor = "black";
})
});
btnClear.addEventListener("click", () => {
boxes.style.backgroundColor = "white";
});
const changeGrid = document.getElementById(".sizechange");
/*clearBtn.forEach.addEventListener("click", function () {
clearBtn.style.color ="white";
});
*/
/*const randomBtn = document.getElementById("randomgen").addEventListener('click',(e) => {
console.log(this.classname)
console.log(e.currentTarget === this)
}) */
//change color
#mainGrid {
display: grid;
justify-content: center;
align-items: center;
grid-template-columns: repeat(16, 1fr);
grid-template-rows: auto;
margin-left: 150px;
width: 200px;
}
.box {
color: black;
border: 3px solid;
height: 10px;
width: 10px;
}
<!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>Etch-a-Sketch</title>
<link type="text/css" rel="stylesheet" href="styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div id="colorContainer">
<input type="radio" id="blackchoice" value="color" name="black" class="defaultbtn">
<label for="defaultcolor">black</label>
<input type="radio" id="randomgen" class="hey">
<label for="randomchoice">random</label>
</div>
<div id="changeGrid">
<button id="clear">clear</button>
</div>
<div id="mainGrid"></div>
<script src="app.js"></script>
</body>
</html>
A couple of related problems:
The variable boxes is undefined. It looks as though it was required to be the set elements with class box. When it is being defined this is indeed done, but then made undefined by the forEach attached to it. Separate out these two things and boxes will become the collection of all elements with class box.
Then when the clear is clicked you need to step through each of these boxes making their background color white, so again use a forEach.
<!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>Etch-a-Sketch</title>
<link type="text/css" rel="stylesheet" href="styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
#mainGrid {
display: grid;
justify-content: center;
align-items: center;
grid-template-columns: repeat(16, 1fr);
grid-template-rows: auto;
margin-left: 150px;
width: 200px;
}
.box {
color: black;
border: 3px solid;
height: 10px;
width: 10px;
}
</style>
</head>
<body>
<div id="colorContainer">
<input type="radio" id="blackchoice" value="color" name="black" class="defaultbtn">
<label for="defaultcolor">black</label>
<input type="radio" id="randomgen" class="hey">
<label for="randomchoice">random</label>
</div>
<div id="changeGrid">
<button id="clear">clear</button>
</div>
<div id="mainGrid"></div>
<script src="app.js"></script>
<script>
const containerGrid = document.getElementById("mainGrid");
function makeGrid(col) {
for (let i = 0; i < col * col; i++) {
const gridAdd = document.createElement("div");
gridAdd.classList.add("box");
gridAdd.textContent = "";
containerGrid.appendChild(gridAdd);
}
}
makeGrid(16); // make grid 16*16
const btnClear = document.getElementById("clear");
//mouseover event black - need to link to button (well done :)
const boxes = document.querySelectorAll('.box');
boxes.forEach(box => {
box.addEventListener('mouseover', event => {
box.style.backgroundColor = "black";
})
});
btnClear.addEventListener("click", () => {
boxes.forEach(box => {
box.style.backgroundColor = "white";
});
});
const changeGrid = document.getElementById(".sizechange");
/*clearBtn.forEach.addEventListener("click", function () {
clearBtn.style.color ="white";
});
*/
/*const randomBtn = document.getElementById("randomgen").addEventListener('click',(e) => {
console.log(this.classname)
console.log(e.currentTarget === this)
}) */
//change color
</script>
</body>
</html>
Simplify your CSS
Use a SELECT element for your colors
Define the gridTemplateColumns in JS, not in CSS.
Use simpler functions
Use global variables to store the current grid size and color
Don't forget to clear your grid before changing the size
Assign the mouseenter Event on each cell on creation!
Add a boolean variable isPenDown for a better user experience!
const NewEL = (sel, prop) => Object.assign(document.createElement(sel), prop);
const EL_grid = document.querySelector("#grid");
const EL_clear = document.querySelector("#clear");
const EL_color = document.querySelector("[name=color]");
const EL_size = document.querySelector("[name=size]");
let size = parseInt(EL_size.value, 10);
let color = "black";
let isPenDown = false;
function makeGrid() {
EL_grid.innerHTML = ""; // Clear current grid!
for (let i = 0; i < size ** 2; i++) {
EL_grid.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
EL_grid.append(NewEL("div", {
className: "box",
onmousedown() { isPenDown = true; paint(this); },
onmouseup() { isPenDown = false; },
onmouseenter() { if (isPenDown) paint(this); },
}));
}
};
function paint(EL) {
EL.style.backgroundColor = color;
}
EL_clear.addEventListener("click", () => {
const tmp_color = color; // Remember current color
color = "transparent"; // Temporarily set it to transparent
EL_grid.querySelectorAll(".box").forEach(paint); // Paint all cells as transparent
color = tmp_color; //* Reset as it was before.
});
EL_color.addEventListener("change", () => {
color = EL_color.value;
if (color === "random") color = `hsl(${~~(Math.random() * 360)}, 80%, 50%)`;
});
EL_size.addEventListener("change", () => {
size = parseInt(EL_size.value, 10);
makeGrid();
});
// INIT!
makeGrid();
#grid {
display: inline-grid;
margin: 10px 0;
}
#grid .box {
border: 1px solid;
height: 10px;
width: 10px;
margin: 0;
user-select: none;
}
<div>
<label>
Size:
<input type="number" name="size" value="16">
</label>
<label>
Color:
<select name="color">
<option value="black">black</option>
<option value="white">white</option>
<option value="red">red</option>
<option value="yellow">yellow</option>
<option value="orange">orange</option>
<option value="fuchsia">fuchsia</option>
<option value="transparent">CLEAR (transparent)</option>
<option value="random">RANDOM COLOR</option>
</select>
</label>
<button id="clear">Clear canvas</button>
</div>
<div id="grid"></div>

Building a vanilla carousel - stuck on one peice of logic

Any mentorship or guidance would be most welcomed.
I am trying to make a vanilla JS carousel and I am so close to realising my objective to build one.
However; I cannot seem to get the prev or next buttons to move the carousel backwards or forwards. The buttons "work" they go up and down in value; they do not change the style. I can see that console logging the values.
I've tried passing the function back onto itself - however, I cannot think of a way of initialising the start frame; if that is the best way.
Adding the slideIndex value into the style rule doesn't work. What I get is if you keep on pressing "prev" for example; eventually, another frame randomly pops up below.
Any help would be very much welcomed.
On a side note - is there a better way to work with variable scoping; without everything requiring this?
'use strict';
function carousel(n) {
this.slideIndex = n;
this.slides = document.querySelectorAll('.homepage_carousel_wrapper .homepage_carousel');
[...this.slides].forEach(function(x) {
x.style.display = 'none';
});
this.slides[this.slideIndex-1].style.display = "flex";
this.prev = function(n) {
this.slideIndex += n;
if (this.slideIndex < 1) {
this.slideIndex = this.slides.length;
}
console.log(`${this.slideIndex}`);
this.slides[this.slideIndex].style.display = "flex";
}
this.next = function(n) {
this.slideIndex += n;
if (this.slideIndex > this.slides.length) {
this.slideIndex = 1;
}
console.log(`${this.slideIndex}`);
this.slides[this.slideIndex].style.display = "flex";
//carousel(this.slideIndex)
}
};
window.addEventListener('load', function() {
const hp_carousel = new carousel(3);
let carouselPrev = document.getElementById('carousel_prev');
carouselPrev.addEventListener('click', function(e){
hp_carousel.prev(-1);
e.preventDefault();
e.stopPropagation();
}, false);
let carouselNext = document.getElementById('carousel_next');
carouselNext.addEventListener('click', function(e){
hp_carousel.next(1);
e.preventDefault();
e.stopPropagation();
}, false);
});
.homepage_carousel:nth-child(1) {
background-color: red;
width: 100%;
height: 200px;
}
.homepage_carousel:nth-child(2) {
background-color: blue;
width: 100%;
height: 200px;
}
.homepage_carousel:nth-child(3) {
background-color: green;
width: 100%;
height: 200px;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>carousel</title>
</head>
<body>
<a id='carousel_prev'>prev</a>
<a id='carousel_next'>next</a>
<div class='homepage_carousel_wrapper'>
<div class='homepage_carousel'>
<h1>Frame 1</h1>
</div>
<div class='homepage_carousel'>
<h1>Frame 2</h1>
</div>
<div class='homepage_carousel'>
<h1>Frame 3</h1>
</div>
</div>
</body>
</html>
I have made some modifications to the HTML and CSS, and have rewritten most of the JavaScript.
Main Modifications
HTML
Changed the controls from links to buttons.
Moved the controls inside the carousel.
CSS
Removed repeated CSS.
JavaScript
Added spacing to make the code more readable.
Added a few comments to make the code easier to understand.
Modified the carousel constructor to allow multiple carousels to be made.
Moved the control event listeners inside the carousel constructor.
Replaced the prev() and next() functions with a changeSlide() function.
'use strict';
window.addEventListener('load', function() {
const hpCarousel = new carousel('homepage_carousel', 3);
});
function carousel(id, index) {
// Set slide index and get slides
this.slideIndex = index;
const carousel = document.getElementById(id);
this.slides = [...carousel.getElementsByClassName('slide')];
// Get controls and add event listeners
const prev = carousel.getElementsByClassName('prev')[0];
const next = carousel.getElementsByClassName('next')[0];
prev.addEventListener('click', () => {
this.changeSlide(-1);
});
next.addEventListener('click', () => {
this.changeSlide(1);
});
// Functions for managing slides
this.hideAll = function() {
this.slides.forEach(function(slide) {
slide.style.display = 'none';
});
}
this.show = function() {
this.hideAll();
this.slides[this.slideIndex - 1].style.display = 'flex';
}
this.changeSlide = function(amount) {
this.slideIndex += amount;
this.slideIndex = (this.slideIndex > this.slides.length) ? 1 :
(this.slideIndex < 1) ? this.slides.length : this.slideIndex;
this.show();
}
// Show the specified slide
this.show();
}
.slide {
width: 100%;
height: 200px;
}
.slide:nth-child(1) {
background-color: red;
}
.slide:nth-child(2) {
background-color: blue;
}
.slide:nth-child(3) {
background-color: green;
}
<div id='homepage_carousel'>
<button class='prev'>prev</button>
<button class='next'>next</button>
<div>
<div class='slide'>
<h1>Frame 1</h1>
</div>
<div class='slide'>
<h1>Frame 2</h1>
</div>
<div class='slide'>
<h1>Frame 3</h1>
</div>
</div>
</div>

Fruit ninja type game in javascript

I'm trying to make a ninja fruit style game in javascript but problems are happening. I have this if statements that compare the variable "fruit" with the index of the "fruits" array. The problem is when I "eliminate" a fruit the other if statements doenst work.
That's how the game needs to work:
1 You start the game, a random name of a fruit appears for you to click on.
2 You click in the image of the fruit and it disappears, in this click another random fruit is generated.
3 An then you finish the game, that's prety much this.
So it's kind hard to explain, but its the same logic as the ninja fruit game. And I dont know if I need to use the shift function to eliminate the fruits in the array as well.
var fruits = ['Banana', 'Apple', 'Pineapple'];
var fruit = fruits[Math.floor(Math.random() * fruits.length)];
document.getElementById("frut").innerHTML = fruit;
if (fruit == fruits[0]) {
bana.onclick = function() {
var fruit = fruits[Math.floor(Math.random() * fruits.length)];
document.getElementById("frut").innerHTML = fruit;
bana.style.display = "none";
}
}
if (fruit == fruits[1]) {
app.onclick = function() {
var fruit = fruits[Math.floor(Math.random() * fruits.length)];
document.getElementById("frut").innerHTML = fruit;
app.style.display = "none";
}
}
if (fruit == fruits[2]) {
pin.onclick = function() {
var fruit = fruits[Math.floor(Math.random() * fruits.length)];
document.getElementById("frut").innerHTML = fruit;
pin.style.display = "none";
}
}
function movFruit() {
document.getElementById("info").style.display = "table";
document.getElementById("fruitAnimation").style.display = "table";
document.getElementById("insructions").style.display = "none";
var elem = document.getElementById("fruitAnimation");
var pos = 0;
var id = setInterval(frame, 10);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + 'px';
}
}
}
#fruitAnimation {
position: relative;
display: none;
margin: 0 auto;
}
.fr {
float: left;
padding: 80px;
}
#info {
display: none;
margin: 0 auto;
}
#insructions {
display: table;
margin: 0 auto;
margin-top: 200px;
border: 1px solid black;
padding: 10px;
}
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
<title>JSfruit</title>
</head>
<body>
<div id="info">
<h1>Fruit: <span id="frut"></span></h1>
</div>
<button onclick="movFruit() " style="display: table; margin: 0 auto;"><h4>Start the game</h4></button>
<div id="fruitAnimation">
<div class="fr" id="bana">
<img src="https://orig00.deviantart.net/5c87/f/2016/322/8/9/banana_pixel_art_by_fireprouf-daosk9z.png" width="60" height="60">
</div>
<div class="fr" id="app">
<img src="https://art.ngfiles.com/images/404000/404664_thexxxreaper_pixel-apple.png?f1454891997" width="60" height="60">
</div>
<div class="fr" id="pin">
<img src="https://i.pinimg.com/originals/c2/f9/e9/c2f9e9f8d332da97a836513de98f7b29.jpg" width="60" height="60">
</div>
</div>
<span id="insructions">Click in the fruits and erase them!</span>
</body>
</html>
Right now, you're only attaching handlers to the fruit images at the top level, in your if statements - but once those statements run and the main block finishes, it doesn't get run again.
You should attach handlers to all fruit images at once in the beginning, and then in the handlers, check to see the clicked fruit was valid.
If you're assigning text to an element, assign to textContent, not innerHTML; textContent is quicker, safer, and more predictable.
const fruits = ['Banana', 'Apple', 'Pineapple'];
const getRandomFruit = () => {
const randomIndex = Math.floor(Math.random() * fruits.length);
const fruit = fruits[randomIndex];
document.getElementById("frut").textContent = fruit;
fruits.splice(randomIndex, 1);
return fruit;
};
let fruitToClickOn = getRandomFruit();
bana.onclick = function() {
if (fruitToClickOn !== 'Banana') return;
bana.style.display = "none";
fruitToClickOn = getRandomFruit();
}
app.onclick = function() {
if (fruitToClickOn !== 'Apple') return;
app.style.display = "none";
fruitToClickOn = getRandomFruit();
}
pin.onclick = function() {
if (fruitToClickOn !== 'Pineapple') return;
pin.style.display = "none";
fruitToClickOn = getRandomFruit();
}
function movFruit() {
document.getElementById("info").style.display = "table";
document.getElementById("fruitAnimation").style.display = "table";
document.getElementById("insructions").style.display = "none";
var elem = document.getElementById("fruitAnimation");
var pos = 0;
var id = setInterval(frame, 10);
function frame() {
if (pos == 350) {
clearInterval(id);
} else {
pos++;
elem.style.top = pos + 'px';
}
}
}
#fruitAnimation {
position: relative;
display: none;
margin: 0 auto;
}
.fr {
float: left;
padding: 80px;
}
#info {
display: none;
margin: 0 auto;
}
#insructions {
display: table;
margin: 0 auto;
margin-top: 200px;
border: 1px solid black;
padding: 10px;
}
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
<title>JSfruit</title>
</head>
<body>
<div id="info">
<h1>Fruit: <span id="frut"></span></h1>
</div>
<button onclick="movFruit() " style="display: table; margin: 0 auto;"><h4>Start the game</h4></button>
<div id="fruitAnimation">
<div class="fr" id="bana">
<img src="https://orig00.deviantart.net/5c87/f/2016/322/8/9/banana_pixel_art_by_fireprouf-daosk9z.png" width="60" height="60">
</div>
<div class="fr" id="app">
<img src="https://art.ngfiles.com/images/404000/404664_thexxxreaper_pixel-apple.png?f1454891997" width="60" height="60">
</div>
<div class="fr" id="pin">
<img src="https://i.pinimg.com/originals/c2/f9/e9/c2f9e9f8d332da97a836513de98f7b29.jpg" width="60" height="60">
</div>
</div>
<span id="insructions">Click in the fruits and erase them!</span>
</body>
</html>

Javascript, JQuery Previous button

I need some help with this code. I want to create an event click button for previous. How can I do this using a little code? some thing similar to my Next button click event.
Here is my full code.
$(document).ready(function() {
var nextSlide = $("#slides img:first-child");
var nextCaption;
var nextSlideSource;
var counter = 0;
// the function for running the slide show
var runSlideShow = function() {
$("#caption").fadeOut(1000);
$("#slide").fadeOut(1000,
function () {
if (nextSlide.next().length === 0) {
nextSlide = $("#slides img:first-child");
}
else {
nextSlide = nextSlide.next();
}
nextSlideSource = nextSlide.attr("src");
nextCaption = nextSlide.attr("alt");
$("#slide").attr("src", nextSlideSource).fadeIn(1000);
$("#caption").text(nextCaption).fadeIn(1000);
}
);
};
// start the slide show
var timer = setInterval(runSlideShow, 3000);
$("#play").on("click", function() {
if($(this).val() === "Pause") {
clearInterval(timer);
$(this).val("Play");
$("#prev").prop("disabled", false);
$("#next").prop("disabled", false);
}
else if ($(this).val() === "Play") {
timer = setInterval(runSlideShow, 3000);
$(this).val("Pause");
$("#prev").prop("disabled", true);
$("#next").prop("disabled", true);
}
});
var imag = $("#slides img").index();
var imageSize = $("#slides img").length - 1;
$("#next").on("click", function (e) {
e.preventDefault();
if (imag === imageSize) {
$("#next").prop("disabled", true);
}
else {
++imag;
runSlideShow(1);
}
});
});
body {
font-family: Arial, Helvetica, sans-serif;
width: 380px;
height: 350px;
margin: 0 auto;
padding: 20px;
border: 3px solid blue;
}
h1, h2, ul, p {
margin: 0;
padding: 0;
}
h1 {
padding-bottom: .25em;
color: blue;
}
h2 {
font-size: 120%;
padding: .5em 0;
}
img {
height: 250px;
}
#slides img {
display: none;
}
#buttons {
margin-top: .5em;
text-align: center;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Slide Show</title>
<link rel="stylesheet" href="main.css">
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="slide_show.js"></script>
</head>
<body>
<section>
<h1>Fishing Slide Show</h1>
<h2 id="caption">Casting on the Upper Kings</h2>
<img id="slide" src="images/casting1.jpg" alt="">
<div id="slides">
<img src="images/casting1.jpg" alt="Casting on the Upper Kings">
<img src="images/casting2.jpg" alt="Casting on the Lower Kings">
<img src="images/catchrelease.jpg" alt="Catch and Release on the Big Horn">
<img src="images/fish.jpg" alt="Catching on the South Fork">
<img src="images/lures.jpg" alt="The Lures for Catching">
</div>
<div id="buttons">
<input type="button" id="prev" value="Previous" disabled>
<input type="button" id="play" value="Pause">
<input type="button" id="next" value="Next" disabled>
</div>
</section>
</body>
</html>
I thought of during it this way, but that is not working.
$("#prev").on("click", function () {
if (imag === imageSize) {
$("#prev").prop("disabled", true);
}
else {
++imag;
runSlideShow(-1);
}
});
Something similar to this Next button click event.
$("#next").on("click", function (e) {
e.preventDefault();
if (imag === imageSize) {
$("#next").prop("disabled", true);
}
else {
++imag;
runSlideShow(1);
}
});
Any help please.
test my idea =)
var mySlide = function(){
var index = 0;
var timer = false;
var self = this;
self.data = [];
self.start = function(){
timer = setInterval(self.next, 3000);
return self;
};
self.stop = function(){
clearInterval(timer);
timer = false;
return self;
};
self.pause = function(){
if(timer == false){
self.start();
} else {
self.stop();
}
};
self.next = function(){
if(self.data.length > 0){
self.stop().start(); // reset the timer
index++;
self.update();
}
};
self.prev = function(){
if(self.data.length > 0 && index > 0){
self.stop().start(); // reset the timer
index--;
self.update();
}
};
self.update = function(){
var item = self.data[index % self.data.length]; // calculating the value of INDEX
$('.print').fadeOut(1000,function(){
$(this).html(item).fadeIn(1000);
});
};
}
// RUN CODE!
var test = new mySlide();
test.data = [ // LOAD ITEM!
'food',
'bar',
$('<img/>').attr('src','https://www.google.it/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png')
];
test.start().update(); // START!
$('.prev').click(test.prev); // add event!
$('.pause').click(test.pause);
$('.next').click(test.next);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="print"></div>
<input type="button" value="prev" class="prev">
<input type="button" value="pause" class="pause">
<input type="button" value="next" class="next">

Categories