Anki Forums

Click on texts to play audio

I found this script on reddit, but I notice in order for the audio to play, I have to edit the card again, and that alone doesn’t guarantee it works, so I am wondering if anyone may know the problem, or has a better solution for playing audio on clicking the text.

1 Like

The script is a bit outdated and as it is might only work on AnkiDroid and won’t work on Anki and AnkiMobile due to this error message in the Chrome DevTools console after reviewing the second card.

Uncaught SyntaxError: Identifier ‘…’ has already been declared

You can fix it by converting the code inside the script tag to IIFE to isolate variable declarations or by using onUpdateHook.

  • onUpdateHook fires after the new card has been placed in the DOM, but before it is shown.
  • onShownHook fires after the card has faded in.

https://addon-docs.ankiweb.net/features-and-debugging.html#card-review-javascript

The updated script looks something like this.

<div data-audio="sound">{{Text}}</div>
<div id="sound" hidden>{{Audio}}</div>

<script>
function playAudio(evt) {
    const el = evt.target.closest("[data-audio]");
    const audio = document.getElementById(el.dataset.audio);
    audio.querySelector(".replay-button, .replaybutton").click();
}

onUpdateHook.push(function() {
    const elements = document.querySelectorAll("[data-audio]");
    for (const el of elements) {
        el.addEventListener("click", playAudio);
    }  
});
</script>

The Text field contains the text and the Audio field contains the audio file. They’re linked together using data-audio="{}" and id="{}" attributes with the same string.

.replay-button - Anki 2.1, AnkiMobile
.replaybutton - AnkiDroid

This is a sample Anki deck - Click on Text to play Audio Template.apkg - Google Drive

If you want something different, maybe share a link to an Anki deck that you’d like to modify or explain a bit more what do you want to do.

2 Likes

I tried it and it worked on anki 2.1, but not on ankimobile, any thoughts?

It’s probably because of this.

Javascript

The warnings that apply to the computer version also apply to AnkiMobile.

In addition to the above, another thing to be aware of in AnkiMobile is that your code also needs to play nicely with AnkiMobile’s tap detection. Taps on A/BUTTON elements, or elements that have an onclick handler should work as you expect.

If you have other elements that must receive tap events, give them the class ‘tappable’ to tell AnkiMobile 2.0.39 or later that it should pass taps through to the element.

https://docs.ankimobile.net/more.html#javascript

Try these two versions.

  • v2.1 (“tappable”)

    Click on Text to play Audio (sample) v2.1.apkg - Google Drive

    Code
    <div data-audio="sound">{{Text}}</div>
    <div id="sound">{{Audio}}</div>
    
    <script>
    function playAudio(evt) {
        const el = evt.target.closest("[data-audio]");
        const audio = document.getElementById(el.dataset.audio);
        audio.querySelector(".replay-button, .replaybutton").click();
    }
    
    onUpdateHook.push(function() {
        const elements = document.querySelectorAll("[data-audio]");
        for (const el of elements) {
            el.addEventListener("click", playAudio);
            el.classList.add('tappable');
        }  
    });
    </script>
    
  • v2.2 (“onclick”)

    Click on Text to play Audio (sample) v2.2.apkg - Google Drive

    Code - short version
    <div onclick="playAudio('sound');">{{Text}}</div>
    <div id="sound">{{Audio}}</div>
    
    <script>
    function playAudio(id) {
        const audio = document.getElementById(id);
        if (audio) audio.querySelector(".replay-button, .replaybutton").click();
    }
    </script>
    
2 Likes