簡體   English   中英

如何在沒有 position:sticky css 的情況下使此堆疊卡生效?

[英]How do make this stack cards effect without position:sticky css?

我如何忽略 position:sticky 屬性並在沒有 position 粘性的情況下實現相同的效果? 因為很多瀏覽器不支持這種粘性 position。 You will see there is stack-cards__item class name has a css that called position:sticky.. is there any way where i can ignore this css and keep this same stacking cards effect..

<script>document.getElementsByTagName("html")[0].className += " js";</script>
<style>
.container {
  width: 100%;
  margin-left: auto;
  margin-right: auto; }
.col {
  max-width: 100%; }
.is-visible {
  display: block !important; }
.is-hidden {
  display: none !important; }
.stack-cards {
  --stack-cards-gap: 10; }
.stack-cards__item {
  position: relative;
  position: -webkit-sticky;
  position: sticky;
  top: 10;
  height: 0;
  padding-bottom: 50%;
  -webkit-transform-origin: center top;
          transform-origin: center top;
  overflow: hidden; }
 
  .stack-cards__item > * {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%; }
  </style>
  <div class="container max-width-adaptive-md margin-bottom-lg">
      <ul class="stack-cards js-stack-cards">
        <li data-theme="default" class="stack-cards__item bg radius-lg shadow-md js-stack-cards__item">
          <div class="grid">
            <div class="col-6 flex items-center height-100%">
              <div class="text-component padding-md ">
                <h2>Card One</h2>
                <p class="display@xs">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
                <p><a href="#0" class="btn btn--accent">Read more</a></p>
              </div>
            </div>

            <div class="col-6 height-100%">
              <img class="block width-100% height-100% object-cover" src="assets/img/img-1.jpg" alt="Image description">
            </div>
          </div>
        </li>
      
        <li data-theme="default" class="stack-cards__item bg radius-lg shadow-md js-stack-cards__item">
          <div class="grid">
            <div class="col-6 flex items-center height-100%">
              <div class="text-component padding-md ">
                <h2>Card Two</h2>
                <p class="display@xs">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
                <p><a href="#0" class="btn btn--accent">Read more</a></p>
              </div>
            </div>

            <div class="col-6 height-100%">
              <img class="block width-100% height-100% object-cover" src="assets/img/img-2.jpg" alt="Image description">
            </div>
          </div>
        </li>

        <li data-theme="default" class="stack-cards__item bg radius-lg shadow-md js-stack-cards__item">
          <div class="grid">
            <div class="col-6 flex items-center height-100%">
              <div class="text-component padding-md ">
                <h2>Card Three</h2>
                <p class="display@xs">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
                <p><a href="#0" class="btn btn--accent">Read more</a></p>
              </div>
            </div>

            <div class="col-6 height-100%">
              <img class="block width-100% height-100% object-cover" src="assets/img/img-3.jpg" alt="Image description">
            </div>
          </div>
        </li>
      </ul>
    </div>
  
    <div class="container max-width-adaptive-sm">
      <div class="text-component line-height-lg v-space-md">
        <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Rem repellat non ratione eum provident quaerat obcaecati dicta autem voluptates sit cum quis distinctio, atque sint commodi reprehenderit perspiciatis iure velit molestiae eos molestias ipsa nihil quia? Porro tempore in fugit, aspernatur et temporibus aliquam magnam adipisci deleniti dicta repellat alias nostrum impedit quidem odit excepturi nam. Itaque numquam unde quae dignissimos exercitationem placeat, ipsa amet tempora vitae ullam animi! Hic asperiores in esse atque expedita dolorem officia illo commodi fugit earum ab, assumenda optio, sed repellat. Maiores laudantium reprehenderit suscipit accusamus assumenda, debitis nemo ut sapiente numquam doloremque alias explicabo minus autem harum illum dicta. Unde obcaecati inventore repellat id eligendi eaque, rerum aliquam maiores aspernatur cumque tenetur quo qui mollitia atque quasi voluptate ipsum neque explicabo voluptatem quibusdam beatae quae iste vero doloribus! Natus libero quibusdam molestias harum atque, assumenda doloribus quis, quam corporis, voluptas suscipit magni! Enim sapiente totam consequatur repellat maxime placeat perferendis iste maiores soluta, obcaecati incidunt expedita eius cumque ipsa quo sed. Minus distinctio culpa cumque labore nulla laborum ex, explicabo magni mollitia eaque aliquam vero blanditiis quae, id necessitatibus error voluptas harum tempora sint porro. Facilis beatae quasi soluta et ipsum suscipit repellendus inventore.</p>
  
        <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Possimus, ipsam molestias. Fuga similique, dolor tempora rerum perferendis ipsam ullam doloribus beatae esse facilis quae sit excepturi expedita non, sunt accusantium magnam? Animi nesciunt nostrum eligendi iusto voluptatum hic qui. Quod distinctio qui nobis et doloremque. Fuga, itaque? Laborum dignissimos nobis quaerat optio voluptatum similique unde, neque cupiditate, vel, fugiat dolore? Accusantium neque deserunt ducimus enim, illum laborum magni ipsam eos optio aspernatur nam necessitatibus quod natus, dolor laboriosam illo velit.</p>
      </div>
    </div>
