Site icon FSIBLOG

How to Fix OnePageNavigation.js Uncaught TypeError in JavaScript?

How to Fix OnePageNavigation.js Uncaught TypeError in JavaScript?

How to Fix OnePageNavigation.js Uncaught TypeError in JavaScript?

Hey, I want to share a recent problem I ran into while working on a website navigation script, and how I fixed it. If you’ve ever seen this error in your JavaScript console

Error Code

Uncaught TypeError: Cannot read property 'top' of undefined

Then this post is for you. I’ll explain why this error happens, walk you through the code causing it, and show you how to fix it properly. I’ll also give some extra tips to improve your page navigation.

The Code That Causes the Error

Here’s the exact code snippet that was giving me trouble:

 OnePageNavigation = function() {
$("body").on("click", ".main-menu li a[href^='#'], .smoothscroll[href^='#'], .main-menu li a[href^='index.html'], .smoothscroll[href^='index.html'], .site-mobile-menu .site-nav-wrap li a", function(e) {
e.preventDefault();

var hash = this.hash;

$('html, body').animate({
'scrollTop': $(hash).offset().top
}, 300, 'easeInOutExpo', function(){
window.location.hash = hash;
});

});
};
OnePageNavigation();

The intention here is to create smooth scrolling behavior when clicking certain navigation links that point to anchors on the page (like #portfolio-section) or links that include an anchor in the URL (like index.html#about-section).

What the Error

Uncaught TypeError: Cannot read property 'top' of undefined

means that when JavaScript tries to access .top of $(hash).offset(), it’s getting undefined instead of an object.

Why? Because:

Does It Happen Only On Some Pages

In my case:

Check Before Accessing .offset()

The key fix is to check if the element exists before trying to scroll to it. Here’s the improved code snippet I wrote:

 OnePageNavigation = function() {
$("body").on("click", ".main-menu li a[href^='#'], .smoothscroll[href^='#'], .main-menu li a[href^='index.html'], .smoothscroll[href^='index.html'], .site-mobile-menu .site-nav-wrap li a", function(e) {
e.preventDefault();

var href = $(this).attr('href');
var isSamePageAnchor = href.startsWith('#');
var target;

if (isSamePageAnchor) {
target = $(href);
if (target.length) {
// Smooth scroll to the element
$('html, body').animate({
scrollTop: target.offset().top
}, 300, 'easeInOutExpo', function() {
window.location.hash = href;
});
} else {
// Element doesn’t exist on this page — fallback to default behavior or log warning
console.warn('Target element not found for:', href);
}
} else if (href.includes('#')) {
// Link to another page with an anchor like index.html#section
window.location.href = href;
} else {
// Regular link without anchor, just navigate
window.location.href = href;
}
});
};
OnePageNavigation();

What This Does:

Some Extra Features I Added for Practice

While I was fixing this, I also added a couple of handy features:

Highlight the Active Menu Item on Scroll

This helps users know which section they’re currently viewing:

highlightOnScroll = function() {
$(window).on('scroll', function() {
var scrollPos = $(document).scrollTop();

$('.main-menu li a[href^="#"]').each(function() {
var currLink = $(this);
var refElement = $(currLink.attr('href'));
if (refElement.length) {
if (refElement.position().top <= scrollPos + 100 && refElement.position().top + refElement.height() > scrollPos + 100) {
$('.main-menu li a').removeClass('active');
currLink.addClass('active');
}
}
});
});
};
highlightOnScroll();

Close Mobile Menu After Clicking a Link

To improve UX on mobile devices, it’s good to automatically close the mobile menu when a user clicks any navigation link:

$("body").on("click", ".site-menu-toggle, .site-mobile-menu .site-nav-wrap li a", function() {
if ($('.site-mobile-menu').hasClass('active')) {
$('.site-mobile-menu').removeClass('active');
}
});

Add Fallback for Animation Timeout

Sometimes the scroll animation might get interrupted. To ensure the URL hash updates reliably, I added a fallback timeout:

scrollTimeout;
$('html, body').animate({scrollTop: target.offset().top}, 300, 'easeInOutExpo', function() {
window.location.hash = hash;
});
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(function(){
window.location.hash = hash;
}, 350);

Final Thought

This error is very common when working with smooth scrolling and one-page navigation, especially when you mix links to different pages with anchors to sections on the same page.

The key takeaway for me was:

I hope this helps you avoid the “Cannot read property ‘top’ of undefined” error and make your site navigation smoother and more reliable.

Exit mobile version