【问题标题】:Intersection Observer: Remove/ Add classes based on <header> and <footer> viewport positionIntersection Observer:根据 <header> 和 <footer> 视口位置删除/添加类
【发布时间】:2020-01-02 11:49:38
【问题描述】:

我有一个关于Intersection Observer 的问题。

正如您在 my code 中看到的,当您向下滚动到 &lt;footer&gt; 时,.product-photo (T-Shirt) 保持不变,我不确定如何正确添加.absolute 类使其位于容器的底部。

注意:我知道 css 的 position: sticky 但它不适用于这种特殊情况


我的目标:制作 T 恤形象...

static 当标题可见时
fixed 当标题不在视图中时
absolute 当页脚可见时

除了absolute 类之外,我什么都可以工作

const photo = document.querySelector(".product-photo");
const header = document.querySelector("header");

const sectionOptions = {
	root: null
};

const sectionObserver = new IntersectionObserver(function(entries, sectionObserver) {
  entries.forEach(entry => {
    if (!entry.isIntersecting) {
      photo.classList.add("fixed");
    } 
		else {
      photo.classList.remove("fixed");
    }
  });
}, sectionOptions);


sectionObserver.observe(header);
* { margin: 0; padding: 0; box-sizing: border-box; font-family: roboto; }

header, footer { background: black; color: white; padding: 2rem; }
footer { height: 100vh; }
main { background: white; padding: 1rem; }
section { margin: 2rem 0; }
h1, h2 { margin: 0 0 1rem; font-size: 2rem; }
p { margin: 0 0 2rem; font-size: 1.2rem; line-height: 1.4; }
img { max-width: 100%; }

/* styles
****************************************/
.announcement { background: #f2f2f2; font-size: 2rem; padding: 2rem; text-align: center; border: 3px dashed rgba(0,0,0,.2); margin-top: 0; }
.product { height: 100%; display: flex; justify-items: space-between; position: relative; }
.product-photo { width: 50%; }
.product-description { width: 50%; }
.recommended-products { display: flex; }

/* Sticky Classes */
.product-photo.fixed img { position: fixed; top: 0; left: 0; width: 50%; }
.product-photo.absolute img { position: absolute; left: 0; bottom: 0; width: 50%; }

/* .fixed { position: fixed; top: 0; left: 0; right: 0; } */




/* Mobile */
@media (min-width: 0) and (max-width: 768px) { 
	.product { display: flex; flex-direction: column; }
	.product-photo { width: 100%; }
	.product-description { width: 100%; }
}
  
/* Tablet */
@media (min-width: 769px) and (max-width: 1024px) { 
	
    
}
  
/* Desktop */
@media (min-width: 1025px) { 
	
    
}
<header>Header</header>
<main>
	
	<!-- Product -->
	<section class="product">
		<figure class="product-photo">
			<img src="https://cdn.shopify.com/s/files/1/0078/6825/2273/products/SSCrew_TrueBlack_Front_1950x.png" alt="Black T-Shirt">
		</figure>
		<article class="product-description">
			<h1>Black T-Shirt</h1>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
		</article>
	</section>
</main>
<footer>Footer</footer>

【问题讨论】:

    标签: javascript scroll sticky sticky-footer intersection-observer


    【解决方案1】:

    footer 添加到观察者并添加/删除fixedabsolute 类,方法是测试页眉/页脚的isIntersecting,您可以使用entry.target.tagName 在您的情况下获得这些类:

    const header = document.querySelector("header");
    const footer = document.querySelector("footer");
    
    const sectionOptions = {
        root: null
    };
    
    const sectionObserver = new IntersectionObserver(function(entries, sectionObserver) {
      const headerEntry = entries.find(entry => entry.target.tagName === 'HEADER');
      const footerEntry = entries.find(entry => entry.target.tagName === 'FOOTER');
      if (headerEntry && headerEntry.isIntersecting) {
        photo.classList.remove("fixed");
      } else if(footerEntry && footerEntry.isIntersecting) {
        photo.classList.remove("fixed");
        photo.classList.add("absolute");
      } else {
        photo.classList.add("fixed");
        photo.classList.remove("absolute");
      }
    }, sectionOptions);
    
    
    sectionObserver.observe(header);
    sectionObserver.observe(footer);
    

    实例:

    const photo = document.querySelector(".product-photo");
    const header = document.querySelector("header");
    const footer = document.querySelector("footer");
    
    const sectionOptions = {
    	root: null
    };
    
    const sectionObserver = new IntersectionObserver(function(entries, sectionObserver) {
      const headerEntry = entries.find(entry => entry.target.tagName === 'HEADER');
      const footerEntry = entries.find(entry => entry.target.tagName === 'FOOTER');
      if (headerEntry && headerEntry.isIntersecting) {
        photo.classList.remove("fixed");
      } else if(footerEntry && footerEntry.isIntersecting) {
        photo.classList.remove("fixed");
        photo.classList.add("absolute");
      } else {
        photo.classList.add("fixed");
        photo.classList.remove("absolute");
      }
    }, sectionOptions);
    
    
    sectionObserver.observe(header);
    sectionObserver.observe(footer);
    * { margin: 0; padding: 0; box-sizing: border-box; font-family: roboto; }
    
    header, footer { background: black; color: white; padding: 2rem; }
    footer { height: 100vh; }
    main { background: white; padding: 1rem; }
    section { margin: 2rem 0; }
    h1, h2 { margin: 0 0 1rem; font-size: 2rem; }
    p { margin: 0 0 2rem; font-size: 1.2rem; line-height: 1.4; }
    img { max-width: 100%; }
    
    /* styles
    ****************************************/
    .announcement { background: #f2f2f2; font-size: 2rem; padding: 2rem; text-align: center; border: 3px dashed rgba(0,0,0,.2); margin-top: 0; }
    .product { height: 100%; display: flex; justify-items: space-between; position: relative; }
    .product-photo { width: 50%; }
    .product-description { width: 50%; }
    .recommended-products { display: flex; }
    
    /* Sticky Classes */
    .product-photo.fixed img { position: fixed; top: 0; left: 0; width: 50%; }
    .product-photo.absolute img { position: absolute; left: 0; bottom: 0; width: 50%; }
    
    /* .fixed { position: fixed; top: 0; left: 0; right: 0; } */
    
    
    
    
    /* Mobile */
    @media (min-width: 0) and (max-width: 768px) { 
    	.product { display: flex; flex-direction: column; }
    	.product-photo { width: 100%; }
    	.product-description { width: 100%; }
    }
      
    /* Tablet */
    @media (min-width: 769px) and (max-width: 1024px) { 
    	
        
    }
      
    /* Desktop */
    @media (min-width: 1025px) { 
    	
        
    }
    <header>Header</header>
    <main>
    	
    	<!-- Product -->
    	<section class="product">
    		<figure class="product-photo">
    			<img src="https://cdn.shopify.com/s/files/1/0078/6825/2273/products/SSCrew_TrueBlack_Front_1950x.png" alt="Black T-Shirt">
    		</figure>
    		<article class="product-description">
    			<h1>Black T-Shirt</h1>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    			<p>This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. This is some content. </p>
    		</article>
    	</section>
    </main>
    <footer>Footer</footer>

    【讨论】:

    • 这是一个有趣的解决方案!但是,如果页脚是相交的,我将如何添加类 absolute 并删除类 fixed.product-photo
    • 宾果游戏!这正是我想要做的:)
    猜你喜欢
    • 2012-04-27
    • 2015-04-27
    • 1970-01-01
    • 1970-01-01
    • 2022-12-15
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 2021-12-07
    相关资源
    最近更新 更多