Journal of Sociology in East and Horn of Africa
Vol 1 Issue 1 — 2025
(function () {
const iframe = document.querySelector('.iframe-container iframe');
const topHeader = document.getElementById('hrlStickyHeader');
const viewToggle = document.querySelector('.view-toggle');
const journalBar = document.querySelector('.journal-bar');
if (!iframe || !topHeader) return;
let lastScrollTop = 0;
let lastMsgTime = 0;
// Helper: show/hide UI with transforms
function hideHeaderImmediately() {
topHeader.style.transform = 'translateY(-120%)';
if (viewToggle) viewToggle.style.transform = 'translateY(-120%)';
if (journalBar) journalBar.style.transform = 'translateY(-120%)';
}
function showHeaderImmediately() {
topHeader.style.transform = 'translateY(0)';
if (viewToggle) viewToggle.style.transform = 'translateY(0)';
if (journalBar) journalBar.style.transform = 'translateY(0)';
}
// Use a small deadzone and timeout to avoid flicker
let hideTimeout = null;
// Listen to postMessage events
window.addEventListener('message', function (e) {
try {
// SECURITY: validate origin if possible. If iframe is same-origin you can check:
// if (e.origin !== window.location.origin) return;
const msg = (typeof e.data === 'string') ? JSON.parse(e.data) : e.data;
if (!msg || msg.type !== 'galleyScroll') return;
// msg: { type: 'galleyScroll', scrollTop, scrollHeight, clientHeight, timestamp }
const scrollTop = Number(msg.scrollTop) || 0;
const now = Date.now();
// Very small throttling to avoid too many operations
if (now - lastMsgTime < 50) return;
lastMsgTime = now;
const delta = scrollTop - lastScrollTop;
// If user scrolls down (delta > threshold) hide header
if (delta > 12) {
hideHeaderImmediately();
// clear any pending show
if (hideTimeout) { clearTimeout(hideTimeout); hideTimeout = null; }
}
// If user scrolls up (delta < -12) show header
else if (delta < -12) {
showHeaderImmediately();
if (hideTimeout) { clearTimeout(hideTimeout); hideTimeout = null; }
} else {
// small movement: keep current state, but if near top show header
if (scrollTop < 80) {
showHeaderImmediately();
}
}
lastScrollTop = scrollTop;
} catch (err) {
console.warn('Parent message handler error', err);
}
}, false);
// Safety: when parent window is resized or user focuses, show header
window.addEventListener('resize', showHeaderImmediately);
window.addEventListener('focus', showHeaderImmediately);
// Add CSS transition if not already present
[topHeader, viewToggle, journalBar].forEach(el => {
if (!el) return;
el.style.transition = el.style.transition || 'transform 0.35s ease-in-out';
el.style.willChange = 'transform';
});
})();