我正在尝试将以下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。 / p>
我希望这很简单,只需将.attr更改为=> setAttribute,但事实并非如此。
任何帮助将不胜感激。
答案 0 :(得分:2)
您非常接近-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年的浏览器通常不支持此功能-为确保与旧版浏览器的兼容性,请使用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);
}
}
);
});