← All examples

JavaScript Media substack.com

Substack: click-to-play GIFs

Pauses looped video and GIFs and adds a "play" button so animated images do not start automatically.

Code to copy

// Replace autoplaying GIFs (and looped MP4s used as GIFs) with click-to-play stills
(function () {
  function stopVideo(v) {
    try { v.autoplay = false; v.loop = false; v.removeAttribute('autoplay'); v.pause(); } catch (e) {}
    if (v.dataset.jzGif) { return; }
    v.dataset.jzGif = '1';
    v.controls = false;
    var play = document.createElement('button');
    play.type = 'button';
    play.textContent = '▶ play';
    play.style.cssText = 'position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);background:rgba(0,0,0,.7);color:#fff;border:none;border-radius:18px;padding:6px 12px;cursor:pointer;font:600 13px/1 system-ui,sans-serif;z-index:5;';
    var wrap = v.parentNode;
    if (wrap && getComputedStyle(wrap).position === 'static') { wrap.style.position = 'relative'; }
    if (wrap) { wrap.appendChild(play); }
    play.addEventListener('click', function () {
      try { v.play(); } catch (e) {}
      play.remove();
    });
  }
  function patch() {
    document.querySelectorAll('video[autoplay], video[loop]').forEach(stopVideo);
    document.querySelectorAll('img[src$=".gif" i]').forEach(function (img) {
      if (img.dataset.jzGif) { return; }
      img.dataset.jzGif = '1';
      var orig = img.getAttribute('src') || '';
      img.addEventListener('click', function () { img.setAttribute('src', orig + (orig.indexOf('?') > -1 ? '&' : '?') + 'jz=' + Date.now()); }, { once: true });
      // freeze by reloading once it's in the DOM (browsers usually animate on load only)
      img.style.cursor = 'pointer';
      img.title = 'Click to play GIF';
    });
  }
  patch();
  var obs = new MutationObserver(function () {
    clearTimeout(window.__jzSubGif);
    window.__jzSubGif = setTimeout(patch, 300);
  });
  obs.observe(document.body, { childList: true, subtree: true });
})();

How to use this example

  1. Copy the code with the button above.
  2. Install JustZix (2 minutes) and open the extension on the target page.
  3. Add a new rule matching that page.
  4. Paste the code into the rule's JavaScript panel and save — it runs on every page visit.

Rate this example

No ratings yet — be the first.

Does this example work?

Snippets are useless without somewhere to paste them.

JustZix takes 2 minutes to install and runs your code on every matching page. No account, no payment.

Download free See use cases