javascript - 视口(viewport)高度差中断滚动事件

标签 javascript jquery css

我希望在某些列进入视口(viewport)后为其添加 CSS 效果。我从另一个 SO 帖子中得到了答案:See here .原始文件在 wordpress 上,我认为这并不重要。 jQuery 按预期工作,但是,经过一些故障排除后,其他 SO 帖子的答案似乎是 elemTop < viewportBottom 的条件。永远不会实现,事件永远不会触发。

<div class="content"></div>
    <div class="wrapper">
      <div class="column first-column">
        <p><strong>title</strong></p>
        <p>lorem.</p>
      </div>
      <div class="column second-column">
        <p><strong>title</strong></p>
        <p>ipsum.</p>
      </div>
      <div class="column third-column">
        <p><strong>title</strong></p>
        <p>dolor.</p>
    </div>
</div>

就codepen而言,如果我将高度设置为contentheight: 84vh;它工作得很好。更高的值会破坏功能。 我的本地开发元素有不同的维度,根本不起作用。

此外,我正在使用 Chrome。如果我没记错的话,Firefox 似乎工作正常。

我见过各种解决方案,包括:

  • 始终显示父级(父级从不隐藏)
  • 设置overflow: auto (我不确定在哪个上,但我已经尝试对所有设置)
  • 从一开始就显示相关元素(这首先违背了整个目的)

以上解决方案均无效。 这是我的 CodePen .

这是冗长的 JS 和 CSS:

function isElementInViewport(elem) {
  var $elem = $(elem);
  // Get the scroll position of the page.
  var scrollElem =
    navigator.userAgent.toLowerCase().indexOf("webkit") != -1 ? "body" : "html";
  var viewportTop = $(scrollElem).scrollTop();

  console.log(viewportTop);
  var viewportBottom = viewportTop + $(window).height();

  // Get the position of the element on the page.
  var elemTop = Math.round($elem.offset().top);
  var elemBottom = elemTop + $elem.height();

  return elemTop < viewportBottom && elemBottom > viewportTop;
}

// Check if it's time to start the animation.
function checkAnimation() {
  var $elem = $(".first-column");
  var $elemTwo = $(".second-column");
  var $elemThree = $(".third-column");

  // If the animation has already been started
  if (
    $elem.hasClass("first-column-start") ||
    $elemTwo.hasClass("second-column-start") ||
    $elemThree.hasClass("third-column-start")
  )
    return;

  if (isElementInViewport($elem)) {
    // Start the animation
    $elem.addClass("first-column-start");
    $elemTwo.addClass("second-column-start");
    $elemThree.addClass("third-column-start");
  }
}

// Capture scroll events
$(window).scroll(function() {
  checkAnimation();
});

CSS 只是一个摘录:

.wrapper {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.column {
  background: #e2e3e5;
  box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.26);
  margin: 0 32px 14px 0;
  max-width: 250px;
  padding: 1rem;
}

@keyframes fadeInLeft {
  from {
    opacity: 0;
    -webkit-transform: translate3d(-20%, 0, 0);
    transform: translate3d(-20%, 0, 0);
  }
  to {
    opacity: 1;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}
@keyframes fadeInTop {
  from {
    opacity: 0;
    -webkit-transform: translate3d(0, -20%, 0);
    transform: translate3d(0, -20%, 0);
  }
  to {
    opacity: 1;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}
@keyframes fadeInRight {
  from {
    opacity: 0;
    -webkit-transform: translate3d(20%, 0, 0);
    transform: translate3d(20%, 0, 0);
  }
  to {
    opacity: 1;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}

.first-column-start {
  -webkit-animation: fadeInLeft 0.8s;
  -moz-animation: fadeInLeft 0.8s;
  -ms-animation: fadeInLeft 0.8s;
  -o-animation: fadeInLeft 0.8s;
  animation: fadeInLeft 0.8s;
}

.second-column-start {
  -webkit-animation: fadeInTop 0.8s;
  -moz-animation: fadeInTop 0.8s;
  -ms-animation: fadeInTop 0.8s;
  -o-animation: fadeInTop 0.8s;
  animation: fadeInTop 0.8s;
}

.third-column-start {
  -webkit-animation: fadeInRight 0.8s;
  -moz-animation: fadeInRight 0.8s;
  -ms-animation: fadeInRight 0.8s;
  -o-animation: fadeInRight 0.8s;
  animation: fadeInRight 0.8s;
}

我如何使它起作用? 谢谢

最佳答案

我会使用 var viewportTop = $(document).scrollTop();

var scrollElem = navigator.userAgent.toLowerCase().indexOf("webkit") != -1 ? document : "html";`

滚动时“body”似乎确实返回 0(无可否认,我现在无法就原因提供正确的解释)

此外,最好在外部范围内维护对 Jquery 查询的引用。

var $elem = $(".first-column");
var $elemTwo = $(".second-column");
var $elemThree = $(".third-column");

function isElementInViewport(elem) {
  // Get the scroll position of the page.
  var scrollElem =
    navigator.userAgent.toLowerCase().indexOf("webkit") != -1 ? document : "html";

  var viewportTop = $(scrollElem).scrollTop();

  console.log(viewportTop);
  var viewportBottom = viewportTop + $(window).height();

  // Get the position of the element on the page.
  var elemTop = Math.round($elem.offset().top);
  var elemBottom = elemTop + $elem.height();

  return elemTop < viewportBottom && elemBottom > viewportTop;
}

// Check if it's time to start the animation.
function checkAnimation() {

  // If the animation has already been started
  if (
    $elem.hasClass("first-column-start") ||
    $elemTwo.hasClass("second-column-start") ||
    $elemThree.hasClass("third-column-start")
  )
    return;


  if (isElementInViewport($elem)) {
    console.log("Hi");
    // Start the animation
    $elem.addClass("first-column-start");
    $elemTwo.addClass("second-column-start");
    $elemThree.addClass("third-column-start");
  }
}

// Capture scroll events
$(window).scroll(function() {
  checkAnimation();
});

关于javascript - 视口(viewport)高度差中断滚动事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54777888/

相关文章:

javascript - HTML5 拖放——在 HTML 表单上放置一个计数器来计算拖放次数

javascript - 使用 angularjs 将焦点更改为下一个输入文本

javascript - 在 on() 事件中创建动态选择器

javascript - 防止刷新?

javascript - 在 textarea 上键入时突出显示文本

javascript - IE8 不动态应用 css 显示

javascript - JavaScript正则匹配是否需要重复代码?

javascript - 如何使用ajax提交已经加载ajax的表单,而不重新加载当前页面?

css - 内部服务器错误 500.19::.less mimeMap

html - Bootstrap 4 Carousel,背景为纯色,右侧为图像,左侧为文本