нативный эквивалент javascript для .each & .attr - PullRequest
0 голосов
/ 14 декабря 2018

У меня следующий скрипт 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.

Хотелось бы, чтобы это было так просто, как изменить .attrto => setAttribute, но это не так.

Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 14 декабря 2018

Вы довольно близки - первый аргумент 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 возвращает NodeList.NodeList.prototype.forEach удобно , чтобы иметь возможность использовать, но это несколько новая функция, и, как правило, не поддерживается в браузерах старше 2016 года - для обеспечения совместимости со старыми браузерами, либо использовать полифилл, либо вызвать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);
      }
    }
  );
});
...