How to change from onclick to keydown javascript

Hey, could someone please help me modify this script to change it from functioning onclick but instead to function on the pressing of a specific key which I can modify?

<div id="word" style="display:none">{{Back}}</div>

<div id="reveal"></div>

<button id="hint-btn" onclick="revealNext()">Next letter</button>

<script>
var nextChar = 1
var word = document.getElementById("word").innerText

function revealNext() {
   if (nextChar <= word.length) {
      document.getElementById("reveal").innerText = word.substring(0, nextChar++)
   }
}
</script>

I would recommend reading the appropriate documentation. If you have any specific question about it, feel free to ask.

Hi thanks for the quick reply.
I have no experience with coding
Could you help me?

Of course! You’ll see, it’s actually very simple.

The first difference between detecting a mouse clicking event vs keyboard key presses (in your case at least) is that mouse clicks events are bound to a particular area of the DOM, that is, if you click on the tag with the onclick=... attribute it will do something, but if you click somewhere else, it won’t, whereas with keyboard events, you can just detect whether the user presses a key, no matter where their mouse is (to keep it simple). This means that the event trigger will no longer be bound to a particular DOM element, so the first step is removing the onclick=... attribute. We won’t need that anymore:

<div id="word" style="display:none">{{Back}}</div>

<div id="reveal"></div>

<button id="hint-btn">Next letter</button>

<script>
var nextChar = 1
var word = document.getElementById("word").innerText

function revealNext() {
   if (nextChar <= word.length) {
      document.getElementById("reveal").innerText = word.substring(0, nextChar++)
   }
}
</script>

Now, we just need to add the wanted event listener, with

document.addEventListener('keydown', onKey);

function onKey(e) {
    if (e.key === "a") {
        revealNext();
    }
}

Note that this will detect if the key pressed is a, but you can change to anything. If you want to detect a printable character (ie. a letter, a number or a symbol) you can just type it in the string, but if you want to detect other buttons, you have to look them up in this table to see their representation. For instance, say I want to detect when I press Enter, I search in the whitespace section of that table and I find its representation is “Enter”, so I would transform my onKey function in

function onKey(e) {
    if (e.key === "Enter") {
        revealNext();
    }
}

Or, alternatively, I could press enter in this input box, which would print on the right what was the key representation.

Also note that this is case sensitive, pressing A with e.key === "a" will not work. If you don’t want it to be case sensitive, you case lowercase the key representation:

function onKey(e) {
    if (e.key.toLowerCase() === "a") {
        revealNext();
    }
}

Finally, just to be clear, this is how your document would look like

<div id="word" style="display:none">{{Back}}</div>

<div id="reveal"></div>

<button id="hint-btn">Next letter</button>

<script>
var nextChar = 1
var word = document.getElementById("word").innerText

function revealNext() {
   if (nextChar <= word.length) {
      document.getElementById("reveal").innerText = word.substring(0, nextChar++)
   }
}
function onKey(e) {
    if (e.key === "a") {
        revealNext();
    }
}
document.addEventListener('keydown', onKey);
</script>
6 Likes

wow thank you so much!!! cant believe it
im terribly grateful for your detailed response
thanks also for running me through the steps! I’m interested in learning code so ur explanations were very helpful
your code works perfectly, its going to help my study a lot

Hi blackbeans,

I’m having a issue that when I press the key function it reveals sometimes 2-3 letters or even the whole word instead of revealing the letters one by one on each key press. This only happens when studying in anki. On preview mode, the script works as intended.
Do you have any idea how/if this can be fixed?

Unfortunately, I have very little experience with JavaScript and web development so I’m afraid I can’t help you, but maybe more competent people such as @kleinerpirat could…

2 Likes

That’s because there’s no guard against adding new EventListeners in the script. Because Anki’s reviewer webview is persistent between cards, the script adds an additional EventListener to the document with each new card.

Result: On the first card, it will reveal 1 letter, on the next it will reveal 2 on each keypress, then 3 and soon you’ll have a full reveal on keypress.

This should fix it:

if (!globalThis.incrementalRevealListener) {
  document.addEventListener("keydown", onKey);
  globalThis.incrementalRevealListener = true;
}
4 Likes

Thanks that works perfectly :smiley: