I can't nake Reset Button - javascript

I need to make reset button which makes Resetting Scores. Can anyone help me?
I tried all my best but I don't know how to make it.
https://github.com/SandroGamrekelashvili/New-folder
const game = () => {
let pScore = 0;
let cScore = 0;
});
const startGame = () => {
const playBtn = document.querySelector(".intro button");
const introScreen = document.querySelector(".intro");
const match = document.querySelector(".match");

There were a few things you needed to get done to make the reset work.
1.) Assign reset button element to a const.
2.) Move your score elements to parent scope.
const game = () => {
let pScore = 0;
let cScore = 0;
const resetBtn = gameContainer.querySelector("button.startOver");
const playerScore = document.querySelector(".player-score p");
const computerScore = document.querySelector(".computer-score p");
// The rest of your code...
2.) Attach event listener to reset button.
const startGame = () => {
playBtn.addEventListener("click", () => {
introScreen.classList.add("fadeOut");
match.classList.add("fadeIn");
});
resetBtn.addEventListener("click", () => {
playerScore.innerText = '0';
computerScore.innerText = '0';
pScore = cScore = 0;
});
};
Here is a JSFiddle with a working example.

I think what you need to solve your problem is very well explained in this other questions here.
The idea is that instead of declaring your variable inside your main function, you would create a variable that refer to your functions related to your score outside of it that can then be called when you need it. To avoid global conflict, you would have that function return an object with functions inside for getters and setters. In your case, I would do something like this:
const scoreModule = () => {
let pScore = 0;
let cScore = 0;
return {
getPScore: () => pScore,
getCScore: () => cScore,
setPScore: value => pScore = value,
setCScore: value => cScore = value,
}
}
Because you defined the scoreModule as a global object, you can then use it wherever you want. And, because you returned only getters and setters (not the actual value, but rather a mean to get or change them) your object is protected and you avoid the bad practice of globally available variables. Then in any of your other functions, when you want to use them either to get or set them, you simply:
const game = () => {
// To get a score
const currentPScore = scoreModule().getPScore()
// To set a score
scoreModule().setPScore(newScore)
});

Related

events with addEventListener

I'm tried to something like : Catch all events in my addEventListeners and then call my function calculateBill. I have a problem my events are lost. It is possible to pass the parameters for each addeventlister separately. I try to do it since few hours and i have no idea what's happening here.
const billInput = document.querySelector('#bill');
const percentageButton = document.querySelectorAll('.tip__values--item');
const numberOfPeople = document.querySelector('#people');
const tipAmount = document.querySelector('.result__amount--price');
const totalBill = document.querySelector('.result__total--price');
const reset = document.querySelector('button');
const catchBill = (e) => {
return e.target.value;
};
const catchPeople = (e) => {
return e.target.value;
};
const handleButtons = (e) => {
return e.target.textContent;
};
const calculateBill = (catchBill, catchPeople, handleButtons) => {
console.log(
'catchBill:',
catchBill,
'catchPeople:',
catchPeople,
'handleButtons:',
handleButtons
);
};
billInput.addEventListener('keyup', function (e) {
calculateBill(catchBill(e), catchPeople, handleButtons);
});
numberOfPeople.addEventListener('keyup', function (e) {
calculateBill(catchBill, catchPeople(e), handleButtons);
});
percentageButton.forEach((btn) => {
btn.addEventListener('click', function (e) {
calculateBill(catchBill, catchPeople, handleButtons(e));
});
});
I know that i can do this FrontedMentor challenge in other way but I'd like to know is this possible to do it that way. I know that problem is with parameters that i call in addeventlistener. How can i get my parameters in my calculateBill function with all events?
You'll need to cache the result of each event somewhere so that you can retrieve them later, or retrieve the value in every input each time any event takes place. It looks like calculateBill expects arguments to be strings, not functions, so passing catchBill, catchPeople, or handleButtons (which are functions) to it doesn't make sense. Consider something like:
// assign default values here if you want
let billValue;
let numPeople;
let percValue;
const handleBillChange = (e) => {
billValue = e.target.valueAsNumber;
calculateBill();
};
const handlePeopleChange = (e) => {
numPeople = e.target.valueAsNumber;
calculateBill();
};
const handlePercentageChange = (e) => {
percValue = e.target.textContent;
calculateBill();
};
billInput.addEventListener('keyup', handleBillChange);
numberOfPeople.addEventListener('keyup', handlePeopleChange);
billInput.addEventListener('keyup', handleBillChange);
// This is a NodeList, not a button. Consider naming the variable more precisely.
// percentageButtons, perhaps?
percentageButton.forEach((btn) => {
btn.addEventListener('click', handlePercentageChange);
});
While it'd be technically possible to store the previous events instead, and then do something like
billInput.addEventListener('keyup', function (e) {
calculateBill(catchBill(e), catchPeople(previousPeopleEvent), handleButtons(previousButtonEvent));
});
for all the inputs and buttons, that'd be extremely strange. Better to store just the values.

