Jump to content

MediaWiki:Gadget-BackToTop.js

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
//Back to Top button with sentinel
(function ($, mw) {
    'use strict';
    if (window.ICWBackToTopLoaded) return;
    window.ICWBackToTopLoaded = true;

    const scrollMs = 600;   // smooth scroll duration

    // SVG
    const svg = `
    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20"
         viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3"
         stroke-linecap="round" stroke-linejoin="round">
        <g transform="translate(1,0)"> <!-- 1 px optical shift -->
            <polyline points="6 9 12 3 18 9"/>
            <line x1="12" y1="21" x2="12" y2="3"/>
        </g>
    </svg>`;

    const $btn = $('<a>', {
        id: 'icw-back-to-top',
        href: '#',
        'aria-label': 'Back to top',
        html: svg
    }).appendTo(document.body);

    // Sentinel before article title (if not found, fall back to body top)
    const sentinel = document.createElement('div');
    sentinel.style.position = 'absolute';
    sentinel.style.top = 0;
    sentinel.style.width = '1px';
    sentinel.style.height = '1px';

    const firstHeading = document.getElementById('firstHeading');
    if (firstHeading && firstHeading.parentNode) {
        firstHeading.parentNode.insertBefore(sentinel, firstHeading);
    } else {
        document.body.prepend(sentinel);
    }

    // Show/hide button
    new IntersectionObserver(
        ([entry]) => {
            $btn.toggleClass('is-visible', !entry.isIntersecting);
        },
        {root: null, threshold: 0}
    ).observe(sentinel);

    // Smooth scroll 
    $btn.on('click.icwBTT', e => {
        e.preventDefault();
        $('html, body').animate({scrollTop: 0}, scrollMs);
    });

})(jQuery, mediaWiki);