I have three HTML buttons with ids and classes. Two of them also hold data attributes.
The data attributes are for the element they should change the style display property for.
The basic idea is to show or hide paragraph elements. I am trying to reduce repetitive code by using querySelectors and for loops instead of having multiple event listeners. I am stuck at writing the function that starts on line 31 of the codepen. I have tried: document.querySelector(classbtns[i].getAttribute('data-value')).style.display = "inline"; and I am getting: TypeError: document.querySelector(...) is null
I have retained and mented out earlier code-blocks to help give you an idea of what I am trying to do.
Please see my code and link to the codepen below:
html:
<p id="toy-pictures-latest" class="panel">Latest Toy Pictures</p><br>
<p id="toy-pictures-greatest" class="panel">Greatest Toy Pictures</p>
Toy Pictures
<button type="button" id="btnlatest" data-value="toy-pictures-latest" class="buttons">Latest</button>
<button type="button" id="btngreatest" data-value="toy-pictures-greatest class="buttons">Greatest</button></details></li>
<button type="button" id="clear-btn">Clear</button>
css:
#toy-pictures-latest.panel{
display: inline;
}
#toy-pictures-greatest.panel{
display: inline;
}
js:
/*function fgreatest() {
document.getElementById('toy-pictures-greatest').style.display = "inline";
}*/
//The following function clears the p elements in class "panel" by changing the display value in css
function clearall()
{
var panels = document.querySelectorAll('.panel'), i;
console.log("exe");
for (i = 0; i < panels.length; ++i) {
panels[i].style.display = "none";
}
}
//This is the previous version of the querySelector.
//It required a new function for each <p> element id
/*const classbtns = document.querySelectorAll(".buttons");
for (let i = 0; i < classbtns.length; i++) {
classbtns[i].addEventListener("click", fgreatest);
}*/
//This is the attempt to grab the name of the element
//from the html data value property and change the css //style display to inline
const classbtns = document.querySelectorAll(".buttons");
for (let i = 0; i < classbtns.length; i++) {
classbtns[i].addEventListener("click", function() {
document.querySelector(classbtns[i].getAttribute('data-value')).style.display = "inline";
});
}
document.getElementById('clear-btn').addEventListener("click", clearall);
codepen
I have three HTML buttons with ids and classes. Two of them also hold data attributes.
The data attributes are for the element they should change the style display property for.
The basic idea is to show or hide paragraph elements. I am trying to reduce repetitive code by using querySelectors and for loops instead of having multiple event listeners. I am stuck at writing the function that starts on line 31 of the codepen. I have tried: document.querySelector(classbtns[i].getAttribute('data-value')).style.display = "inline"; and I am getting: TypeError: document.querySelector(...) is null
I have retained and mented out earlier code-blocks to help give you an idea of what I am trying to do.
Please see my code and link to the codepen below:
html:
<p id="toy-pictures-latest" class="panel">Latest Toy Pictures</p><br>
<p id="toy-pictures-greatest" class="panel">Greatest Toy Pictures</p>
Toy Pictures
<button type="button" id="btnlatest" data-value="toy-pictures-latest" class="buttons">Latest</button>
<button type="button" id="btngreatest" data-value="toy-pictures-greatest class="buttons">Greatest</button></details></li>
<button type="button" id="clear-btn">Clear</button>
css:
#toy-pictures-latest.panel{
display: inline;
}
#toy-pictures-greatest.panel{
display: inline;
}
js:
/*function fgreatest() {
document.getElementById('toy-pictures-greatest').style.display = "inline";
}*/
//The following function clears the p elements in class "panel" by changing the display value in css
function clearall()
{
var panels = document.querySelectorAll('.panel'), i;
console.log("exe");
for (i = 0; i < panels.length; ++i) {
panels[i].style.display = "none";
}
}
//This is the previous version of the querySelector.
//It required a new function for each <p> element id
/*const classbtns = document.querySelectorAll(".buttons");
for (let i = 0; i < classbtns.length; i++) {
classbtns[i].addEventListener("click", fgreatest);
}*/
//This is the attempt to grab the name of the element
//from the html data value property and change the css //style display to inline
const classbtns = document.querySelectorAll(".buttons");
for (let i = 0; i < classbtns.length; i++) {
classbtns[i].addEventListener("click", function() {
document.querySelector(classbtns[i].getAttribute('data-value')).style.display = "inline";
});
}
document.getElementById('clear-btn').addEventListener("click", clearall);
codepen
Share Improve this question edited Sep 13, 2020 at 6:53 Always Helping 14.6k4 gold badges15 silver badges30 bronze badges asked Sep 13, 2020 at 5:41 castoncaston 1591 silver badge16 bronze badges4 Answers
Reset to default 3I found two issues:
In HTML, data-value tag for button "btngreatest" is missing end quote.
<button type="button" id="btngreatest" data-value="toy-pictures-greatest class="buttons">
Since you want to select panels by ID, you should prefix with '#'
document.querySelector('#'+ classbtns[i].getAttribute('data-value')).style.display = "inline";
When selecting an element by Id with document.querySelector you need to preface with "#" so that would be:
document.querySelector('#' + classbtns[i].getAttribute('data-value')).style.display = "inline";
});
But then you might as well just use
document.getElementById(classbtns[i].getAttribute('data-value')).style.display = "inline";
Just as an additive to the solutions already it may be worth taking into consideration the good old MDN on getting the data attribute:
[...], but the standard defines a simpler way: a DOMStringmap you can read out via a dataset property. https://developer.mozilla/en-US/docs/Learn/HTML/Howto/Use_data_attributes
I personally would also go for the target of of the event. Something like:
const attachListener = btn => btn.addEventListener('click', (e) => document.getElementById(e.target.dataset.value).style.display = 'inline';
clsBtns.forEach(attachListener);
Here is a more current and simplified clean approach by using forEach
method and targeting the actual element we have clicked on using event.target
method
Event.target will ensure you are targeting the correct element to get its data-value
- This approach is better if you have alot of buttons and nested inside each other.
You can also use newly dataset
approach as well instead of using the getAtribute
method
Using data.set
document.querySelector("#" + e.target.dataset.value).style.display = "inline";
Live Demo:
function clearall() {
var panels = document.querySelectorAll('.panel')
panels.forEach(function(el) {
el.style.display = "none";
});
}
const classbtns = document.querySelectorAll(".buttons");
classbtns.forEach(function(btn) {
btn.addEventListener("click", function(e) {
document.querySelector("#" + e.target.getAttribute('data-value')).style.display = "inline";
})
})
//clear al;
document.getElementById('clear-btn').addEventListener("click", clearall);
#toy-pictures-latest.panel {
display: none;
}
#toy-pictures-greatest.panel {
display: none;
}
<p id="toy-pictures-latest" class="panel">Latest Toy Pictures</p><br>
<p id="toy-pictures-greatest" class="panel">Greatest Toy Pictures</p>
<br>
Toy Pictures
<button type="button" id="btnlatest" data-value="toy-pictures-latest" class="buttons">Latest</button>
<button type="button" id="btngreatest" data-value="toy-pictures-greatest" class="buttons">Greatest</button>
<button type="button" id="clear-btn">Clear</button>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745176512a4615217.html
评论列表(0条)