首页 > 解决方案 > isInViewport() 辅助方法不接受多个元素。抛出错误:不是函数。需要 .find() vanilla JS 等价物

问题描述

我有 jQuery 代码要翻译成 Vanilla JS。通常您可以链接查询选择器来替换 .find() 但它不起作用。

任务

使用辅助方法isInViewport()我想:

  1. 选择具有特定类名的多个元素。
  2. 循环遍历每个元素并选择它的所有后代。
  3. 使用 isInViewport() 检查后代,然后为所有后代元素设置动画。

问题

isInViewport() 仅适用于 .querySelector()。
.querySelectorAll()抛出错误“ elem.getBoundingClientRect 不是函数”。

.find() 是否有香草 JS 等价物

代码

查询:

var $window = $(window);

$window.scroll(function() {
triggerMessage();
});


function triggerMessage() {
  $('.find-my').each(function() {
    let $findMy = $(this);
    let $keys = $findMy.find('span');

    if($findMy.hasClass('animated')) {
      if(!isInViewport($keys, false)) {
        $keys.css('opacity', 0);
        $findMy.removeClass('animated');
      }
    } else if(isInViewport($keys, true)) {
      if(!$findMy.hasClass('animated')) {
        $keys.css('opacity', 1);
        $findMy.addClass('animated');
      }
    }
    if(isInViewport($keys, true)) {
      if(!$findMy.hasClass('animated')) {
        $keys.css('opacity', 1);

        $findMy.addClass('animated');
      }
    } else {
      if($findMy.hasClass('animated')) {
        $keys.css('opacity', 0);
        $findMy.removeClass('animated');
      }
    }
  });
}

function isInViewport(el) {
  if(typeof jQuery === "function" && el instanceof jQuery) {
    el = el[0];
  }
  var rect = el.getBoundingClientRect();

  if(el) {
    return (
      rect.top >= ((window.innerHeight*0.25) || (document.documentElement.clientHeight*0.25)) &&
      rect.left >= 0 &&
      rect.bottom <= ((window.innerHeight*0.75) || (document.documentElement.clientHeight*0.75)) &&
      rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
  } else {
    return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
  }
} 

JS小提琴

JS Fiddle 可以在这里找到:JS fiddle

堆栈溢出片段

triggerMessage();

function triggerMessage() {
  document.querySelectorAll('.find-my').forEach(function(element) {
    let findMy = element;
    let keys = findMy.querySelectorAll('.span');

    window.addEventListener('scroll', function(event) {
      if (findMy.classList.contains('animated')) {
        if (!isInViewport(keys)) {
          console.log('Nope...');
          keys.style.opacity = 0;
          findMy.classList.remove('animated');
          console.log('Removed class!');
        }
      } else if (isInViewport(keys)) {
        if (!findMy.classList.contains('animated')) {
          console.log('In viewport!');
          keys.style.opacity = 1;
          findMy.classList.add('animated');
          console.log('Added class!');
        }
      }
    });
  });
}




var isInViewport = function(elem) {
  var distance = elem.getBoundingClientRect();
  return (
    distance.top >= ((window.innerHeight * 0.25) || (document.documentElement.clientHeight * 0.25)) &&
    distance.left >= 0 &&
    distance.bottom <= ((window.innerHeight * 0.75) || (document.documentElement.clientHeight * 0.75)) &&
    distance.right <= (window.innerWidth || document.documentElement.clientWidth)
  );
};
span {
  opacity: 0;
}
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
<div class="find-my">
  <span>Key</span><br>
  <span>Key</span><br>
  <span>Key</span><br>
  <span>Key</span><br>
</div>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
<div class="find-my">
  <span>Key</span><br>
  <span>Key</span><br>
  <span>Key</span><br>
  <span>Key</span><br>
</div>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>
<div class="find-my">
  <span>Key</span><br>
  <span>Key</span><br>
  <span>Key</span><br>
  <span>Key</span><br>
</div>
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br> .
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>

标签: javascriptdom-traversal

解决方案


推荐阅读