diff --git a/resources/assets/javascripts/lib/header_magic.js b/resources/assets/javascripts/lib/header_magic.js
index f465e7e95b87bcc55da693aad2f87ac59e5b5785..a581107ee5dfbb2dcea1c6afa860561b44bde0cf 100644
--- a/resources/assets/javascripts/lib/header_magic.js
+++ b/resources/assets/javascripts/lib/header_magic.js
@@ -17,7 +17,7 @@ const scroll = function(scrolltop) {
 const HeaderMagic = {
     enable() {
         fold = $('#navigation-level-1').height();
-        Scroll.addHandler('header', scroll);
+        Scroll.addHandler('header', scroll, true);
     },
     disable() {
         Scroll.removeHandler('header');
diff --git a/resources/assets/javascripts/lib/scroll.js b/resources/assets/javascripts/lib/scroll.js
index a4d24d5d55fdfa7d0ca707b1ea325542bb885396..f4ffc66e335a95ec0cd178c749790132a742f57f 100644
--- a/resources/assets/javascripts/lib/scroll.js
+++ b/resources/assets/javascripts/lib/scroll.js
@@ -6,49 +6,54 @@
  * Updates/calls to the callback are synchronized to screen refresh by using
  * the animation frame method (which will fallback to a timer based solution).
  */
-var handlers = {};
-var animId = false;
+const handlers = {};
+let animId = false;
 
-var lastTop  = null;
-var lastLeft = null;
-
-function scrollHandler() {
-    var scrollTop = $(document).scrollTop();
-    var scrollLeft = $(document).scrollLeft();
-
-    if (scrollTop !== lastTop || scrollLeft !== lastLeft) {
-        $.each(handlers, function(index, handler) {
-            handler(scrollTop, scrollLeft);
-        });
-
-        lastTop  = scrollTop;
-        lastLeft = scrollLeft;
-    }
-
-    animId = false;
-
-    engageScrollTrigger();
-}
+let lastTop = null;
+let lastLeft = null;
 
 function refresh() {
-    var hasHandlers = !$.isEmptyObject(handlers);
+    const hasHandlers = Object.keys(handlers).length > 0;
     if (!hasHandlers && animId !== false) {
         window.cancelAnimationFrame(animId);
         animId = false;
     } else if (hasHandlers && animId === false) {
-        animId = window.requestAnimationFrame(scrollHandler);
+        animId = window.requestAnimationFrame(() => Scroll.executeHandlers());
     }
 }
 
 function engageScrollTrigger() {
-    $(window).off('scroll.studip-handler');
-    $(window).one('scroll.studip-handler', refresh);
+    window.removeEventListener('scroll', refresh);
+    window.addEventListener('scroll', refresh, {once: true});
 }
 
 const Scroll = {
-    addHandler(index, handler) {
+    executeHandlers(only_these = []) {
+        const scrollTop = document.scrollingElement.scrollTop;
+        const scrollLeft = document.scrollingElement.scrollLeft;
+
+        if (scrollTop !== lastTop || scrollLeft !== lastLeft) {
+            for (const [index, handler] of Object.entries(handlers)) {
+                if (only_these.length === 0 || only_these.includes(index)) {
+                    handler(scrollTop, scrollLeft);
+                }
+            }
+
+            lastTop  = scrollTop;
+            lastLeft = scrollLeft;
+        }
+
+        animId = false;
+
+        engageScrollTrigger();
+    },
+    addHandler(index, handler, immediate = false) {
         handlers[index] = handler;
         engageScrollTrigger();
+
+        if (immediate) {
+            Scroll.executeHandlers([index]);
+        }
     },
     removeHandler(index) {
         delete handlers[index];
diff --git a/resources/vue/components/responsive/ResponsiveNavigation.vue b/resources/vue/components/responsive/ResponsiveNavigation.vue
index 1c07e738a2f44cd6b3f42cedfe16d37fb7ded7c1..fffce17d77ac7130949c6aa499fdd3ac8c1062e4 100644
--- a/resources/vue/components/responsive/ResponsiveNavigation.vue
+++ b/resources/vue/components/responsive/ResponsiveNavigation.vue
@@ -594,6 +594,9 @@ export default {
                 attributeFilter: ['class']
             })
         });
+
+        // Check initial state after load
+        this.headerMagic = document.querySelector('body').classList.contains('fixed');
     },
     beforeDestroy() {
         this.classObserver.disconnect();