Dynamic Function Watcher in JS

I'm working on a pet project, a little front-end library for students. It reads variables/code in a JS file and tests it, outputting some panels. The code itself roughly follows the Jest framework.
My problem is that I'm trying to create a function that watches the execution of other functions, counts them, and lets me access the count.
function watchFunction(funcName){
let originalFunction = window[funcName];
let counter = 0;
// Wrap the function, counts when called
window[funcName] = function(...args){
console.log("watching");
counter++;
return originalFunction(...args);
}
return {
getCount: () => {return counter},
reset: () => {
// Unwrap the function
window[funcName] = originalFunction
}
}
}
This seems to work for methods like Number() or parseInt(), but I don't know how I would go about accessing methods like Math.floor(), or prototype methods like Array.prototype.map().
I've tried passing in the function reference instead of using window["funcNameString"], but that doesn't seem to work.
Does anyone have suggestions or tips for wrapping functions or watching functions like this?
EDIT:
It appears a solution was found!
function watchFunction(obj, fName) {
let counter = 0;
const originalFunction = obj[fName];
obj[fName] = (...args) => {
counter++;
return originalFunction.bind(obj)(...args);
};
return {
removeWatcher: () => (obj[fName] = originalFunction),
resetCount: () => (counter = 0),
getCount: () => counter,
};
}
Example of use:
// Array.prototype.push
const arrayPushWatcher = watchFunction(Array.prototype, "push");
let arr = [];
// 0
console.log("Array.prototype.push", arrayPushWatcher.getCount());
arr.push(1);
// 1
console.log("Array.prototype.push", arrayPushWatcher.getCount());
arr.push(1);
// 2
console.log("Array.prototype.push", arrayPushWatcher.getCount());
arrayPushWatcher.removeWatcher();
arr.push(1);
// 2 (stopped counting)
console.log("Array.prototype.push", arrayPushWatcher.getCount());
How to watch for any function call
Is that what you want? I can also write a block for this function so that it determines whether an object has been passed in or a string. If string -> run this function on window as a property "objectThatStoresFunction".
I've tried playing around with the Function.prototype, but it doesn't really work. So the function turned out a bit more complex.
This code below works both with functions / objects on window Array.prototype.map (Prototype / Class functions)
function watchFunction(objectThatStoresFunction, functionName) {
let counter = 0;
const originalFunction = objectThatStoresFunction[functionName];
objectThatStoresFunction[functionName] = (...args) => {
counter += 1;
return originalFunction(...args);
}
return {
getCount: () => {
return counter
}
}
}
const mathRoundWatcher = watchFunction(Math, 'round');
// 0
console.log(mathRoundWatcher.getCount());
// 1
Math.round(99666.9999999);
console.log(mathRoundWatcher.getCount());
// 2
Math.round(999999999.99);
console.log(mathRoundWatcher.getCount());
function watchFunction(objectThatStoresFunction, functionName, optionalOriginalFunction) {
const self = this;
if (optionalOriginalFunction) {
objectThatStoresFunction = this.window;
functionName = optionalOriginalFunction.name;
}
let counter = 0;
const originalFunction = objectThatStoresFunction[functionName] || optionalOriginalFunction;
objectThatStoresFunction[functionName] = (...args) => {
counter += 1;
return originalFunction.bind(self)(...args);
}
return {
// should it remove the watcher or reset the count?
reset: () => objectThatStoresFunction[functionName] = originalFunction,
getCount: () => {
return counter;
}
}
}
const arrayMapWatcher = watchFunction(Array.prototype, 'map');
// 0
console.log('Array.prototype.map', arrayMapWatcher.getCount());
[-99].map(() => {});
// 1
console.log('Array.prototype.map', arrayMapWatcher.getCount());
const mathRoundWatcher = watchFunction(Math, 'round');
// 0
console.log('Math.round', mathRoundWatcher.getCount());
// 1
Math.round(99666.9999999);
console.log('Math.round', mathRoundWatcher.getCount());
// 2
Math.round(999999999.99);
console.log('Math.round', mathRoundWatcher.getCount());
const alertWatcher = watchFunction(null, null, window.alert);
// 0
console.log('window.alert', alertWatcher.getCount());
// 1
window.alert('1');
console.log('window.alert', alertWatcher.getCount());
// 2
alert('2')
console.log('window.alert', alertWatcher.getCount());
// reset the alertWatcher counter
alertWatcher.reset();
This code above breaks the stacksnippets.com when used with Array.prototype.map for some reason, please see this JsFiddle link:
https://jsfiddle.net/ctbjnawz/3/
Do you mean a method of an instance or object? One way is to create a new function. e.g
function WatchInstanceMethods(instance, functionName){
let originalFunction = window[instance][funcName];
let counter = 0;
window[instance][functionName] = function(...args){
console.log("watching");
counter++;
return originalFunction(...args);
}
return {
getCount: () => {return counter},
reset: () => {
// Unwrap the function
window[funcName] = originalFunction
}
}
}
although adding support for chaining methods will get difficult with more nested methods but you can pass a string for functionName name and split it to have each layer of calling instance for function and repeat the logic above.

Access data from inside a function in the global scope

I'm still learning JS and I'm currently struggling with this problem. I want to be able to access the data from ordArray in the global scope. How do I do this ? I've tried with returns but struggling to solve it.
const startOrd = function() {
const ordArray = [];
val = document.getElementById("val_ord").value;
ordArray.push(val)
console.log(ordArray)
}
Simply create ordArray outside of the function :)
const ordArray = [];
const startOrd = function () {
val = document.getElementById("val_ord").value;
ordArray.push(val)
console.log(ordArray)
}
Declare/initialize the array outside of the function.
const ordArray = [];
const startOrd = function() {
val = document.getElementById("val_ord").value;
ordArray.push(val)
console.log(ordArray)
}
Your code looks correct, Only thing you want is I've tried with returns but struggling to solve it
Demo :
const startOrd = function() {
const ordArray = [];
const val = document.getElementById("val_ord").value;
ordArray.push(val)
return ordArray;
};
console.log(startOrd());
<input type="text" id="val_ord" value="abcd"/>
Constants are block-scoped, when you create variable in function you dont access to variable out side the function.
please follow the link
I think, This writing code method is more better:
var ordArray = [];
let startOrd = (elem) => elem?.value;
let targetElem = document.getElementById("val_ord");
ordArray.push(startOrd(targetElem));

Button to delete a grid of squares only works once - Node.removeChild: The node to be removed is not a child of this node

I am doing an etch-a-sketch project and so far it has gone well. I wanted to challenge myself by making a button to "destroy" the new grid that I create with another button.
The problem is the button only works once, then throws the error: Node.removeChild: The node to be removed is not a child of this node**
I solved this after trial and error, by moving my const variable out of the global scope and inside the destroyBtn function. The problem is I don't know why it works. If it's in the global scope, shouldn't querySelectorAll('.grid') always be accessible / targetting a newly created grid?? Thanks for your time.
This works:
const containerBtn = document.querySelector('.container')
const destroyBtn = document.querySelector('#destroybtn')
destroyBtn.addEventListener('click', () => {
const targetSquares = document.querySelectorAll('.grid') // moved inside function
for (let i = 0; i < targetSquares.length; i++) {
containerBtn.removeChild(targetSquares[i])
}
})
This does not:
const containerBtn = document.querySelector('.container')
const destroyBtn = document.querySelector('#destroybtn')
const targetSquares = document.querySelectorAll('.grid') // in global scope
destroyBtn.addEventListener('click', () => {
for (let i = 0; i < targetSquares.length; i++) {
containerBtn.removeChild(targetSquares[i])
}
})

JS HTML CSS: how to make a function dynamically repeat with different variables each time while not repeating the same variables inside de function

Intertwining Functions
I've been trying to make functions different but both have have the same original function.
Here are my selectors:
const popControl = document.getElementById("pop");
const popHeader = document.getElementById("header");
const popButton = document.getElementById("close");
const popTitle = document.getElementById("title");
const popBody = document.getElementById("body");
const popControl2 = document.getElementById("pop2");
const popHeader2 = document.getElementById("header2");
const popButton2 = document.getElementById("close2");
const popTitle2 = document.getElementById("title2");
const popBody2 = document.getElementById("body2");`
With all my id's selected, I create my first function, called verifyPosition:
function verifyPosition(circleLeftPosition, circleRightPosition, moveBy) {
console.log(circleLeftPosition, circleRightPosition);
if (circleLeftPosition == "550px" && circleRightPosition == "75px") {
popButton.addEventListener("click", closePosition);
openPosition();
}
}
Now, I must create the other, malfunctioning func, verifyPosition2:
function verifyPosition2(circleLeftPosition, circleRightPosition, moveBy) {
console.log(circleLeftPosition, circleRightPosition);
if (circleLeftPosition == "550px" && circleRightPosition == "75px") {
popButton2.addEventListener("click", closePosition2);
openPosition2();
}
}
For some reason, my verifyPosition2 does not work, and it does not matter what you put in it.
This brings me to my final questions:
Why is it not working?
And how can I make it work?
Thanks and thanks all!
Hint: [!ch.edit] tag means I have edited this question.
You may try the below approach
function verifyPosition(circleLeftPosition, circleRightPosition, moveBy, selector_extension) {
if (circleLeftPosition == "550px" && circleRightPosition == "75px") {
const popButton = document.getElementById("close" + selector_extension);
// Checkout the below code, if verifyPosition is called multiple times on same element, there is chance of setting multiple click events on popButton
popButton.addEventListener("click", function (e) { return closePosition(e, selector_extension); });
openPosition(selector_extension);
}
}
function closePosition(e, selector_extension) {
// access the required elements using `selector_extension`
}
function openPosition(selector_extension) {
// access the required elements using `selector_extension`
}

Categories