Ленивая загрузка анимации при прокрутке вниз (и удаление дополнительных библиотек JavaScript) - PullRequest
0 голосов
/ 11 июня 2019

У меня есть проблема, с которой я надеюсь, что кто-то достойный в Javascript может помочь с этим.

У меня есть эта ручка: https://codepen.io/connecteev/pen/ewYNBe

Но я хочу, чтобы этот раздел появилсяв нижней части веб-страницы и начинайте анимацию только тогда, когда раздел станет видимым на странице (на рабочем столе или на мобильном устройстве).

Я хочу изменить это перо на:

  1. загрузить этоанимация только при прокрутке вниз к разделу (ленивая загрузка)
  2. , если возможно, используйте ванильный Javascript и удалите посторонние библиотеки, такие как: https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.2/TweenMax.min.js https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.2/plugins/CSSRulePlugin.min.js

Код:

HTML:

<div class="content">

</div>

<div class="Container">
  <ul class="BlogList">
    <li class="ArticleTeaser">
      <h3 class="ArticleTeaser-title"><a href="http://zslabs.com/articles/polyno">PolyNo?</a></h3>
      <div class="ArticleTeaser-bubble"></div>
      <div class="ArticleTeaser-date">November 15th, 2015</div>
    </li>
    <li class="ArticleTeaser">
      <h3 class="ArticleTeaser-title"><a href="http://zslabs.com/articles/boomqueries">BoomQueries - Element Queries, Today</a></h3>
      <div class="ArticleTeaser-bubble"></div>
      <div class="ArticleTeaser-date">April 24th, 2015</div>
    </li>
    <li class="ArticleTeaser">
      <h3 class="ArticleTeaser-title"><a href="http://zslabs.com/articles/svg-cool-kids">Reference SVGs Like the Cool Kids</a></h3>
      <div class="ArticleTeaser-bubble"></div>
      <div class="ArticleTeaser-date">October 14th, 2014</div>
    </li>
    <li class="ArticleTeaser">
      <h3 class="ArticleTeaser-title"><a href="http://zslabs.com/articles/svg-background-fill">Modifying SVG Background Fills</a></h3>
      <div class="ArticleTeaser-bubble"></div>
      <div class="ArticleTeaser-date">September 29th, 2014</div>
    </li>
  </ul>
</div>

CSS:

html {
  height: 100%;
}

body {
  font-family: -apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Open Sans","Helvetica Neue",sans-serif;
  letter-spacing: 0;
  font-weight: 400;
  font-style: normal;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -moz-font-feature-settings: "liga" on;
  color: #686868;
  font-size: 15px;
  line-height: 1.4;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  box-sizing: border-box;
  min-height: 100%;
}
body *, body *:before, body *:after {
  box-sizing: inherit;
}

.Container {
  max-width: 800px;
  margin: 0 auto;
  padding: 0 16px;
}

.BlogList {
  padding: 16px 0;
  margin: 0;
  list-style: none;
  position: relative;
}
@media (max-width: 767px) {
  .BlogList {
    padding: 32px 0;
  }
}
.BlogList:before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  -webkit-transform: translateX(-50%);
          transform: translateX(-50%);
  background: #0177FA;
  width: 8px;
  height: 8px;
  border-radius: 50%;
}
.BlogList:after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  -webkit-transform: translateX(-50%);
          transform: translateX(-50%);
  background: #0177FA;
  width: 2px;
}

.ArticleTeaser {
  position: relative;
  padding: 32px 0;
  z-index: 2;
  visibility: hidden;
}
@media (max-width: 767px) {
  .ArticleTeaser {
    text-align: center;
    background: #fff;
    border-radius: 3px;
    padding: 16px;
    border: 2px solid #0177FA;
  }
  .ArticleTeaser:first-child {
    margin-top: 16px;
  }
  .ArticleTeaser + * {
    margin-top: 32px;
  }
}
@media (min-width: 768px) {
  .ArticleTeaser {
    display: flex;
    align-items: center;
  }
  .ArticleTeaser:before {
    opacity: 0 !important;
  }
}
.ArticleTeaser:hover .ArticleTeaser-bubble:before {
  background: #0177FA;
}
.ArticleTeaser:last-child:after {
  content: '';
  position: absolute;
  bottom: -16px;
  left: 50%;
  -webkit-transform: translateX(-50%);
          transform: translateX(-50%);
  background: #0177FA;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  visibility: visible;
}
@media (max-width: 767px) {
  .ArticleTeaser:last-child:after {
    bottom: -40px;
  }
}
.ArticleTeaser a {
  color: #686868;
  text-decoration: none;
}
.ArticleTeaser-bubble {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid #0177FA;
  -webkit-transform-origin: 50% 50%;
          transform-origin: 50% 50%;
  position: relative;
  z-index: 1;
}
.ArticleTeaser-bubble:before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: #fff;
  border-radius: 50%;
  transition: background 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  z-index: 1;
}
@media (min-width: 768px) {
  .ArticleTeaser-bubble:after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
    width: 32px;
    height: 2px;
    background: rgba(1, 119, 250, 0.25);
    z-index: -1;
  }
}
@media (max-width: 767px) {
  .ArticleTeaser-bubble {
    position: absolute;
    top: 0;
    left: 50% !important;
    -webkit-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
  }
}
.ArticleTeaser-title {
  margin: 0;
}
@media (min-width: 768px) {
  .ArticleTeaser-title {
    margin: 0 32px 0 0;
    text-align: right;
    width: 200px;
  }
}
@media (min-width: 768px) {
  .ArticleTeaser-date {
    color: #a8a8a8;
    margin: 0 0 0 32px;
    width: 200px;
  }
}

