Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用交叉点观察者(IO)更改标题/导航样式_Javascript_Html_Css_Intersection Observer - Fatal编程技术网

Javascript 使用交叉点观察者(IO)更改标题/导航样式

Javascript 使用交叉点观察者(IO)更改标题/导航样式,javascript,html,css,intersection-observer,Javascript,Html,Css,Intersection Observer,我用scroll event方法开始了这个问题,但由于建议使用IntersectionObserver这似乎更好的方法,我正试图让它以这种方式工作 目标是什么: header { position: fixed; width: 100%; top: 0; line-height: 32px; padding: 0 15px; z-index: 5; color: black; /* default */ background-color: white; /* d


我用
scroll event
方法开始了这个问题,但由于建议使用
IntersectionObserver
这似乎更好的方法,我正试图让它以这种方式工作


目标是什么:

header {
  position: fixed;
  width: 100%;
  top: 0;
  line-height: 32px;
  padding: 0 15px;
  z-index: 5;
  color: black; /* default */
  background-color: white; /* default */
}
<div class="grid-30-span g-100vh">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_default_header.jpg" 
    class="lazyload"
    alt="">
</div>
<div class="grid-30-span g-100vh" data-color="white" data-background="darkblue">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_darkblue.jpg" 
    class="lazyload"
    alt="">
</div>

<div class="grid-30-span g-100vh" data-color="white" data-background="black">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_black.jpg" 
    class="lazyload"
    alt="">
</div>
var mq = window.matchMedia( "(min-width: 568px)" );
if (mq.matches) {
  // Add for mobile reset

document.addEventListener("DOMContentLoaded", function(event) { 
  // Add document load callback for leaving script in head
  const header = document.querySelector('header');
  const sections = document.querySelectorAll('div');
  const config = {
    rootMargin: '0px',
    threshold: [0.00, 0.95]
  };

  const observer = new IntersectionObserver(function (entries, self) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        if (entry.intersectionRatio > 0.95) {
          header.style.color = entry.target.dataset.color !== undefined ? entry.target.dataset.color : "black";
          header.style.background = entry.target.dataset.background !== undefined ? entry.target.dataset.background : "white";   
        } else {
        if (entry.target.getBoundingClientRect().top < 0 ) {
          header.style.color = entry.target.dataset.color !== undefined ? entry.target.dataset.color : "black";
          header.style.background = entry.target.dataset.background !== undefined ? entry.target.dataset.background : "white";
          }
        } 
      }
    });
  }, config);

  sections.forEach(section => {
    observer.observe(section);
  });

});

}
我想根据当前的
div
/
通过查找(我正在考虑?)它的
数据
来覆盖默认的
标题
样式,从而更改
标题
的样式(
颜色
)(黑色白色)


标题样式:

header {
  position: fixed;
  width: 100%;
  top: 0;
  line-height: 32px;
  padding: 0 15px;
  z-index: 5;
  color: black; /* default */
  background-color: white; /* default */
}
<div class="grid-30-span g-100vh">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_default_header.jpg" 
    class="lazyload"
    alt="">
</div>
<div class="grid-30-span g-100vh" data-color="white" data-background="darkblue">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_darkblue.jpg" 
    class="lazyload"
    alt="">
</div>

<div class="grid-30-span g-100vh" data-color="white" data-background="black">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_black.jpg" 
    class="lazyload"
    alt="">
