I have a html document where has 3 button and one h1 element. I have tried to change the h1 element content by clicking in each button with EventListener. And i have done this too. But i dont understand how foor loop work there. How exact button working when i am click on them?
//JavaScript Code
var len = document.querySelectorAll(".mybutton").length
for (let i = 0; i < len; i ) {
var doucemnts = document.querySelectorAll("button")[i]
doucemnts.addEventListener("click", function(){
var text = this.innerHTML
document.querySelector("h1").innerHTML= "You Have Selected " text
console.log(i)
})
}
<!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>Document</title>
</head>
<body>
<h1>You have selected no button</h1>
<button >Button 1</button>
<button >Button 2</button>
<button >Button 3</button>
<script src="index.js">
</script>
</body>
</html>
Can Anyone Tell me How For loop worked there?
CodePudding user response:
For in the nodelist attach an event listener that calls a function when the button is clicked. The function updates the h1
with the button text.
Your code can be improved slightly by caching all the elements up front, and then using those references in the loop (a for/of loop is a little easier to parse) instead.
// Cache the elements
const buttons = document.querySelectorAll('.mybutton');
const heading = document.querySelector('h1');
// Loop over `buttons`
for (const button of buttons) {
// For every button add a click listener
button.addEventListener('click', function() {
// Assign the button textContent to a new variable
const text = this.textContent;
// Use that variable to update the textContent
// of the heading textContent
heading.textContent = 'You Have Selected ' text;
});
}
<h1>You Have Selected No Button</h1>
<button >Button 1</button>
<button >Button 2</button>
<button >Button 3</button>
You could even use event delegation. It attaches one listener to a parent element which captures events from its child elements as they "bubble up" the DOM.
// Cache the elements, and a partial string
const heading = document.querySelector('h1');
const buttons = document.querySelector('.buttons');
const tmpl = 'You Have Selected';
// Add an event listener to the buttons container
buttons.addEventListener('click', handleClick);
function handleClick(e) {
// If the child element that fired the
// click event is a button
if (e.target.matches('button')) {
// Construct the new string, and assign it
// to the heading textContent
const text = `${tmpl} ${e.target.textContent}`;
heading.textContent = text;
}
}
<h1>You Have Selected No Button</h1>
<section >
<button>Button 1</button>
<button>Button 2</button>
<button>Button 3</button>
</section>
Additional information
CodePudding user response:
In JS when manipulating DOM elements, it's better to query elements once at start of your code then reuse those variables. Another important thing to consider is to use const
/let
instead of old var
keyword. Here's your updated code based on that and might make more sense now:
const h1 = document.querySelector('h1');
const buttons = document.querySelectorAll('.mybutton');
for (let i = 0; i < buttons.length; i ) {
buttons[i].addEventListener("click", function() {
const text = this.innerHTML;
h1.innerHTML = "You Have Selected " text;
});
}
This code is basically doing the same, but instead of querying for elements on each iteration, it's done once before starting loop. Then loop over the buttons one by one and add click event to each one of them.
You can also use for..of
it might be easier to understand. Here's the code updated to use for..of
:
const h1 = document.querySelector('h1');
const buttons = document.querySelectorAll('.mybutton');
for (const button of buttons) {
button.addEventListener('click', function() {
const text = this.innerHTML;
h1.innerHTML = 'You Have Selected ' text;
});
}
Update: The main thing to understand in both code snippets is const text = this.innerHTML
. This line of code is using the this
keyword to get the HTML content of each button. this
keyword will be pointing to button triggered the event, so based on that you're getting text displayed on that button using innerHTML
property and concatenate that to content of h1. In short, getting text in clicked button and append to h1 content.
I have removed console.log(i)
as it refers to variable i
that is valid only while add the event listener callback only. It'll show an error because when event callback function is called there will be no for loop and i won't be defined.