<script>
  (function() {
  var StackCards = function(element) {
    this.element = element;
    this.items = this.element.getElementsByClassName('js-stack-cards__item');
    this.scrollingFn = false;
    this.scrolling = false;
    initStackCardsEffect(this); 
    initStackCardsResize(this); 
  };

  function initStackCardsEffect(element) { // use Intersection Observer to trigger animation
    setStackCards(element); // store cards CSS properties
        var observer = new IntersectionObserver(stackCardsCallback.bind(element), { threshold: [0, 1] });
        observer.observe(element.element);
  };

  function initStackCardsResize(element) { // detect resize to reset gallery
    element.element.addEventListener('resize-stack-cards', function(){
      setStackCards(element);
      animateStackCards.bind(element);
    });
  };
  
  function stackCardsCallback(entries) { // Intersection Observer callback
    if(entries[0].isIntersecting) {
      if(this.scrollingFn) return; // listener for scroll event already added
      stackCardsInitEvent(this);
    } else {
      if(!this.scrollingFn) return; // listener for scroll event already removed
      window.removeEventListener('scroll', this.scrollingFn);
      this.scrollingFn = false;
    }
  };
  
  function stackCardsInitEvent(element) {
    element.scrollingFn = stackCardsScrolling.bind(element);
    window.addEventListener('scroll', element.scrollingFn);
  };

  function stackCardsScrolling() {
    if(this.scrolling) return;
    this.scrolling = true;
    window.requestAnimationFrame(animateStackCards.bind(this));
  };

  function setStackCards(element) {
    // store wrapper properties
    element.marginY = getComputedStyle(element.element).getPropertyValue('--stack-cards-gap');
    getIntegerFromProperty(element); // convert element.marginY to integer (px value)
    element.elementHeight = element.element.offsetHeight;

    // store card properties
    var cardStyle = getComputedStyle(element.items[0]);
    element.cardTop = Math.floor(parseFloat(cardStyle.getPropertyValue('top')));
    element.cardHeight = Math.floor(parseFloat(cardStyle.getPropertyValue('height')));

    // store window property
    element.windowHeight = window.innerHeight;

    // reset margin + translate values
    if(isNaN(element.marginY)) {
      element.element.style.paddingBottom = '0px';
    } else {
      element.element.style.paddingBottom = (element.marginY*(element.items.length - 1))+'px';
    }

    for(var i = 0; i < element.items.length; i++) {
      if(isNaN(element.marginY)) {
        element.items[i].style.transform = 'none;';
      } else {
        element.items[i].style.transform = 'translateY('+element.marginY*i+'px)';
      }
    }
  };

  function getIntegerFromProperty(element) {
    var node = document.createElement('div');
    node.setAttribute('style', 'opacity:0; visbility: hidden;position: absolute; height:'+element.marginY);
    element.element.appendChild(node);
    element.marginY = parseInt(getComputedStyle(node).getPropertyValue('height'));
    element.element.removeChild(node);
  };

  function animateStackCards() {
    if(isNaN(this.marginY)) { // --stack-cards-gap not defined - do not trigger the effect
      this.scrolling = false;
      return; 
    }

    var top = this.element.getBoundingClientRect().top;

    if( this.cardTop - top + this.element.windowHeight - this.elementHeight - this.cardHeight + this.marginY + this.marginY*this.items.length > 0) { 
      this.scrolling = false;
      return;
    }

    for(var i = 0; i < this.items.length; i++) { // use only scale
      var scrolling = this.cardTop - top - i*(this.cardHeight+this.marginY);
      if(scrolling > 0) {  
        var scaling = i == this.items.length - 1 ? 1 : (this.cardHeight - scrolling*0.05)/this.cardHeight;
        this.items[i].style.transform = 'translateY('+this.marginY*i+'px) scale('+scaling+')';
      } else {
        this.items[i].style.transform = 'translateY('+this.marginY*i+'px)';
      }
    }

    this.scrolling = false;
  };

  // initialize StackCards object
  var stackCards = document.getElementsByClassName('js-stack-cards'),
    intersectionObserverSupported = ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype),
    reducedMotion = Util.osHasReducedMotion();
    
    if(stackCards.length > 0 && intersectionObserverSupported && !reducedMotion) { 
    var stackCardsArray = [];
        for(var i = 0; i < stackCards.length; i++) {
            (function(i){
        stackCardsArray.push(new StackCards(stackCards[i]));
      })(i);
    }
    
    var resizingId = false,
      customEvent = new CustomEvent('resize-stack-cards');
    
    window.addEventListener('resize', function() {
      clearTimeout(resizingId);
      resizingId = setTimeout(doneResizing, 500);
    });

    function doneResizing() {
      for( var i = 0; i < stackCardsArray.length; i++) {
        (function(i){stackCardsArray[i].element.dispatchEvent(customEvent)})(i);
      };
    };
    }
}());
</script>

幾乎就在那里,卡片后面的內容仍然存在一個小問題:它出現在粘性卡片下方。 你可以用z-index來修復這個問題。

原理是每當一張卡片到達視口頂部時,我們就克隆它,position 克隆為fixed ,並使原始卡片不可見。

以全頁模式更好地查看:

 const cards = document.querySelectorAll('.stack-cards__item'); cards.forEach(card => card.style.zIndex = 1); const offsetTop = cards[0].getBoundingClientRect().y - document.body.getBoundingClientRect().y; window.addEventListener('scroll', _e => { cards.forEach((card, index) => { const pos = card.getBoundingClientRect(); const STICK_AT = 10; if (pos.y < offsetTop) { //console.log(pos.y, pos.height); if (.card.stickyClone) { card.stickyClone = card;cloneNode(true). card.stickyClone.style;position = 'fixed'. card.stickyClone.style;width = '100%'. card.stickyClone.style;zIndex = 0. card.stickyClone.style;top = offsetTop + 'px'. card.parentNode.append(card;stickyClone). card.style;visibility = 'hidden'. } } else if (card.stickyClone) { card.style;visibility = ''. card.stickyClone;remove(). card;stickyClone = null; } }); });
 .container { background: white; /* added that for tests */ width: 100%; margin-left: auto; margin-right: auto; }.col { max-width: 100%; }.is-visible { display: block;important. }:is-hidden { display; none.important: };stack-cards { --stack-cards-gap. 10: };stack-cards__item { position: relative; top: 10px; height: 100vh; -webkit-transform-origin: center top; transform-origin: center top; overflow. hidden: };stack-cards__item > * { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
 <div class="container max-width-adaptive-md margin-bottom-lg"> <ul class="stack-cards js-stack-cards"> <li data-theme="default" class="stack-cards__item bg radius-lg shadow-md js-stack-cards__item"> <div class="grid"> <div class="col-6 flex items-center height-100%"> <div class="text-component padding-md "> <h2>Card One</h2> <p class="display@xs">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p> <p><a href="#0" class="btn btn--accent">Read more</a></p> </div> </div> <div class="col-6 height-100%"> <img class="block width-100% height-100% object-cover" src="https://picsum.photos/seed/card1/200/300" alt="Image description"> </div> </div> </li> <li data-theme="default" class="stack-cards__item bg radius-lg shadow-md js-stack-cards__item"> <div class="grid"> <div class="col-6 flex items-center height-100%"> <div class="text-component padding-md "> <h2>Card Two</h2> <p class="display@xs">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p> <p><a href="#0" class="btn btn--accent">Read more</a></p> </div> </div> <div class="col-6 height-100%"> <img class="block width-100% height-100% object-cover" src="https://picsum.photos/seed/card2/200/300" alt="Image description"> </div> </div> </li> <li data-theme="default" class="stack-cards__item bg radius-lg shadow-md js-stack-cards__item"> <div class="grid"> <div class="col-6 flex items-center height-100%"> <div class="text-component padding-md "> <h2>Card Three</h2> <p class="display@xs">Lorem ipsum dolor sit amet consectetur adipisicing elit.</p> <p><a href="#0" class="btn btn--accent">Read more</a></p> </div> </div> <div class="col-6 height-100%"> <img class="block width-100% height-100% object-cover" src="https://picsum.photos/seed/card3/200/300" alt="Image description"> </div> </div> </li> </ul> </div> <div class="container max-width-adaptive-sm"> <div class="text-component line-height-lg v-space-md"> <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Rem repellat non ratione eum provident quaerat obcaecati dicta autem voluptates sit cum quis distinctio, atque sint commodi reprehenderit perspiciatis iure velit molestiae eos molestias ipsa nihil quia? Porro tempore in fugit, aspernatur et temporibus aliquam magnam adipisci deleniti dicta repellat alias nostrum impedit quidem odit excepturi nam. Itaque numquam unde quae dignissimos exercitationem placeat, ipsa amet tempora vitae ullam animi, Hic asperiores in esse atque expedita dolorem officia illo commodi fugit earum ab, assumenda optio. sed repellat, Maiores laudantium reprehenderit suscipit accusamus assumenda. debitis nemo ut sapiente numquam doloremque alias explicabo minus autem harum illum dicta, Unde obcaecati inventore repellat id eligendi eaque, rerum aliquam maiores aspernatur cumque tenetur quo qui mollitia atque quasi voluptate ipsum neque explicabo voluptatem quibusdam beatae quae iste vero doloribus, Natus libero quibusdam molestias harum atque, assumenda doloribus quis, quam corporis. voluptas suscipit magni, Enim sapiente totam consequatur repellat maxime placeat perferendis iste maiores soluta, obcaecati incidunt expedita eius cumque ipsa quo sed. Minus distinctio culpa cumque labore nulla laborum ex. explicabo magni mollitia eaque aliquam vero blanditiis quae, id necessitatibus error voluptas harum tempora sint porro. Facilis beatae quasi soluta et ipsum suscipit repellendus inventore,</p> <p>Lorem. ipsum dolor sit amet consectetur adipisicing elit, Possimus, ipsam molestias? Fuga similique. dolor tempora rerum perferendis ipsam ullam doloribus beatae esse facilis quae sit excepturi expedita non. sunt accusantium magnam, Animi nesciunt nostrum eligendi iusto voluptatum hic qui? Quod distinctio qui nobis et doloremque, Fuga, itaque, Laborum dignissimos nobis quaerat optio voluptatum similique unde? neque cupiditate, vel, fugiat dolore. Accusantium neque deserunt ducimus enim, illum laborum magni ipsam eos optio aspernatur nam necessitatibus quod natus, dolor laboriosam illo velit.</p> </div> </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM