javascript 原生等同于 .each & .attr

javascript native equivalent to .each & .attr

我正在尝试将以下 jQuery 脚本转换为本机 javascript。

function isElementInViewport(el) {
  //special bonus for those using jQuery
  if (typeof jQuery === "function" && el instanceof jQuery) {
    el = el[0];
  }
  var rect = el.getBoundingClientRect();
  return (
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
    rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
  );
}

$(document).on("scroll", function() {
  $(".anchor").each(function (idx, el) {
    if ( isElementInViewport(el) ) {
      if (window.history.pushState) {
        var urlHash = "#" + $(el).attr("id");
        window.history.pushState(null, null, urlHash);
      }
    }
  });
});

我试过了,

document.addEventListener('scroll', function() {
  var anchor = document.querySelectorAll(".anchor");
  anchor.forEach(function (idx, el) {
    if ( isElementInViewport(el) ) {
      if (window.history.pushState) {
        var urlHash = "#" + $(el).attr("id");
        window.history.pushState(null, null, urlHash);
      }
    }
  });
});

但我收到各种控制台错误,说 xxxxx 不是函数等。我想我没有正确转换 jQuery 迭代 (.each) & 我也不知道如何转换 $(el ) & .attr.

我希望这很简单,只需将 .attr 更改为 => setAttribute 但事实并非如此。

任何帮助将不胜感激。

您非常接近 - forEach 的第一个参数是您要迭代的 元素 ,而不是索引。 (在 jQuery 中,参数是相反的——第一个参数是 index,第二个参数是 item)。

对于 .attr('id') 部分,您可以只访问元素的普通 .id 属性:

document.addEventListener('scroll', function() {
  var anchor = document.querySelectorAll(".anchor");
  anchor.forEach(function(el) {
    if (isElementInViewport(el)) {
      if (window.history.pushState) {
        var urlHash = "#" + el.id;
        window.history.pushState(null, null, urlHash);
      }
    }
  });
});

还要注意 querySelectorAll returns 一个 NodeListNodeList.prototype.forEach 使用起来方便,但它是一个有点新的功能,通常不支持 2016 年以前的浏览器 - 以确保与旧浏览器的兼容性,或者使用 polyfill,或改为调用 Array.prototype.forEach

document.addEventListener('scroll', function() {
  Array.prototype.forEach.call(
    document.querySelectorAll(".anchor"),
    function(el) {
      if (isElementInViewport(el) && window.history.pushState) {
        var urlHash = "#" + el.id;
        window.history.pushState(null, null, urlHash);
      }
    }
  );
});