Assign event handlers to dynamically created buttons - javascript

I am trying to assign a click event handler to dynamically created buttons that once clicked, will return the ID of the clicked button in vanilla Javascript without any frameworks. Yet I can't seem to get the events to handle properly, here's the code
let h = document.getElementsByClassName("buttons");
h.forEach(function() {
addEventListener("click", function() {
alert(this.id);
});
};

Try
let h = document.getElementsByClassName("buttons");
[...h].forEach(b => {
b.addEventListener("click", () => {
alert(b.id);
});
});
<button id="btn-id-1" class="buttons">Btn 1</button>
<button id="btn-id-2" class="buttons">Btn 2</button>
<button id="btn-id-3" class="buttons">Btn 3</button>

The method document.getElementsByClassName() returns and HTMLCollection wich is an array-like object (but not an array), so you can't use forEach() on it to iterate over his elemtents. Instead, you can use a for loop:
let h = document.getElementsByClassName("buttons");
for (let i = 0; i < h.length; i++)
{
h[i].addEventListener("click", function()
{
alert(this.id);
});
}
<button id="id1" class="buttons">BUTTON 1</button>
<button id="id2" class="buttons">BUTTON 2</button>
Alternatively, you can spread his element on an array, and then use forEach() on it:
let h = document.getElementsByClassName("buttons");
[...h].forEach(function(btn)
{
btn.addEventListener("click", function()
{
alert(this.id);
});
});
<button id="id1" class="buttons">BUTTON 1</button>
<button id="id2" class="buttons">BUTTON 2</button>

let h = document.getElementsByClassName("buttons");
h.forEach(function(element) {
element.addEventListener("click", function() {
alert("Hello");
});
};

Related

Element that calls the function JS

Could someone say how to select and element that called current function?
function Myfunc() {
element.style.padding = '16px';
}
//---
<button onclick="Myfunc()">Click Me!</button>
I ask how to do it without giving an id or class to the element, and without:
function Myfunc(this) { }
You can explicitly pass the element as the argument of the function, you can refer to the event object, or you can inline the code (this last one is not a good option but it works nonetheless):
function clickFunc1(element) {
element.style.padding = '16px'
}
function clickFunc2() {
event.target.style.padding = '16px'
}
<button onclick="clickFunc1(this)">ClickMe 1</button>
<button onclick="clickFunc2()">ClickMe 2</button>
<button onclick="this.style.padding = '16px'">ClickMe 3</button>
You can use it like this:
function Myfunc(element) {
element.style.padding = '16px';
}
<button onclick="Myfunc(this)">Click Me!</button>
Use this.style.padding:
function Myfunc(element) {
element.style.padding = '16px';
}
<button onclick="Myfunc(this)">Click Me!</button>
<button onclick="Myfunc(this)">Click Me 2!</button>
<button onclick="this.style.padding = '16px'">Click Me Without function!</button>
Method 1
function foo(target){
target.style.padding = '16px';
}
<button onclick="foo(this)">Click me!</button>
Method 2 (Better)
document.querySelector("button").addEventListener("click", function(event){
const element = event.target;
element.style.padding = '16px';
});
<button>Click me!</button>
You can go with event.
<button onclick="Myfunc(event)">Click Me!</button>
Then e.target is you clicked element.
function Myfunc(e) {
e.target.style.padding = '16px';
}
JSFiddle

How can I show and hide a button after click?

I tried this:
<button onclick="button_onclick()">Click me</button>
js:
button_onclick() = "this.style.visibility = 'hidden';"
You have a spelling error in visibility and this is not how you define functions in javascript.
You also need to pass down the element reference down as a parameter of the function.
function button_onclick(element) {
element.style.visibility = 'hidden';
}
<button onclick="button_onclick(this)">Click me</button>
OR with inline js:
<button onclick="this.style.visibility = 'hidden'">Click me</button>
There are three problems:
you're calling button_onclick() as a function but it's not defined as one.
using inline onclick is no good
you've misspelled visibality. You should use visibility instead.
If you want to handle events. the best way is to attach an event listener to the element.
const myButton = document.querySelector('.my-button')
myButton.addEventListener('click', () => {
myButton.style.visibility = 'hidden'
})
<button class="my-button">Click me</button>
Easest way of doing
<button onclick="this.style.display = 'none'">Click me</button>
Note this way of doing is not a good practice
So do it in this way
<button id="btn"> Click me </button>
<script>
const btn = document.querySelector ('#btn');
btn.addEventListener ('click', () =>{
btn.style.display = "none"
// btn.style.visibility = "hidden"
})
</script>
Thank you
try this
function button_onclick() {
document.getElementById("btn").style.visibility="hidden";
}
<button id="btn" onclick="button_onclick()">Click me</button>

addEventListener for loop doesn't respond

Please don't make it Duplicate, I just want to understand If I wrote my code wrong, All thought I checked it couple of times.
I can't understand way my code dosen't work.
Js:
var p1button = document.querySelector("#p1");
var p2button = document.getElementById("p1");
//p1 btn
for(var i = 0; i < p1button.length; i++){
  p1button[i].addEventListener("click", function(){
alert("clicked") });
 };
html:
   
<button id="p1">Player One</button>
   <button id="p2">Player Two</button>
My codepen
It doesn't work because p1button is already an ElementButton, not an Array where you have to use [0] to get the element from.
var p1button = document.querySelector("#p1");
p1button.addEventListener("click", function(){
alert("clicked")
});
<button id="p1">Player One</button>
whereas, is you had multiple class .btn elements your code would make sense, since .getElementsByClassName or .querySelectorAll do actually return an array-like NodeList:
function doThaChng () {
alert("clicked!");
}
var btn = document.querySelectorAll(".btn");
for(var i=0; i<btn.length; i++) {
btn[i].addEventListener("click", doThaChng);
}
<button class="btn">Player One</button>
<button class="btn">Player Two</button>
Or in ES6
const btn = document.querySelectorAll(".btn");
const doThaChng = () => alert("Clicked");
[...btn].forEach(el => el.addEventListener("click", doThaChng) );
<button class="btn">Player One</button>
<button class="btn">Player Two</button>
p1button is not an array but a DOM element.
Try keeping just:
p1button.addEventListener("click", function(){
alert("clicked")
});
From the documentation of querySelector():
The Document method querySelector() returns the first Element within the document that matches the specified selector, or group of selectors. If no matches are found, null is returned.
Try it out (open up Developer Tools to see the console):
console.log(document.querySelector("button"));
So you don't need (and you can not) iterate over p1button, because it's a node instead of an array.
It's because querySelector and getElementById returns a single DOM element and not an array of DOM elements. So your for loop is useless and try to add an event listener on an undefined value.
Here is a correct way to listen for click event
var p1button = document.querySelector("#p1");
p1button.addEventListener("click", function(){
alert("clicked")
});
Here you can find more infos about querySelector and getElementById.

combining multiple javascript var into one function

I know absolutely nothing about js but I stumbled on this and was wondering if someone could help me combine these two into one. I will probably end up having about 30 of them. is it possible for all 30 vars to be combined? each customPush will push a new html.
Thank you.
var customPush1 = function (event) {
myNavigator.pushPage('pageNav2.html', { data: { cardTitle:
event.target.textContent } })
};
var customPush2 = function (event) {
myNavigator.pushPage('pageNav3.html', { data: { cardTitle: event.target.textContent } })
};
yes. the plan is to have 30 buttons loading a separate html each
In this case, I'd do it a different way, rather than creating lots of functions, I would add some data-attributes to the buttons, and use delegated events.
But if you want to make it so that you can share code between functions. You can create a function that returns a function, and use closures to pass parameters. Below is an example.
function makePush(url) {
return function (event) {
myNavigator.pushPage(url, { data: { cardTitle:
event.target.textContent } })
}
}
var
customPush1 = makePush('pageNav2.html'),
customPush2 = makePush('pageNav3.html');
And here is an example of using delegated events on the buttons. It's uses jQuery as I find it quick and easy, but the same can be done without jQuery.
$('body').on('click', '[data-custom-push]', function () {
var page = $(this).attr('data-custom-push');
alert('Page = ' + page);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-custom-push="pageNav1.html">Button 1</button> <br>
<button data-custom-push="pageNav2.html">Button 2</button> <br>
<button data-custom-push="pageNav3.html">Button 3</button> <br>
<button data-custom-push="pageNav4.html">Button 4</button> <br>
<button data-custom-push="pageNav5.html">Button 5</button> <br>
<button data-custom-push="xyz.html">Button 6</button> <br>
<button data-custom-push="abc.html">Button 7</button> <br>

Get element from which onclick function is called

I have a button with a onclick attribute which is pointing to the function test().
<button onclick="test()">Button 1</button>
<button onclick="test()">Button 2</button>
<button onclick="test()">Button 3</button>
Function test():
function test()
{
var button_name = this.html;
console.log("Im button "+ button_name);
}
How can I get informations about the clicked button?
e.g. How can i read the html?
jsfiddle: https://jsfiddle.net/c2sc9j9e/
Pass the this reference to the function, then read textContent property the text content of the node.
HTML
<button onclick="test(this)">Button 1</button>
Script
function test(clickedElement){
var button_name = clickedElement.textContent;
}
Fiddle
Four options:
Pass this into the function.
<button onclick="test(this)">Button 1</button>
and then use that argument in the function.
Hook up the handlers with addEventListener or jQuery's on, and then use this within the handler.
var buttons = document.querySelectorAll("selector-for-the-buttons");
Array.prototype.forEach.call(buttons, function(btn) {
btn.addEventListener("click", handler, false);
});
function handler() {
// Use `this` here
}
jQuery version:
$("selector-for-the-buttons").on("click", function() {
// Use `this` here
});
Hook up a single handler on a container these buttons are in, and use the target property of the event object to determine which was clicked (but note that if you use other elements within button, you'll need to loop up to the button first).
document.querySelector("selector-for-the-container").addEventListener("click", function(e) {
// Use `e.target` here
}, false);
jQuery version that handles the possibility of nested elements within the button for you:
$("selector-for-the-container").on("click", "button", function() {
// Use `this` here (note this is different from the DOM version above)
});
I came across an other extremely simple way to do it in Vanilla JS so I post it here for reference:
function whoami () {
var caller = event.target;
alert("I'm " + caller.textContent);
}
<button onclick="whoami()">Button 1</button>
<button onclick="whoami()">Button 2</button>
<button onclick="whoami()">Button 3</button>
I'm not sure about the browser support for it but it works at least on Safari, Firefox and Blink based browsers.
function test(button)
{
var button_name = button.getAttribute('name');
console.log("Im button "+ button_name);
}
<button onclick="test(this)" name="button1">Button 1</button>
<button onclick="test(this)" name="button2">Button 2</button>
<button onclick="test(this)" name="button3">Button 3</button>
If you want to use Jquery, then you can call the $(this) object in the function.
you must pass "this" to function
<button onclick="test(this)">1</button>
<button onclick="test(this)">2</button>
<button onclick="test(this)">3</button>
<script>
function test(t)
{
console.log(t);
}
</script>
Here is your solution jsfiddle , using jquery.
<button onclick="test(this)">1</button>
<button onclick="test(this)">2</button>
<button onclick="test(this)">3</button>
<script>
function test(button)
{
var button_name = $(button).html();
alert("Im button "+ button_name);
}
</script>
just add id to each button and pass it to your test function
and here is working jsfiddle
<button onclick="test(this.id)" id="button1">1</button>
<button onclick="test(this.id)" id="button2">2</button>
<button onclick="test(this.id)" id="button3">3</button>
<script>
function test(id)
{
var button_name = id;
alert("Im button name is : "+ button_name);
console.log("Im button name is :"+ button_name);
}
</script>
What you want is the event that triggers the click, and you do that by specifying the function call as MyFunction(event). For example:
<ul>
<li onclick="MyFunction(event)">Red</li>
<li onclick="MyFunction(event)">Orange</li>
<li onclick="MyFunction(event)">Yellow</li>
</ul>
and then your Javascript function can be:
function MyFunction(ev) {
// Now you have access to everything in the event
//- including the triggering element
var element = ev.srcElement;
}
By leaving out the (event) parameter in the specification of the onclick function call you don't get it.

Categories