MediaWiki:Gadget-StickyHeader.js
Jump to navigation
Jump to search
In other languages: Deutsch • English • Español • Français • Português • 中文
Note: After saving, you may have to bypass your browser's cache to see the changes.
Note: After saving, 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)
- Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
var I18n, instance, intersectPoint, isMobile;
var isBoundToTitle = !mw.config.get( 'wgIsMainPage' );
function StickyHeader() {
this.$search = $( '#p-search' );
this.$searchParent = this.$search.parent();
this.isVisible = false;
this.$stickyHeaderCnt = $( '<header id="ark-sticky-header">' )
.insertAfter( '#wikigg-header' );
this.$stickyName = $( '<a>' )
.attr( 'href', mw.config.get( 'wgScriptPath' ) || '/' )
.prepend( $( '<span class="skull-icon" />' ) )
.append( $( '<span> ')
.text( mw.config.get( 'wgSiteName' ) ) )
.appendTo( $( '<div class="sticky-wiki-name">' )
.appendTo( this.$stickyHeaderCnt ) );
this.$stickySearchContainer = $( '<div class="sticky-search-box">' )
.appendTo( this.$stickyHeaderCnt );
this.$stickyButtonsCnt = $( '<div class="sticky-buttons">' )
.appendTo( this.$stickyHeaderCnt );
var $toc = $( '#toc' );
if ( $toc.length > 0 ) {
this.$btnToC = $( '<a role="button" id="sticky-toc" class="with-icon">' )
.attr( 'title', I18n( 'ToC' ) )
.append( $( '<div class="toc">' )
.append( $toc.find( '> ul' ).clone( true ) ) )
.appendTo( this.$stickyButtonsCnt );
}
this.$btnEdit = this.cloneButton( 'edit', 'Edit' );
this.$btnTalk = this.cloneButton( 'talk', 'Talk' );
this.$btnHistory = this.cloneButton( 'history', 'History' );
this.$btnBackToTop = $( '<a role="button" href="#">' )
.text( I18n( 'BackToTop' ) )
.appendTo( this.$stickyButtonsCnt );
}
StickyHeader.prototype.cloneButton = function ( id, messageName ) {
var $ca = $( '#ca-'+id+' > a' );
if ( $ca.length > 0 ) {
return $( '<a role="button" class="with-icon" id="sticky-'+id+'">' )
.attr( {
href: $ca.attr( 'href' ),
title: $ca.attr( 'title' )
} )
.text( I18n( messageName ) )
.appendTo( this.$stickyButtonsCnt );
}
return null;
}
StickyHeader.prototype.show = function () {
isVisible = true;
document.body.classList.add( 'is-sticky-header-visible' );
this.$search.appendTo( this.$stickySearchContainer );
};
StickyHeader.prototype.hide = function () {
isVisible = false;
document.body.classList.remove( 'is-sticky-header-visible' );
this.$search.appendTo( this.$searchParent );
};
function throttle( func, wait ) {
var context, args, timeout, previous = Date.now() - wait;
var run = function () {
timeout = null;
previous = Date.now();
func.apply( context, args );
};
return function () {
context = this;
args = arguments;
if ( !timeout ) {
timeout = setTimeout( run, Math.max( wait - ( Date.now() - previous ), 0 ) );
}
};
}
var _handleScroll = throttle( function () {
var anchor;
if ( screen.width > 720 ) {
anchor = intersectPoint.getBoundingClientRect().bottom;
} else {
anchor = screen.height * 0.8 - scrollY;
}
if ( anchor < 0 ) {
if ( !instance.isVisible ) {
instance.show();
}
} else {
instance.hide();
}
}, 100 );
mw.loader.using( 'site', function () {
I18n = arkCreateI18nInterface( 'StickyHeader', {
en: {
BackToTop: 'Back to top',
Edit: 'Edit',
History: 'History',
Talk: 'Discuss',
ToC: 'Table of contents'
},
fr: {
BackToTop: 'Haut de page',
Edit: 'Éditer',
History: 'Historique',
Talk: 'Discussion'
},
es: {
BackToTop: 'Volver arriba',
Edit: 'Editar',
History: 'Historique',
Talk: 'Discusión',
ToC: 'Tabla de contenido',
}
} );
$( function () {
// Initialise the sticky header
instance = new StickyHeader();
// Get #firstHeading or #mw-content-text as the intersection point
intersectPoint = $( isBoundToTitle ? '#firstHeading' : '#top' ).get( 0 );
// Set up the scroll observer
_handleScroll();
window.addEventListener( 'scroll', _handleScroll, {
passive: true
} );
} );
} );