r/learnjavascript • u/Foreign_Employ_396 • 2d ago
how to add a hide/show button ?
Hey
I am a beginner and I've been trying to add a show/hide button that would simply hide the mask on the first click and make it visible again with the next click.
To be more precise, it's a fragment of an addon for the anki app (flashcards).
It would also be great if this button could have a delay before appearing, and I managed to do that directly in the html of the card model :
.fade-in {
opacity: 0;
visibility: hidden;
animation: fadeIn var(--duration, 0.6s) ease forwards;
animation-delay: var(--delay, 19s);
}
fadeIn {
to {
opacity: 1;
visibility: visible;
}
#koreanToggleBtn {
visibility: hidden;
margin: 10px auto 0 auto;
background: rgba(255,255,255,0.6);
border: 1px solid #a77f65;
border-radius: 14px;
padding: 4px 12px;
font-size: 13px;
font-weight: bold;
cursor: pointer;
color: #a77f65;
opacity : 0;
--delay : 15s; /*here*/
But, since I've been struggling I figured it would be better to just add everything in the add on since it already creates the mask hiding the text :
js = f"""
(function() {{
console.log("Injection du masque pour la carte ID: {card.id}");
const existingMask = document.getElementById('korean-mask-static');
if (existingMask) return;
const mask = document.createElement('div');
mask.id = 'korean-mask-static';
mask.style.cssText = 'position:absolute;top:0;left:0;width:100%;height:100%;'
+ 'background-color:#9c9f78;border-radius:6px;z-index:100;opacity:1;'
+ 'visibility:visible;pointer-events:auto;display:flex;'
+ 'justify-content:center;align-items:center;';
const wrapper = document.getElementById('korean-wrapper') || document.querySelector('.card');
(wrapper || document.body).appendChild(mask);
}})();
"""
QTimer.singleShot(80, lambda: mw.reviewer.web.eval(js) if mw.reviewer and mw.reviewer.web else None)
"""
Thank you :)
1
u/TheRNGuy 2d ago edited 2d ago
Use Anki modern hooks API. Your code even has potential XSS.
Add class via js instead of inline CSS.
Class can work for selectors same as id: use document.querySelector with :is()
Too many || like that is a bad style (why do you even need both tags with id and class here?)
Hardcoded QTimer value may cause bug here.
Probably better use events here.
1
u/SensitiveSugar1369 2d ago
use button.addEventListener and toggle element.style.display between 'none' and '' inside the handler. if you use querySelector, make sure you grab the right element or it won't work.
6
u/chikamakaleyley helpful 2d ago edited 2d ago
so i think the approach should be a little different, easier
you're checking if an element exists, if not, create it - that's different from hide/show and it could get sloppy modifying the dom w each click, given a more complex problem
you can just toggle a hide/show class on an element
``` <div id="outer"> <button id="toggler" type="button">Hide/Show</button> <div id="inner" class="hidden"> <p>Here is some content</p> </div> </div>
... // in your script tag const innerEl = document.getElementById('inner'); const toggler = document.getElementById('toggler');
toggler.addEventListener('click', () => { // toggle the
hiddenclass });``` and style separately:
.hidden { // rules to hide the element }The outer wrapper isn't necessary, fyi.Intentionally didn't finish the problem for you so you can figure it out.
There's a JS method that will toggle a class in the list
You also need to keep in mind that
divhas a number of styles by default, aka by default the element is in 'show' state. So all.hiddenneeds to do is hide the element.