How to hide certain images by default?

I wanted to hide certain images in my note by default. The image should become visible if I click on a button. It can look something like the following:

Source: Hide images on front, show images on back - Card Design - Anki Forums (ankiweb.net)

Now, I don’t want to create a separate field for such images because it would disturb the order in which things appear on my card. So, I can add the class “hide” to these images.

I am using the following script to hide the image. However, I can’t figure out how to get the button displayed. So, I need assistance.

<script>
var hideimage = document.getElementsByClassName('hideimage');
for(var i = 0; i < hideimage.length; i++) {hideimage[i].style.display = "none";
const buttonhtml = "<button onclick=''>Show Image</button>";
document.body.insertAdjacentHTML( 'afterend', buttonhtml );}
</script>

Note that I know only basic HTML/CSS/JS from high school. So, an easy-to-understand solution would be appreciated.

You should be able to use {{hint:Image}}, assuming that Image is the name of the field containing the image. hint: is already a built-in feature of Anki.

Thanks for the suggestion but I mentioned this:

To elaborate, my different cards will have such images at different positions. Using a separate field will force me to have those images at the same place in each card.

Also, I want to do this on the back side of the card (after the answer is displayed), if it matters.

Yes, hint: works on the back side of the card. Instead of displaying the contents of the field, it just displays the name of the field as a clickable link, and then clicking on it reveals the contents of the field.

If your image is copy-pasted into a field, then the hint: method will work. You can use hint: in more than one field.

If you want your images arranged in a grid, you could use the Back Template to create an HTML table, and each cell of the table could contain a field with a different image. If it’s something more elaborate, then I guess that wouldn’t work.

This seems to work ok on my computer:

<script>
var hideimage = document.getElementsByClassName('hideimage');

for (var i = 0; i < hideimage.length; i++) {
  hideimage[i].style.display = "none";
  
  const buttonhtml = document.createElement("button");
  buttonhtml.innerText = "Show Image";
  
  hideimage[i].insertAdjacentElement("afterend", buttonhtml);
  buttonhtml.addEventListener("click", showImage.bind(null, i, buttonhtml));

  function showImage(i, button) {
    hideimage[i].style.display = "unset";
    button.style.display = "none";
  }
}
</script>

It seems to work well. Thanks!

However, there is one issue. The image and the button are left-aligned, ignoring my CSS code display: block; set for img in the styling tab.
The rest of the contents of the card are left-aligned in my note type, if it matters.

Though not super-important, it would be nice to have an option to re-hide the image.

Maybe something like this :
(I put the styling inside <style></style> tags, but if you want you can simply move it to the styling section)

Edit: the script contained this line: action = 0.
It was included by mistake and has no purpose in the code, so you may want to remove it. I already deleted it from the code below.

<script>
var hideimage = document.getElementsByClassName('hideimage');

for (var i = 0; i < hideimage.length; i++) {
  hideimage[i].style.display = "none";
  
  const buttonhtml = document.createElement("button");
  buttonhtml.innerText = "Show Image";
  buttonhtml.classList.add("buttonhtml");
  
  hideimage[i].insertAdjacentElement("afterend", buttonhtml);
  buttonhtml.addEventListener("click", toggleImage.bind(null, i));

  function toggleImage(j) {
    if (hideimage[j].style.display === "none") {
      hideimage[j].style.display = "block";
    } else {
      hideimage[j].style.display = "none";
    }
  }
}
</script>

<style>
.buttonhtml {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.hideimage {
  display: block;
  margin-left: auto;
  margin-right: auto;
}
</style>
2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.