I have a weird issue where I’m using jQuery to automatically add an "active" class to an internal menu (and update the url on) when the user scrolls or clicks on each menu item. On scroll it works fine, but on click it bolds and updates the url for the item ABOVE the item clicked, and I can’t figure out why…
I have a menu set up like this:
<ul>
<li><a href="#1" data-id="1" class="toc-link">link 1</a></li>
<li><a href="#2" data-id="2" class="toc-link">link 2</a></li>
...etc
</ul>
And content set up as:
<h2 id="1">title 1<h2>
<p>content</p>
<h2 id="2">title 2<h2>
<p>content</p>
...etc
jQuery script:
jQuery(document).ready(function() {
// Update the active header and URL on click
jQuery('.toc-link').click(function(e) {
e.preventDefault();
var activeId = jQuery(this).attr('data-id');
var url = window.location.href.split('#')[0];
var newUrl = url + '#' + activeId;
window.history.pushState('', document.title, newUrl);
jQuery('.toc-link.active').removeClass('active');
jQuery(this).addClass('active');
// Scroll to corresponding header
var headerTop = jQuery('#' + activeId).offset().top;
jQuery('html, body').animate({ scrollTop: headerTop }, 500);
});
// Update the active header and URL on scroll
jQuery(window).scroll(function() {
var scrollPos = jQuery(window).scrollTop();
var activeId = null; // Initialize activeId to null
jQuery('h2').each(function() {
var headerTop = jQuery(this).offset().top;
var id = jQuery(this).attr('id');
if (scrollPos >= headerTop) {
activeId = id;
}
});
if (activeId !== null) {
var newUrl = window.location.href.split('#')[0] + '#' + activeId;
window.history.pushState('', document.title, newUrl);
jQuery('.toc-link').removeClass('active'); // remove active class from all links
jQuery('.toc-link[data-id="' + activeId + '"]').addClass('active'); // add active class to matching link
}
});
});
You can see this problem in action here.
I feel like this is a simple fix, but my javascript isn’t that great. I’d appreciate any pointers. Thanks!
2
Answers
So to make a long story short, the problem seems to be with the way I'm scrolling the page. Although there are probably better solutions, this is what I came up with - taking
100
off of theheaderTop
variable:I observed in the console
while click on tag your data-id is very weird for me like below:
activeId = ‘1-%D7%94%D7%9C%D7%94%D7%A7%D7%95%D7%AA-%D7%91%D7%A7%D7%95%D7%9E%D7%93%D7%99%D7%94-%D7%93%D7%9C%D7%B3%D7%90%D7%A8%D7%98%D7%94’
can you check your active-Id because you have passed numeric ID in that attribute.