首页 > 解决方案 > jQuery 切换动画与 element.forEach

问题描述

我有以下页面,我正在使用带有 jQ​​uery 的 JavaScript 来控制动画。但是,当前代码会在页面加载时切换所有动画。我想要做的是切换动画,当元素的父 div 在视口中可见时。所以我的第一个想法是“注册” .half-widthas allModifications,但这会排除最后一个列表。
有人可以帮助我并给我一个最佳实践,告诉我应该在哪个元素上注册这个“监听器”,以便每个元素单独切换?
小例子:当第一个列表“可见”时,它应该由脚本动画。第二个列表不应该是动画的,首先当它也可见时。

//this is only to make the scroll arrow work
$(document).on('click', 'a[href^="#"]', function (event) {
    //prevent direct jump to the linked element
    event.preventDefault();

    $('html, body').animate({
        scrollTop: $($.attr(this, 'href')).offset().top
    }, 500);
});


//this function determines wether an element is visible on the current viewport or not
(function($) {
  $.fn.visible = function(partial) {
    
      var $t            = $(this),
          $w            = $(window),
          viewTop       = $w.scrollTop(),
          viewBottom    = viewTop + $w.height(),
          _top          = $t.offset().top,
          _bottom       = _top + $t.height(),
          compareTop    = partial === true ? _bottom : _top,
          compareBottom = partial === true ? _top : _bottom;
    
    return ((compareBottom <= viewBottom) && (compareTop >= viewTop));

  };
    
})(jQuery);

var win = $(window);

var allModifications = $(".container");

//make elements visible that get scrolled into the viewport
win.scroll(function(event) {
  var current = 1;
  var current2 = 1;
  allModifications.each(function(i, el) {
    var el = $(el);
    if (el.visible(true)) {
      el.find(".half-width-text").addClass("open"); 
      el.find(".list-div ul li").each(function(){
       $(this).addClass("animate").css("animation-delay", current + 's');
        current++;
      });
            el.find(".list-div2 ul li").each(function(){
       $(this).addClass("animate").css("animation-delay", current2 + 's');
        current2++;
      });
    } 
  });
  
});
body {
  margin:0;
}
.container {
  display:flex;
  flex-wrap:wrap;     
  height:100vh;
  background-color: white;
}
.container > div {
  min-height: 100vh;
  border: 1px solid black;
  box-sizing:border-box;
  background-color: inherit;
}
.container > div > a > .dot{
  position: relative;
  transition: background .2s linear;
  left: 50%;
  bottom: 10%;
  z-index: 101;
    height: 25px;
  width: 25px;
  background-color: white;
  border-radius: 50%;
  display: inline-block;
}
.container > div > a  > .dot > .arrow-down {
  transition: border .2s linear;
  position: absolute;
  top:11%;
  left: 24%;
  border: solid black;
  border-width: 0 3px 3px 0;
  display: inline-block;
  padding: 5px;
}
.container > div > a .dot:hover{
  background: black;
}
.container > div > a .dot:hover > .arrow-down{
    border: solid white;
    border-width: 0 3px 3px 0;
    display: inline-block;
    padding: 5px;
}
.container > div > a > .dot > .arrow-down{
    transform: rotate(45deg);
    -webkit-transform: rotate(45deg);
}

.container > div .content{
  height: 100vh;
  width: 100vw;
  background-color: inherit;
}
.full-width {
  width:100%;              
}
.half-width {
  width:50%;
}

.video-iframe.fullsize{
  height: 100%;
  width: 100%;
}

.list{
  text-align: center;
}

.half-width > .half-width-content{
  position: relative;
  margin-top: 0;
  height: 100%;
  width: 100%;
}
.half-width > .half-width-content > .instagram-slideshow{
  position: relative;
  height: 100%;
  width: 100%;
}
.half-width > .half-width-content > .instagram-slideshow > img{
  position: absolute;
  width: 60%;
  height: 60%;
  margin: auto;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  /*left: 50%;
  top:50%;*/
  visibility: visible;
  text-align: center;
  /*-webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);*/
}

.half-width > .half-width-content > .half-width-text {
  /*position: absolute;
  left: 50%;
  top: 50%;*/
  visibility: visible;
  /*-webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);*/
  padding-left: 50px;
    padding-right: 50px;
}
.half-width#section2 > .half-width-content, .half-width#section3 > .half-width-content {
    display: flex;
  flex-direction: column;
  justify-content: center;
}
.half-width > .half-width-content > h1{
  position: relative;
  text-align: center;
  /*top: 15%;*/
}

.half-width > .half-width-content > .half-width-text.open{
  visibility: visible;
  top: 50%;
}
.half-width-text > .middle-text{
  margin-left: -30px;
}

.list-div {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.list-div ul {
  padding: 0;
  width: 75%;

}

.list-div li {
  position: relative;
  display: block;
  margin-bottom: 5px;
  padding: 10px;
  text-align: left;
  visibility: hidden;
  text-transform: uppercase;
}
  .list-div li:nth-child(1){
background: url(https://fakeimg.pl/30x30/?text=A);
    list-style-type: none;
    margin: 0;
    padding: 10px 10px 10px 48px;
    vertical-align: middle;
    background-repeat: no-repeat;
    background-position-y: 50%;
}
.list-div li:nth-child(2){
background: url(https://fakeimg.pl/30x30/?text=B);
    list-style-type: none;
    margin: 0;
    padding: 10px 10px 10px 48px;
    vertical-align: middle;
    background-repeat: no-repeat;
    background-position-y: 50%;
 
}
.list-div li:nth-child(3){
background: url(https://fakeimg.pl/30x30/?text=C);
    list-style-type: none;
    margin: 0;
    padding: 10px 10px 10px 48px;
    vertical-align: middle;
    background-repeat: no-repeat;
    background-position-y: 50%;
 
}

.list-div li:nth-child(4){
background: url(https://fakeimg.pl/30x30/?text=D);
    list-style-type: none;
    margin: 0;
    padding: 10px 10px 10px 48px;
    vertical-align: middle;
    background-repeat: no-repeat;
    background-position-y: 50%;
}

.list-div li.animate{
  visibility: visible;
  animation: fadeIn 1s linear;
  animation-fill-mode: both;
}

@-webkit-keyframes fadeIn {
  0% {
    opacity: 0;
    top: 220px;
  }
  25%{
    opacity: 0.3;
  }
  
  75% {
    opacity: 0.5;
    top: 0px;
  }
  100% {
    opacity: 1;
  }
}

.full-width > .content > .third-parent{
  height: 100%;
  display: flex;
}

.full-width > .content > .third-parent > .third{
  position: relative;
  flex: 1 1 0px;
  border: 1px solid black;
  width: 100%;
}

.full-width > .content > .third-parent > .third > img{
  /*position: absolute;
  width: 100%;
  left: 50%;
  top:50%;*/
  visibility: visible;
  text-align: center;
  /*-webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);*/
}

.middle-text{
  position: absolute;
  width: 100%;
  left: 50%;
  top:50%;
  visibility: visible;
  text-align: center;
  -webkit-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
}

.full-width > .content > .third-parent > .third > .middle-text > .list-div2{
    display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
}

.full-width > .content > .third-parent > .third > .middle-text > .list-div2  li{
   position: relative;
  display: block;
  border: 1px solid red;
  margin-bottom: 5px;
  padding: 10px;
  text-align: left;
  text-transform: uppercase;
  visibility: hidden;
}

.list-div2 li::before{
  content: '\2022';
  margin-right: 10px;
}
.items-list2 {
  margin: 0;
  padding: 0;
}

.full-width > .content > .third-parent > .third > .middle-text > .list-div2  li.animate{
   visibility: visible;
  animation: fadeIn 1s linear;
  animation-fill-mode: both;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="full-width">
<iframe class="video-iframe fullsize" src="https://www.youtube.com/embed/osg9PmkfTB0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
    <a href="#section2">
      <span class="dot">
        <i class="arrow-down"></i>
      </span>
    </a>
  </div>
  <div class="half-width" id="section2">
    <div class="half-width-content">
              <h1>Headline</h1>
      <div class="half-width-text">

        <div class="text-content">
        <p>Some text
          </p>
        </div>
      </div>
    </div>
  </div>
  <div class="half-width">
    <div class="half-width-content">
      <div class="instagram-slideshow" id="1">
        <img class="slide" src="https://placeimg.com/640/480/animals">
      </div>
    </div>
  </div>
  <div class="half-width">
    <div class="half-width-content">
      <div class="instagram-slideshow" id="2">
        <img class="slide" src="https://fakeimg.pl/350x200/?text=Hello">
        <img class="slide" src="https://fakeimg.pl/350x200/?text=Bye">
        <img class="slide" src="https://fakeimg.pl/350x200/?text=BLA">
      </div>
    </div>
  </div>
  <div class="half-width">
    <div class="half-width-content">
	<div class="middle-text">
	<h2>Headline</h2>
      <div class="list-div">
        <ul class="items-list" id="list">
          <li>Entry A</li>
          <li>Entry B</li>
          <li>Entry C</li>
          <li>Entry D</li>
        </ul>
      </div>
    </div>
	</div>
  </div>
  <div class="full-width">
    <div class="content">
       <div class="third-parent">
         <div class="third" id="one">
           <img src="https://fakeimg.pl/350x200/?text=right">
          </div>
        <div class="third" id="two">
          <div class="middle-text">
            <h1>Headline</h1>
                  <div class="list-div2">
        <ul class="items-list2" id="list">
          <li>Entry A</li>
          <li>Entry B</li>
          <li>Entry C</li>
          <li>Entry D</li>
        </ul>
      </div>
          </div>
        </div>
        <div class="third" id="three">
          <img src="https://fakeimg.pl/350x200/?text=left">
        </div>
         </div>
       </div>
</div>
</div>

标签: javascriptjqueryhtmlcss

解决方案


您可以使用 Waypoint 库在所选项目可见时执行操作。

[下载库后][1]

[1]:https ://github.com/imakewebthings/waypoints/zipball/latest并在您的 html 文件中包含文件“noframework.waypoints.min.js”:

<script src="/path/to/noframework.waypoints.min.js"></script>

您需要使用此语法来触发事件。

var waypoint = new Waypoint({
element: document.getElementById('basic-waypoint'),
handler: function() {
notify('Basic waypoint triggered')
}
})

推荐阅读