Button in JavaScript not active / undefined - javascript

I added an event listener to my button and assigned it a variable. However, it is not functioning. The console keeps showing undefined with no code issues at the same time which makes it complex to figure out.
This is the html markup:
<button value="button" id="myBtn">Click to See</button>
Here is the JavaScript declaration for button to call the function "action" on click:
var btn = document.getElementById("myBtn").addEventListener("click", action);
Yet the console shows I got no issues and still shows btn undefined. Don't know how to fix it.
html :
<div>
<h3>ZooMoji</h3>
<img src="moji1.jpg" id="pic1">
<img src="moji2.jpg" id="pic2">
<button value="button" id="myBtn">Click to See</button>
</div>
JS:
var swap1 = document.getElementById("pic1").src;
var swap2 = document.getElementById("pic2").src;
var btn = document.getElementById("myBtn").addEventListener("click", action);
function action() {
if (swap1.endsWith("moji1.jpg") == true) {
swap1.src = swap2;
}
}

It's because you're getting the value of the .addEventListner function and not the actual .getElementById.
Do this instead.
let btn = document.getElementById("myBtn");
btn.addEventListener("click", action);
And also scrap those var's they're old and should in 99.9% of cases be replaced by either const or let if you want it to be mutable.

Actually, the event listener will work fine, and the function action will be executed whenever you click the button, try this:
function action() {
if (swap1.endsWith("moji1.jpg") == true) {
swap1.src = swap2;
}
console.log("the click event is working fine!")
}
The reason why the btn variable is returning undefined is the event listener itself which returns a void, if you are using VS Code try to hover over the btn variable and you would see something like this:
var btn: void
So in order to get an HTMLElement from the btn variable just do that:
var btn = document.getElementById("myBtn"); // returns HTMLElement
btn.addEventListener("click", action); // returns void
function action() {
if (swap1.endsWith("moji1.jpg") == true) {
swap1.src = swap2;
}
}
For more details: EventTarget.addEventListener()

Related

Variable out of scope but in scope

I have a jquery function that adds an event listener to various elements to execute on click. For some reason, when I try to reference a global variable (daySelected) inside the function, it says it is undefined. Am I missing something?
var daySelected = false;
$('.deal-day').bind('click', function(e) {
console.log("Day Selected: " + daySelected);
if (!daySelected) {
if($(this).hasClass('selected-filter')) {
$(this).removeClass('selected-filter');
var daySelected = false;
} else {
$(this).addClass('selected-filter');
var daySelected = true;
}
}
});
You have multiple var daySelected.
var should be defined only once. Otherwise you're creating new scopes.
As a general fix you could improve the code like:
let daySelected = false; // Feel free to change this boolean
const $dealDay = $(".deal-day"); // Get all buttons with that class
const toggleDaySelectedButtons = () => $dealDay.toggleClass("selected-filter", daySelected);
$dealDay.on("click", function(e) {
daySelected = !daySelected; // Toggle boolean
toggleDaySelectedButtons(); // Handle buttons
});
toggleDaySelectedButtons(); // Do on DOM ready
.selected-filter {background: gold;}
<button type="button" class="deal-day">Filter deal day</button>
<hr>
<button type="button" class="deal-day">Filter deal day</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
I really hope you have only one .deal-day button - otherwise the above will not be ideal

Button Doesn't Work If Created Using innerHTML

I have this kind of structure
<button ng-click="something(1)">click!</button>
<div id="place"></div>
something() works in this situation, but if I try to make another button with innerHTML on a js code
str="<button ng-click=\"something(2)\">click 2!</button>"
document.getElementById("place").innerHTML = str;
thrn the 2nd button, the one created by innerHTML, apears normal, but doesn't call the function something() when clicked
Is there a nother way to add the button? the buttons should be generated proceduraly as the page runs
Thank you very much!
<script>
let btn = document.createElement("button");
btn.innerText = "click2"
// class
btn.classList = [];
// on click function
btn.onclick = () => {
}
document.getElementById("place").innerHTML = "";
document.getElementById("place").appendChild(btn)
</script>

Javascript object methods evaluate functions

first of all, I'm new to javascript.
my question is how can I add an event listener to the button and call the function from the myObj script. I tried to google but I don't know what is the keyword for that. thank you
<div id="my-btn"></div>
<script>
myObj.button('my-btn',{
onClick: function() {
alert('Button is clicked !');
},
onCancel: function() {
alert('You cancel the process !');
}
});
</script>
and my object
var myObj = {
button: function(btnId, methods)
{
var btn = document.getElementById(btnId);
for (var method in methods)
{
if (method.toLowerCase() == 'onclick')
{
//btn.addEventListener('click', function(e) {
//}
// i want to add listener
// and call the function "onClick"
}
}
// render button
btn.innerHTML = '<input type="button" value="My Button"></button>';
}
}
thank you for your advice.
Here's one way.
<html>
<head></head>
<body>
<div id="my-btn"></div>
</body>
<script>
const myObj = {
button: (btnId, methods) => {
const btn = document.getElementById(btnId);
for (let method in methods) {
const nameLower = method.toLowerCase();
if (nameLower.startsWith('on')) {
btn.addEventListener(nameLower.substr(2), function(e) {
methods[method]();
});
}
}
// render button
btn.innerHTML = '<input type="button" value="My Button"></button>';
}
};
myObj.button('my-btn',{
onClick: () => alert('Button is clicked !'),
onCancel: () => alert('You cancel the process !')
});
</script>
</html>
We can map the function names to their events by converting to lowercase and stripping off the "on" prefix. So onClick becomes click. You could simplify things by just using the standard event names in your call to myObj.button.
Start by iterating over the functions, map the name and add the event listener. Inside the event listener all we do is call the function provided in the arguments.

