Home > database >  Multiple declaration of Id for getElementById - how to automate?
Multiple declaration of Id for getElementById - how to automate?

Time:12-03

I have such a small javascript code (I use it in Markdown):

<button title="Click to show answer" type="button" class="btn btn-primary"
   onclick="if(document.getElementById('spoiler') .style.display=='none')
              {document.getElementById('spoiler') .style.display=''}
            else{document.getElementById('spoiler') .style.display='none'}">
  show/hide
</button><div id="spoiler" style="display:none">
***

Hidden Text

***
</div>

The problem is that if I want to make several buttons on one page to hide the text, then I need to rename spoiler to spoilerN 4 times

Questions:

  1. (Minimum) Is it possible to compactly output Id to a separate variable in this piece of code?

  2. (Maximum) Is it possible to automatically generate a variable? So that the code itself reuses the variable every time a new button is declared?

CodePudding user response:

You would be better doing away with inline style AND javascript, and doing this in css with some javascript to control adding.removing css classes.

Assuming the button is always a sibling of the spoiler div, you can do this by having just a class on the spoiler div and attaching it automatically to every instance on a page:

document.querySelectorAll(".spoiler").forEach(s => {
  s.previousSibling.addEventListener("click", () => {
    s.classList.toggle("show");
  });
})
.spoiler{
  display:none
}
.show{
  display:block
}
<button title="Click to show answer" type="button" class="btn btn-primary">   
  show/hide
</button><div class="spoiler">
***

Hidden Text

***
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Jamie's answer turned out to be very similar to the truth! Thanks!

But in Markdown, my colleagues and I made a number of small edits, because the solution did not work right away. The working version looks like this:

First chunk (One, at the beginning of the document (or in style.css for all Rmd files in bookdown)):

.spoiler{
  display:none
}
.show{
  display:block
}

The second piece (actually hidden texts)

<button title="Click to show answer" type="button" class="btn btn-primary">   
  show/hide
</button><div class="spoiler">
***

Hidden Text

***
</div>
<button title="Click to show answer" type="button" class="btn btn-primary">   
  show/hide
</button><div class="spoiler">
***

Hidden Text2

***
</div>

The third piece (one, at the very end of the Rmd file) Changed previousibling to previousElementSibling

document.querySelectorAll(".spoiler").forEach(s => {
  s.previousElementSibling.addEventListener("click", () => {
    s.classList.toggle("show");
  });
})

Thank you for your help!

  • Related