</div>
var mq = window.matchMedia( "(min-width: 568px)" );
if (mq.matches) {
  // Add for mobile reset

document.addEventListener("DOMContentLoaded", function(event) { 
  // Add document load callback for leaving script in head
  const header = document.querySelector('header');
  const sections = document.querySelectorAll('div');
  const config = {
    rootMargin: '0px',
    threshold: [0.00, 0.95]
  };

  const observer = new IntersectionObserver(function (entries, self) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        if (entry.intersectionRatio > 0.95) {
          header.style.color = entry.target.dataset.color !== undefined ? entry.target.dataset.color : "black";
          header.style.background = entry.target.dataset.background !== undefined ? entry.target.dataset.background : "white";   
        } else {
        if (entry.target.getBoundingClientRect().top < 0 ) {
          header.style.color = entry.target.dataset.color !== undefined ? entry.target.dataset.color : "black";
          header.style.background = entry.target.dataset.background !== undefined ? entry.target.dataset.background : "white";
          }
        } 
      }
    });
  }, config);

  sections.forEach(section => {
    observer.observe(section);
  });

});

}
字体颜色

根据内容(
div
/
部分
),默认的
标题
应能够将
字体颜色
更改为两种可能的颜色:

  • 黑色的
  • 白色的
背景色:

根据内容,
背景色
可以有无限的颜色或是透明的,因此最好解决这个问题,这些可能是最常用的背景色:

  • 白色(默认)
  • 黑色的
  • 无颜色(透明)

CSS:

header {
  position: fixed;
  width: 100%;
  top: 0;
  line-height: 32px;
  padding: 0 15px;
  z-index: 5;
  color: black; /* default */
  background-color: white; /* default */
}
<div class="grid-30-span g-100vh">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_default_header.jpg" 
    class="lazyload"
    alt="">
</div>
<div class="grid-30-span g-100vh" data-color="white" data-background="darkblue">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_darkblue.jpg" 
    class="lazyload"
    alt="">
</div>

<div class="grid-30-span g-100vh" data-color="white" data-background="black">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_black.jpg" 
    class="lazyload"
    alt="">
</div>
var mq = window.matchMedia( "(min-width: 568px)" );
if (mq.matches) {
  // Add for mobile reset

document.addEventListener("DOMContentLoaded", function(event) { 
  // Add document load callback for leaving script in head
  const header = document.querySelector('header');
  const sections = document.querySelectorAll('div');
  const config = {
    rootMargin: '0px',
    threshold: [0.00, 0.95]
  };

  const observer = new IntersectionObserver(function (entries, self) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        if (entry.intersectionRatio > 0.95) {
          header.style.color = entry.target.dataset.color !== undefined ? entry.target.dataset.color : "black";
          header.style.background = entry.target.dataset.background !== undefined ? entry.target.dataset.background : "white";   
        } else {
        if (entry.target.getBoundingClientRect().top < 0 ) {
          header.style.color = entry.target.dataset.color !== undefined ? entry.target.dataset.color : "black";
          header.style.background = entry.target.dataset.background !== undefined ? entry.target.dataset.background : "white";
          }
        } 
      }
    });
  }, config);

  sections.forEach(section => {
    observer.observe(section);
  });

});

}
Div/section示例,默认标题内容不变:

header {
  position: fixed;
  width: 100%;
  top: 0;
  line-height: 32px;
  padding: 0 15px;
  z-index: 5;
  color: black; /* default */
  background-color: white; /* default */
}
<div class="grid-30-span g-100vh">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_default_header.jpg" 
    class="lazyload"
    alt="">
</div>
<div class="grid-30-span g-100vh" data-color="white" data-background="darkblue">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_darkblue.jpg" 
    class="lazyload"
    alt="">
</div>

<div class="grid-30-span g-100vh" data-color="white" data-background="black">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_black.jpg" 
    class="lazyload"
    alt="">
</div>
var mq = window.matchMedia( "(min-width: 568px)" );
if (mq.matches) {
  // Add for mobile reset

document.addEventListener("DOMContentLoaded", function(event) { 
  // Add document load callback for leaving script in head
  const header = document.querySelector('header');
  const sections = document.querySelectorAll('div');
  const config = {
    rootMargin: '0px',
    threshold: [0.00, 0.95]
  };

  const observer = new IntersectionObserver(function (entries, self) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        if (entry.intersectionRatio > 0.95) {
          header.style.color = entry.target.dataset.color !== undefined ? entry.target.dataset.color : "black";
          header.style.background = entry.target.dataset.background !== undefined ? entry.target.dataset.background : "white";   
        } else {
        if (entry.target.getBoundingClientRect().top < 0 ) {
          header.style.color = entry.target.dataset.color !== undefined ? entry.target.dataset.color : "black";
          header.style.background = entry.target.dataset.background !== undefined ? entry.target.dataset.background : "white";
          }
        } 
      }
    });
  }, config);

  sections.forEach(section => {
    observer.observe(section);
  });

});

}

