javascript - 根据使用 Intersection Observer 滚动到 View 中的元素的数据属性更改导航栏的主题

标签 javascript intersection-observer

我有一个固定的侧面导航栏,默认情况下,它是深色的,以匹配页面最顶部元素(标题)的深色。

enter image description here

这个深色标题下面的下一部分有白色背景,当它以 50% 的偏移量滚动到 View 中时,我想将固定的左侧导航栏更改为相同的颜色。当向上滚动时,侧面导航必须再次相应地改变。

我曾经通过使用一个名为 Waypoints by Imakewebthings 的插件来实现这种效果。 :

var waypoint1 = new Waypoint({
    element: document.getElementById('services-summary'),
        handler: function (direction) {
            if (direction === 'down') {
                // change navigation theme
            } else {
                // change navigation theme
            }
    },
    offset: main_nav_height
});

但是,我正在尝试构建这个新项目而不使用任何依赖项。因此,我决定使用 Javascript 的原生 Intersection Observer尝试实现相同的效果,因为我同意浏览器对此和其他一些视觉效果的支持。

我无法获得一个尊重上下滚动方向的工作版本。我还有一个问题,在页面加载时,我将两个部分主题名称输出到 JS 控制台,这根本不理想。

这就是我要做的:

Javascript:

var intersection_observer_options = {
    root: null,
    rootMargin: '0px',
    threshold: 0
};

var observer = new IntersectionObserver(change_themes_on_view, intersection_observer_options);

function change_themes_on_view(entries, observer) {
    for (var i = 0; i < entries.length; i++) {
        var theme = entries[i].target.getAttribute('data-theme');
        console.log(theme);
    }
}

var themed_sections = document.querySelectorAll('*[data-theme]');
for (var i = 0; i < themed_sections.length; i++) {
    observer.observe(themed_sections[i]);
}

HTML:

我不包括 CSS 方面的内容,因为我可以自己解决这个问题。我也不在这里包括导航栏,因为我只是想演示如何识别每个部分的主题。然而,我在 JSFIDDLE example 中展示了更多内容。 .

<header data-theme="dark">
    ...
</header>

<main>
    <section data-theme="light">
        ...
    </section>

    <section data-theme="dark">
        ...
    </section>

    <section data-theme="light">
        ...
    </section>

    <section data-theme="dark">
        ...
    </section>
</main>

当我运行页面时,我得到以下控制台输出,无需滚动到任何地方,也看不出原因:

> dark
> light
> dark
> light
> dark

为了帮助你帮助我,我整理了一个FIDDLE帮助实现这一目标。

了解这个新的 Intersection Observer API 的人可以帮助我跨过阈值吗?请原谅这个双关语。

更新1

I think I have got it working here 。还在修修补补。

更新2

是的,it's working .

我将添加自己的答案,因为我确信其他人会发现这很有用,而不是删除问题。

最佳答案

我自己修复了它,令人惊讶的是,距离并不远。

为了解决我的两个问题 - 为什么它在控制台中输出所有主题而不考虑滚动方向 - 我只是将此条件语句添加到我的 change_themes_on_view 函数中:

if (entries[i].intersectionRatio > 0) {
    // do stuff now entry is in viewport
}

它测试目标元素/条目是否在视口(viewport)内。

这显然修复了将页面加载时所有目标主题值输出到我的控制台的脚本。现在它也尊重方向,因为当目标元素离开视口(viewport)时,主题会反转。

现在这是完整的功能:

function change_themes_on_view(entries, observer) {
  for (var i = 0; i < entries.length; i++) {
    if (entries[i].intersectionRatio > 0) {
      var theme = entries[i].target.getAttribute('data-theme');
      nav_bar.setAttribute('data-theme', theme);
    }
  }
}

This is the working demo

关于javascript - 根据使用 Intersection Observer 滚动到 View 中的元素的数据属性更改导航栏的主题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58120648/

相关文章:

javascript - While 循环和输出数学运算符

javascript - IntersectionObserver 和 ajax 加载内容

javascript - IntersectionObserver 方法不起作用 - Javascript

javascript - 如果阈值大于 0,IntersectionObserver isIntersecting 属性永远不会为 false

javascript - 将额外参数传递给 IntersectionObserver?

javascript - ReactJS:动态添加标签和内容到 react-dom 并重新加载它

javascript - 如何让 2 个不同的点击相同的图像来做 2 个不同的事情

javascript - 使用react-router的历史记录,有没有办法在不使用push()或replace()的情况下返回到之前渲染的特定页面?

javascript - 带有 Ember CLI 的 jQuery UI

javascript - 如何将 IntersectionObserver 与 React 结合使用?