Toggle Event Listeners

I am trying to make a function that would allow me to toggle eventListener of an element.
In the example below, I have three buttons: main, on and off. When I click on the on button, the main button becomes functional. After I click off button, the main button should not work anymore (but now it still does).
Now I can achieve a desired behavior by clicking on button for the second time, but I guess it's a bad coincidence and it's not supposed to work that way.
Maybe I should add that I would like to work this out without using jQuery or similar and it needs to be a function, because I am going to use it for a lot of buttons.
(I suspect something with scope causes the problem (clickHandler when calling the function to activate the button is not the same as the clickHandler when calling the function to disable the button), but I can't think of a way to test it.)
// buttons definitions, not important
var mainButton = document.querySelector("#mainButton");
var onButton = document.querySelector("#onButton");
var offButton = document.querySelector("#offButton");
// main function
var toggleButtons = function(toggleVal, button, element) {
var activateButton, clickHandler, disableButton;
// callback function for listener bellow
clickHandler = function() {
document.querySelector(element).classList.toggle("yellow");
};
activateButton = function() {
button.addEventListener("click", clickHandler);
};
disableButton = function() {
button.removeEventListener("click", clickHandler);
};
// when first argument is 1, make the button functional, otherwise disable its functionality
if (toggleVal === 1) {
activateButton();
} else {
disableButton();
}
};
// when onButton is clicked, call main function with arguments
// this works
onButton.addEventListener("click", function() {
toggleButtons(1, mainButton, "body");
});
// this fails to disable the button
offButton.addEventListener("click", function() {
toggleButtons(0, mainButton);
});
.yellow {
background-color: yellow;
}
<button type="button" id="mainButton">mainButton
</button>
<button type="button" id="onButton">onButton
</button>
<button type="button" id="offButton">offButton
</button>
<p>mainButton: toggles background color on click
</p>
<p>onButton: turns on mainButtons's functionality</p>
<p>offButton: supposed to turn off mainButton's functionality</p>
var mainButton = document.querySelector("#mainButton");
var onButton = document.querySelector("#onButton");
var offButon = document.querySelector("#offButton");
var element; // declare the element here and change it from toggleButtons when needed.
function clickHandler() {
document.querySelector(element).classList.toggle('yellow');
}
function activateButton(button) { // You missed this part
button.addEventListener('click', clickHandler);
}
function disableButton(button) { // You missed this part
button.removeEventListener('click', clickHandler);
}
function toggleButtons(value, button) {
if (value === 1) {
activateButton(button); // You missed this part
} else {
disableButton(button); // You missed this part
}
};
onButton.addEventListener('click', function() {
element = 'body'; // you can change it to some other element
toggleButtons(1, mainButton);
});
offButton.addEventListener('click', function() {
element = 'body'; // you can change it to some other element
toggleButtons(0, mainButton);
});
Below code helps to toggle between two functions from an eventListener:
var playmusic=false;
function playSound() {
const audio = document.querySelector(`audio[data-key="${event.keyCode}"]`)
audio.currentTime = 0
audio.play()
playmusic=true;
}
function stopSound() {
const audio = document.querySelector(`audio[data-key="${event.keyCode}"]`)
audio.pause()
playmusic=false;
}
window.addEventListener('keydown',
function(){playmusic?stopSound():playSound()} )

Button's onclick works but JS event listener does not

I have the following button:
<input type="button" class ="anhalteButton" id="StopButton" value="&#9611 &#9611"/>
which I want to execute the following function (viewsLoop is a global variable):
function clearTDLoop(){
clearInterval(viewsLoop);
}
If I call the function via the button's onclick attribute. i.e.:
onclick="clearTDLoop()" it works flawlessly.
However, I would like to call the function through a JS event listener, but that does not work at all. Do you guys have any idea what I might be doing wrong? My Event Listener Code is attached:
var stopButtonEl = document.getElementById("StopButton");
stopButtonEl.addEventListener("click",clearTDLoop);
Sry for the prior confusion, where my code example stated "StartButton" as the button ID, I copied the wrong ID, the problem persists..
It looks like you have the wrong ID for your event listener:
var startButtonEl = document.getElementById("StartButton");
startButtonEl.addEventListener("click",clearTDLoop);
Should be:
var stopButtonEl = document.getElementById("StopButton");
stopButtonEl.addEventListener("click",clearTDLoop);
I've set an example code for you, please check it:
var tdLoop;
var counter = 0;
var startButton = document.getElementById('startButton');
startButton.addEventListener('click', startTDLoop, false);
var stopButton = document.getElementById('stopButton');
stopButton.addEventListener('click', clearTDLoop, false);
var result = document.getElementById('result');
function startTDLoop() {
tdLoop = setInterval(updateValue, 1000);
}
function updateValue() {
counter++;
result.innerHTML = counter;
}
function clearTDLoop() {
counter = 0;
clearTimeout(tdLoop);
}
#result {
padding: 15px 0 0;
}
<input type="button" class ="anhalteButton" id="startButton" value="Start"/>
<input type="button" class ="anhalteButton" id="stopButton" value="Stop"/>
<div id="result"></div>

Categories

Resources