This piece of javascript does not seem to work (hint button)

Hello, I have this piece of code I would like to use, it seems to work on online code editors but not on Anki
Am i doing something wrong, or is there some incompatibility issue?
I am using Anki 2.1.22
Thank you in advance

HTML:
<div id="Hint">Hint</div>
<p id="demo"></p>
<button>Hint</button>

CSS:
#Hint {display:none}

Javascript:
<script>
let funcArr = [
    function () {
var str = document.getElementById("Hint").innerHTML;
var res = str.charAt(0);
document.getElementById("demo").innerHTML = res;
},
  

    function() {
var str = document.getElementById("Hint").innerHTML;
var res = str.charAt(1);
document.getElementById("demo").innerHTML = res;
},

    function() {
var str = document.getElementById("Hint").innerHTML;
var res = str.charAt(2);
document.getElementById("demo").innerHTML = res;
},

    

    function() {
var str = document.getElementById("Hint").innerHTML;
var res = str.charAt(3);
document.getElementById("demo").innerHTML = res;
},
];

let i = 0;

window.onload = function () {

    let btn = document.getElementsByTagName('button')[0];

    btn.onclick = function () {

        funcArr[i++ % funcArr.length](); // first call function and then, increment the value of i

    }

}
</script>

My script would work like this: first click - first letter of the hidden field is shown; second click - second letter is shown; third click: third letter is shown; and so on

Here is a demo: Code PlayGround | SoloLearn

Can the addon you suggested do this (without creating a field for each letter)? I cannot seem to make it work this way, but maybe I am doing something wrong

(Disclaimer: I’m just a user of Anki.)

First of all, Javascript feature in Anki is only intended for advanced users, and is not officially guaranteed to work. See here.

Secondly, you can use Google Chrome to debug the webview of the card screen.

That being said, here are a few things you might want to keep in mind when writing javascript for card templates.

  • You can’t use window.onload or window.addEventListener('DOMContentLoaded', ...), because Anki desktop only updates a part of the DOM tree when displaying a card rather than refreshing the whole page.
  • Do not use let or const at the top level of scripts. This is due to the same reason as above.
  • Loading external scripts with <script src="..."> may not work. In such a case, you need to load them dynamically. See Linking to external javascript for more information.
  • In some cases, you may not be able to properly get the element you want by using getElement(s)By... or querySelector(All). In such cases, wrapping the process with the setTimeOut() function may work.

If I were to rewrite your script, I would probably use a closure and write something like this:

<div id="Hint">Hint</div>
<p id="demo"></p>
<button onclick="revealHintChar();">Hint</button>

<script>
    var revealHintChar = (function () {
        const hintString = document.getElementById("Hint").innerHTML;
        const outputElement = document.getElementById("demo");
        let index = 0;

        return function () {
            outputElement.innerHTML = hintString.charAt(index++ % hintString.length);
        };
    })();
</script>
6 Likes

Try this setup:

<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>

You can move that style=“display:none” for the word div over to CSS, I just kept it inline for clarity.

EDIT: Haha nice @hkr, almost simultaneous :grinning_face_with_smiling_eyes:

4 Likes

My bad, I assumed wrongly it was that. Nevermind

1 Like

@hkr @kleinerpirat
Wow, thank you both for the explanation and the pieces of code! (: