javascript - 突出显示事件菜单项作为页面滚动 div(侧边栏滚动菜单)

标签 javascript jquery html css

JSFiddle通过 Gaurav Kalyan在 Chrome 中运行良好,但在 Safari 和 Firefox 中它会激活错误的菜单项。它不是突出显示单击的菜单项,而是突出显示之前的菜单项。因此,例如,如果您单击“Punkt 4”,则会突出显示“Punkt 3”。我没能解决这个问题。有人可以帮忙吗?两周来我一直在努力解决这个问题。

HTML

    <section id="main">
    <div class="target" id="1">TARGET 1</div>
    <div class="target" id="2">TARGET 2</div>
    <div class="target" id="3">TARGET 3</div>
    <div class="target" id="4">TARGET 4</div>
</section>
<aside id="nav">
    <nav>
        <a href="#1" class="active">Punkt 1</a>
        <a href="#2">Punkt 2</a>
        <a href="#3">Punkt 3</a>
        <a href="#4">Punkt 4</a>
    </nav>
</aside>

CSS

    * {
    margin: 0;
    padding: 0;
}

#main {
    width: 75%;
    float: right;
}

#main div.target {
    background: #ccc;
    height: 400px;
}

#main div.target:nth-child(even) {
    background: #eee;
}

#nav {
    width: 25%;
    position: relative;
}

#nav nav {
    position: fixed;
    width: 25%;
}

#nav a {
    border-bottom: 1px solid #666;
    color: #333;
    display: block;
    padding: 10px;
    text-align: center;
    text-decoration: none;
}

#nav a:hover, #nav a.active {
    background: #666;
    color: #fff;
}

JavaScript

    $('#nav nav a').on('click', function(event) {
    $(this).parent().find('a').removeClass('active');
    $(this).addClass('active');
});

$(window).on('scroll', function() {
    $('.target').each(function() {
        if($(window).scrollTop() >= $(this).offset().top) {
            var id = $(this).attr('id');
            $('#nav nav a').removeClass('active');
            $('#nav nav a[href=#'+ id +']').addClass('active');
        }
    });
});

最佳答案

如果视口(viewport)高度(浏览器窗口的内部高度)<= 400px,这就可以正常工作。这是因为当您单击 nav 元素中的 a 链接时,href#4,默认浏览器行为启动,带有 id="4" 的元素滚动到顶部(尽可能多)。

当视口(viewport)与滚动到的元素的高度相同或更小时,当您的 scroll 处理程序被触发时, if($(window).scrollTop() >= $(this).offset().top) 条件评估为真,因为 scrollTop 将完全等于 offset().top #4 分区

但是,当视口(viewport)比内容 div 大时(在您的情况下,> 400px),当浏览器试图将最后一个 div 滚动到 View 中时,它可以完全这样做,同时仍然显示前一个 div 的下半部分的一部分。这意味着第三个 div 将通过您的滚动处理程序 if 检查,而不是您的第四个。 (最后一个 div 的偏移顶部不会 <= 窗口的滚动顶部)。

example of viewport height more than 400 pixels

那么解决方案是什么?

我会让每个目标 div 至少与视口(viewport)具有相同的高度。您可以在现代浏览器上使用 min-height: 100vh;(视口(viewport)高度的 100%)实现这一点。这意味着当最后一个滚动到 View 中时,它将完全填满视口(viewport),正确的 div 将正确通过您的 scroll 逻辑检查。

See here for a working fork.

奖金提示

您可以采取多种措施来提高此代码的性能。缓存 jQuery 变量的创建,避免重复工作在每个滚动事件上发生 4 次(这可能经常发生)等。目前它可以正常工作,但以后可能会成为瓶颈。

关于javascript - 突出显示事件菜单项作为页面滚动 div(侧边栏滚动菜单),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54994173/

相关文章:

javascript - AngularJS 日期过滤器不产生结果

javascript - ng-model 导致 AngularJS 输出中的计算失败

javascript - 将元素下的所有元素与元素的外部样式隔离的正确方法

javascript - JavaScript 如何知道 Promises 回调函数何时准备好执行?

javascript - instagram 喜欢将鼠标悬停在图像上时显示的计数

javascript - 如何使用 Jquery 或 Javascript 在 API 调用函数之外使用变量

jquery - 从复选框中选择时显示来自 jQuery JSON 的相应数据

javascript - 如何将 tinymce 4.x 动态添加到 textarea?

javascript - 用 div 标签包裹 iframe 标签

html - 不同页面上使用 em 的 CSS 字体大小不同