MediaWiki:Gadget-BackToTop.js
Appearance
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);