JS:

var optimizedResize = (function() {

    var callbacks = [],
        running = false;

    // fired on resize event
    function resize() {

        if (!running) {
            running = true;

            if (window.requestAnimationFrame) {
                window.requestAnimationFrame(runCallbacks);
            } else {
                setTimeout(runCallbacks, 66);
            }
        }

    }

    // run the actual callbacks
    function runCallbacks() {

        callbacks.forEach(function(callback) {
            callback();
        });

        running = false;
    }

    // adds callback to loop
    function addCallback(callback) {

        if (callback) {
            callbacks.push(callback);
        }

    }

    return {
        // public method to add additional callback
        add: function(callback) {
            if (!callbacks.length) {
                window.addEventListener('resize', resize);
            }
            addCallback(callback);
        }
    }
}());

var forEach = function (array, callback, scope) {
  for (var i = 0; i < array.length; i++) {
    callback.call(scope, i, array[i]); // passes back stuff we need
  }
};

var $articles = document.querySelectorAll('.ArticleTeaser');

setTimeout( run, 500 );

// Do the dew
function run() {
  forEach($articles, function(index, value) {
    articleAnim(value, index);

    articleHover(value);
  });
}

// Individual teaser animation
function articleAnim(element, count) {
  var at = new TimelineMax();

  at
  .set(element, {
    visibility: 'visible'
  })
  .from(element.querySelector('.ArticleTeaser-bubble'), .5, {
    scale: 0,
    delay: (count * .75),
    ease: Elastic.easeOut.config(1.5, 1)
  }, 'article-bubble')
  .from(element, .5, {
    delay: (count * .75),
    opacity: 0,
    ease: Elastic.easeOut.config(1.5, 1)
  }, 'article-bubble')
  .from(element.querySelector('.ArticleTeaser-title'), .5, {
    x: '25%',
    opacity: 0,
    ease: Elastic.easeOut.config(1.5, 1)
  }, 'article-teaser')
  .from(element.querySelector('.ArticleTeaser-date'), .5, {
    x: '-25%',
    opacity: 0,
    ease: Elastic.easeOut.config(1.5, 1)
  }, 'article-teaser');
}

// Hover animation
function articleHover(element) {
  var $articleLink = element.querySelector('.ArticleTeaser-title a');
  element.timeline = new TimelineMax({ paused: true });

  element.timeline
  .to(element.querySelector('.ArticleTeaser-bubble'), 0.15, {
    scale: 1.25
  });

  $articleLink.addEventListener('mouseenter', function() {
    element.timeline.play();
  }, false);

  $articleLink.addEventListener('mouseleave', function() {
    element.timeline.reverse();
  }, false);
}

// Reset transform position for article bubble on resize
optimizedResize.add(function() {
  forEach($articles, function(index, value) {
    if (window.matchMedia('(min-width: 768px)').matches) {
      TweenMax.set(value.querySelector('.ArticleTeaser-bubble'), {
        x: '0%',
        y: '0%'
      });
    } else {
      TweenMax.set(value.querySelector('.ArticleTeaser-bubble'), {
        x: '-50%',
        y: '-50%'
      });
    }
  });
});

1 Ответ

0 голосов
/ 11 июня 2019

Зависит от поддержки браузера Я бы предложил Наблюдателей на пересечении , если вы ищете чистый ванильный подход JS.

Если IE11 по-прежнему требуется, существует надежный полифилл , доступный от W3C.

Надеюсь, это поможет.

...