How can I access variable outside event click - javascript

Hi everyone as title says I would like to achieve access to my variable called "Year" outside from my event.
Is that possible?
const ModifyYear = () =>
{
const button = document.querySelector(".button");
let Year = 2022;
button.addEventListener("click", () =>
{
Year = 2023;
})
console.log(Year); //2022
}

Another option is to change your program logic. Here we can use callbacks:
// Your function
const ModifyYear = cb => {
const button = document.querySelector("button");
let Year = 2022;
button.addEventListener("click", () => cb(Year+1));
}
// Call with callback function as parameter
ModifyYear(newYear => console.log(newYear));
<button>Click me</button>

Related

what's the difference in using closure and private class in javascript

const BUTTON = document.querySelector('.clickBtn');
const P = document.querySelector('.click');
const click = (() => {
let click = 0;
return () => ++click;
})();
BUTTON.onclick = () => {
P.textContent = click();
};
const BUTTON2 = document.querySelector('.clickBtn2');
const P2 = document.querySelector('.click2');
class Click {
#click = 0;
click = () => ++this.#click;
}
const c = new Click();
BUTTON2.onclick = () => {
P2.textContent = c.click()
};
<button class="clickBtn">CLOSURE</button>
<p class="click"></p>
<button class="clickBtn2">CLASS</button>
<p class="click2"></p>
say I have a code like above, trying to manage real-time state in vanilla JS and also wanting to hide the actual data from exposing.
I don't need multiple method
nor do I need to copy multiple instances
in case like this, would there be any difference between closure and class except class being slightly more verbose?

Vanilla JS Reusable Dynamic Function taken as a string

I'm trying to make a reusable function that can take in a dynamic "action" for reusability...
In this case, adding the background color is the action.
const button = document.querySelector("#button");
const items = document.querySelectorAll(`*[id^="eventHandlerCreatedItem"]`);
var eventHandler = (refEl, event, focusEls, action) => {
refEl.addEventListener(`${event}`, () => {
focusEls.forEach((focusEl) => {
// focusEl.style.backgroundColor = "orange"; // works
focusEl.`${action}`; // doesn't work
});
});
};
eventHandler(button, "click", items, 'style.backgroundColor = "orange"');
Thanks!
Don't use a string for this. An "action" semantically describes a "function", use a function:
var eventHandler = (refEl, event, focusEls, action) => {
refEl.addEventListener(`${event}`, () => {
focusEls.forEach((focusEl) => {
action(focusEl);
});
});
};
eventHandler(button, "click", items, (el) => el.style.backgroundColor = "orange");

addEventListener returns undefined in Javascript

I want set the addEventListner value to int value,
const stringItem = window.addEventListener("click",(e) => {
const itemTarget = e.target;
const itemParent = itemTarget.parentElement.id;
const strItem = parseInt(itemParent.slice(5));
console.log(strItem);
return strItem;
}, false);
let currentItem = stringItem;
console.log(currentItem);
stringItem return undefined, but I want the strItem to be returned
I want to access the strItem value outside the addEventListener.
How do I do that?
The addEventListener returns undefined as a function (see link). You are passing a function to the addEventListener which gets called whenever you click on the window. The return value of that function will be lost. To be able to use that value outside of the function you will have to do something like this:
let stringItem;
window.addEventListener("click",(e) => {
const itemTarget = e.target;
const itemParent = itemTarget.parentElement.id;
const strItem = parseInt(itemParent.slice(5));
console.log(strItem);
stringItem = strItem;
return strItem;
}, false);
The last two line of your code wouldn't work as they're executed as soon as the eventListener gets added. The currentItem will always be undefined. I would advise you to read more on using callback function in javascript.
The return value of the callback function is discarded. It doesn't make sense to return anything. window.addEventListener doesn't return anything. It doesn't make sense to store the result in a variable stringItem.
You can create a variable outside of the function and store the value in it:
let value = 0;
document.querySelector('#button1').addEventListener("click",(e) => {
++value;
}, false);
document.querySelector('#button2').addEventListener("click",(e) => {
value = 0;
}, false);
document.querySelector('#button3').addEventListener("click",(e) => {
console.log(value);
}, false);
<button id="button1">Increment</button>
<button id="button2">Reset</button>
<button id="button3">Show</button>

React dynamically add html element with event handler

Is it possible to append buttons with event handler in react ?
// This is working fine but its pure javascript onclick , how can I make this element with react js onClick ?
This is reference code , my scenario is appending html code dynamically
const Button = () => {
const dynamicElement = () => {
let li = document.createElement('li');
li.className = 'dynamic-link'; // Class name
li.innerHTML = "I am New"; // Text inside
document.getElementById('links').appendChild(li);
li.onclick = function(){ alert(0) }
}
useEffect(() => {
dynamicElement();
}, [])
}
You can just convert your function to a functional component like this.
const DynamicElement = () => {
return (
<li onClick={()=>alert(0)} className="dynamic-link">I am New</li>
)
}
const Button = () => {
const [visible, setVisible] = useState(false);
useEffect(()=>setVisible(true), [])
// if visible is true return <DynamicElement/>, either way return null
return visible ? <DynamicElement/> : null
}
BTW useState is hooks implementation of a state

Override a function already attached to an event

I want to override a function already attached to an event. Like that :
let orFn = () => {
console.log('old');
};
buttonEl.addEventListener('click', orFn);
orFn = () => {
console.log('new');
};
However, when I click on the button, the old function is still called.
I have seen this stackoverflow. I can't use a function wrapper in my case. And I want to understand why this is not working.
My code is available for testing here: jsfiddle.
One way is to remove first listener, then add another one
let orFn = () => {
console.log('old');
};
let orFnNew = () => {
console.log('new');
};
var buttonEl = document.querySelector('button')
buttonEl.addEventListener('click', orFn);
// remove old listener
buttonEl.removeEventListener('click', orFn);
// add another one
buttonEl.addEventListener('click', orFnNew);
<button>button</button>
Another way is to have one listener, that may call different functions inside. Example:
// button
const buttonEl = document.querySelector('button')
const orFn = () => {
console.log('old');
};
const orFnNew = () => {
console.log('new');
};
// function that will be called
let functionToCall = orFn;
buttonEl.addEventListener('click', (event) => { // single listener
functionToCall.call(event); // call a function with event
functionToCall = functionToCall === orFn ? orFnNew : orFn; // change function to be called
});
<button>button</button>
One way of using bind().
const btn = document.getElementById('btn');
let orFn = () => {
alert('old');
};
orFn = () => {
alert('new');
};
orFn.bind(orFn)
btn.addEventListener('click', orFn);
This will bind with new function and show new in alert Popup.

Categories

Resources