首页 > 解决方案 > 等效于 .each 和 .attr 的 javascript 原生

问题描述

我有以下 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 但事实并非如此。

任何帮助将不胜感激。

标签: javascriptjqueryeachnative

解决方案


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

对于这一.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返回一个NodeList. NodeList.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);
      }
    }
  );
});

推荐阅读