Div/section示例更改内容标题:

header {
  position: fixed;
  width: 100%;
  top: 0;
  line-height: 32px;
  padding: 0 15px;
  z-index: 5;
  color: black; /* default */
  background-color: white; /* default */
}
<div class="grid-30-span g-100vh">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_default_header.jpg" 
    class="lazyload"
    alt="">
</div>
<div class="grid-30-span g-100vh" data-color="white" data-background="darkblue">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_darkblue.jpg" 
    class="lazyload"
    alt="">
</div>

<div class="grid-30-span g-100vh" data-color="white" data-background="black">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_black.jpg" 
    class="lazyload"
    alt="">
</div>
var mq = window.matchMedia( "(min-width: 568px)" );
if (mq.matches) {
  // Add for mobile reset

document.addEventListener("DOMContentLoaded", function(event) { 
  // Add document load callback for leaving script in head
  const header = document.querySelector('header');
  const sections = document.querySelectorAll('div');
  const config = {
    rootMargin: '0px',
    threshold: [0.00, 0.95]
  };

  const observer = new IntersectionObserver(function (entries, self) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        if (entry.intersectionRatio > 0.95) {
          header.style.color = entry.target.dataset.color !== undefined ? entry.target.dataset.color : "black";
          header.style.background = entry.target.dataset.background !== undefined ? entry.target.dataset.background : "white";   
        } else {
        if (entry.target.getBoundingClientRect().top < 0 ) {
          header.style.color = entry.target.dataset.color !== undefined ? entry.target.dataset.color : "black";
          header.style.background = entry.target.dataset.background !== undefined ? entry.target.dataset.background : "white";
          }
        } 
      }
    });
  }, config);

  sections.forEach(section => {
    observer.observe(section);
  });

});

}

交叉口观察者进近:

header {
  position: fixed;
  width: 100%;
  top: 0;
  line-height: 32px;
  padding: 0 15px;
  z-index: 5;
  color: black; /* default */
  background-color: white; /* default */
}
<div class="grid-30-span g-100vh">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_default_header.jpg" 
    class="lazyload"
    alt="">
</div>
<div class="grid-30-span g-100vh" data-color="white" data-background="darkblue">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_darkblue.jpg" 
    class="lazyload"
    alt="">
</div>

<div class="grid-30-span g-100vh" data-color="white" data-background="black">
    <img 
    src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1.414 1'%3E%3C/svg%3E"
    data-src="/images/example_black.jpg" 
    class="lazyload"
    alt="">
