javascript - 等效于 .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 但事实并非如此。
任何帮助将不胜感激。
解决方案
你非常接近 -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);
}
}
);
});
推荐阅读
- c# - 使用 DataSet 过滤两个不同的事物
- ubuntu-18.04 - Ubuntu 18 - 扫描仪问题(EPSON v33)
- laravel - cpanel 中的 cron 作业不适用于 laravel 调度程序
- r - 如何找到R中两条曲线相交的x截距?
- java - Thread priorities no effect
- python - How to refresh front page after back-end task completed
- python - 从列表中提取整个 Python 字典并导出到 csv
- android - 当日期更改且未调用 onCreate 时更改数据库中观察到的行
- go - 为什么客户端总是从 localhost 收到“传输:收到意外的内容类型”GO 编写 GRPC 服务
- android - 如何只允许经过身份验证的用户插入 Cloud Firestore 数据库