</div>
var mq = window.matchMedia( "(min-width: 568px)" );
if (mq.matches) {
  // Add for mobile reset

document.addEventListener("DOMContentLoaded", function(event) { 
  // Add document load callback for leaving script in head
  const header = document.querySelector('header');
  const sections = document.querySelectorAll('div');
  const config = {
    rootMargin: '0px',
    threshold: [0.00, 0.95]
  };

  const observer = new IntersectionObserver(function (entries, self) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        if (entry.intersectionRatio > 0.95) {
          header.style.color = entry.target.dataset.color !== undefined ? entry.target.dataset.color : "black";
          header.style.background = entry.target.dataset.background !== undefined ? entry.target.dataset.background : "white";   
        } else {
        if (entry.target.getBoundingClientRect().top < 0 ) {
          header.style.color = entry.target.dataset.color !== undefined ? entry.target.dataset.color : "black";
          header.style.background = entry.target.dataset.background !== undefined ? entry.target.dataset.background : "white";
          }
        } 
      }
    });
  }, config);

  sections.forEach(section => {
    observer.observe(section);
  });

});

}
var mq=window.matchMedia((最小宽度:568px));
if(mq.matches){
//添加移动重置
addEventListener(“DOMContentLoaded”,函数(事件){
//添加文档加载回调,以便将脚本留在头部
const header=document.querySelector('header');
const sections=document.queryselectoral('div');
常量配置={
rootMargin:'0px',
阈值:[0.00,0.95]
};
const observer=新的IntersectionObserver(函数(条目,self){
entries.forEach(entry=>{
if(输入。isIntersecting){
如果(entry.intersectionRatio>0.95){
header.style.color=entry.target.dataset.color!==未定义?entry.target.dataset.color:“黑色”;
header.style.background=entry.target.dataset.background!==未定义?entry.target.dataset.background:“白色”;
}否则{
if(entry.target.getBoundingClientRect().top<0){
header.style.color=entry.target.dataset.color!==未定义?entry.target.dataset.color:“黑色”;
header.style.background=entry.target.dataset.background!==未定义?entry.target.dataset.background:“白色”;
}
} 
}
});
},config);
sections.forEach(section=>{
观察员:观察(第节);
});
});
}

您应该查看(IO),而不是收听滚动事件。 这是为了解决像你这样的问题而设计的。它比听滚动事件然后自己计算位置要有效得多

首先,它显示了问题的解决方案。 我不是这个代码笔的作者,我可能会做一些有点不同的事情,但它肯定会向您展示如何解决问题的基本方法

我想改变的事情:在这个例子中,你可以看到,如果你把99%的注意力集中到一个新的部分,标题会改变,即使新的部分不完全可见

现在,我们来解释一下它是如何工作的(注意,我不会盲目地从codepen复制粘贴,我也会将const改为let,但使用更适合您的项目的东西)

首先,您必须指定IO的选项:

let options = {
  rootMargin: '-50px 0px -55%'
}

let observer = new IntersectionObserver(callback, options);
在这个例子中,当一个元素距离进入视图的距离为50px时,IO就会执行回调。我不能从我的头脑中推荐一些更好的值,但如果我有时间,我会尝试调整这些参数,看看是否可以得到更好的结果

在codepen中,他们内联定义了回调函数,我只是这样写的,以便更清楚地了解在哪里发生了什么

IO的下一步是定义一些要监视的元素。在您的情况下,您应该向div添加一些类,如

最后,您必须定义回调函数:

entries.forEach(entry => {
    if (entry.isIntersecting) {
     //specify what should happen if an element is coming into view, like defined in the options. 
    }
  });
编辑:正如我所说,这只是一个关于如何开始的示例,它不是复制粘贴的完整解决方案。在基于get可见部分ID的示例中,当前元素将高亮显示。您必须更改此部分,而不是将活动类设置为,例如,第三个元素根据元素上设置的属性设置颜色和背景色。我建议使用

编辑2:当然,您可以继续使用just scroll events,W3C使用scroll events来模拟旧浏览器的IO。只是监听scroll event和计算位置不起作用,特别是在有多个元素的情况下。所以如果您关心用户体验,我真的建议您使用IO。只是想添加这个answ呃,来说明这个问题的现代解决办法是什么

编辑3:我花时间创建了一个基于IO的示例,这应该可以让您开始

基本上,我定义了两个阈值:一个为20,一个为90%。如果元素在视口中为90%,则可以保存以假设它将覆盖标题。因此,我将标题的类设置为视图中为90%的元素

第二个阈值是20%,这里我们必须检查元素是从顶部还是从底部进入视图。如果它从顶部可见20%,那么它将与标题重叠

如您所见,调整这些值并调整逻辑

const sections=document.querySelectorAll('div');
常量配置={
rootMargin:'0px',
阈值:[.2,