javascript - IntersectionObserver.observe 不是对象,如何使用 IntersectionObserver
问题描述
我正在使用 css position:sticky 创建一个带有粘性列的表。当它们“卡住”时,我想以不同的方式设置列的样式。我的第一个项目涉及在第二列部分滑过时设置第一列或 .wdtscroll td:nth-child(1) 的样式。这是javascript
const stickyElm = document.querySelector('.wdtscroll td')
const observer = new IntersectionObserver(
([e]) => e.target.classList.toggle('isSticky', e.intersectionRatio < 1),
{threshold: [1]}
);
observer.observe(stickyElm)
这是jsfiddle:https ://jsfiddle.net/g421kjcx/
虽然它肯定不是完美的,但我已经通过将其左侧位置设置为 -1px 来实现这一点,因此一旦您开始水平滚动表格,它就会被样式化。如您所见,这是有效的,但仅适用于顶部单元格。
当我在我的网站上使用此代码时,它不起作用,并且我收到一条警告:“TypeError:IntersectionObserver.observe 的参数 1 不是对象。”
当我查找它时,似乎 Object.observe 已过时。
我将如何在不使用 Object.observe 的情况下使用此 javascript,以及如何定位第一列中的所有 td。
额外的问题:当第二列或 .wdtscroll td:nth-child(2) 卡住时,我将如何设置它的样式,即使它永远不会滚动到视口之外。
谢谢!
解决方案
这是jsfiddle:https ://jsfiddle.net/g421kjcx/
这是我对您的小提琴的回应:https ://jsfiddle.net/5nfb2qdy/4/
我回答了你在这篇文章中提出的一系列问题:
如您所见,这是有效的,但仅适用于顶部单元格。...我如何“定位”第一列中的所有 td。
1)观察者的目标是单个元素(在这种情况下)。这意味着您不能依赖它来设置多个元素的样式。相反,这样做:
([e]) => {
let all_td = document.querySelectorAll('.wdtscroll td:first-child')
all_td.forEach(entry =>
entry.classList.toggle('isSticky', e.intersectionRatio < 1)
)
}
当我在我的网站上使用此代码时,它不起作用,并且我收到一条警告:“TypeError:IntersectionObserver.observe 的参数 1 不是对象。”
2) 这很可能是因为 JavaScript 是在页面上引用的元素甚至存在之前运行的。如果此代码块在<head></head>
页面的一部分中,则只需稍作修改即可使其工作:
window.onload = function(){
observer.observe(stickyElm)
}
通过将观察者激活包装在 中onload
,它不会在页面完成渲染之前运行。另一种选择是将所有这些 JavaScript 移动到页面末尾,就在您的</body></html>
额外的问题:当第二列或 .wdtscroll td:nth-child(2) 卡住时,我将如何设置它的样式,即使它永远不会滚动到视口之外。
3)也许像这样?
([e]) => {
let all_td = document.querySelectorAll('.wdtscroll td:nth-child(1)')
let all_2nd_td = document.querySelectorAll('.wdtscroll td:nth-child(2)')
all_td.forEach(entry =>
entry.classList.toggle('isSticky', e.intersectionRatio < 1)
)
all_2nd_td.forEach(entry =>
entry.classList.toggle('isSticky', e.intersectionRatio < 1)
)
}
还要将其添加到 CSS 的末尾:
.wdtscroll tr td:nth-child(2).isSticky {
background-color: pink;
}
4) 没有回答您的任何问题,但我注意到您的 CSS 通常存在一些问题。以下是我更改的内容:
CSS
/* added td to the selectors of the next 2 rules */
.wdtscroll tr:nth-child(even) td { background-color: #f2f2f2; }
.wdtscroll tr:hover td { background-color: #ddd; }
/* added tr to the selector list to override the background color set above */
.wdtscroll tr td.isSticky{
background-color: salmon;
}
5) 最后,对用于对元素进行类分配的方法进行批评。您可能有充分的理由为td
每个tr
. 这也可以更简单地通过将类属性分配给表格本身来实现,该表格本身具有应用样式的规则td:nth-child(1)
并且td:nth-child(2)
仅具有 2 个 CSS 规则。这将消除在 JavaScript 中遍历表格的每一行的需要,并利用 CSS 的特性来设置大容量元素的样式。
CSS:
.wdtscroll.isSticky tr td:nth-child(1) {
background-color: salmon;
}
.wdtscroll.isSticky tr td:nth-child(2) {
background-color: pink;
}
JavaScript:
// get the sticky element
const stickyElm = document.querySelector('.wdtscroll td')
const tableElm = document.querySelector('.wdtscroll')
const observer = new IntersectionObserver(
([e]) => {
tableElm.classList.toggle('isSticky', e.intersectionRatio < 1)
},
{threshold: [1]}
);
window.onload = function(){
observer.observe(stickyElm)
}
一个漂亮、整洁、整洁的解决方案怎么样?:) 最后的小提琴:https ://jsfiddle.net/5nfb2qdy/5/
推荐阅读
- vue.js - Vue.js | 如何访问字段:脚本标签中的类型属性
- python - 如何从 Django 中永久删除记录?
- scrapy - 尝试在不启动scrapy项目但从 .py 文件的情况下下载文件。在 python 文件中创建了自定义管道,这个错误是提到的
- jenkins - Jenkins miniOrange SAML 2.0 登录失败
- pine-script - pinescript 中的脚本警报
- netlify-function - cloudconvert API 不适用于 netlify 无服务器功能
- python - 在由三个或更多零分隔的部分中对列表元素进行计数和求和
- github - 没有合并的 PR 验证管道
- javascript - Spotify WebApi 无法获取用户播放列表数据
- css - 为什么我的 CSS 中的椭圆形 div 在我调整大小或还原它时会放在我网站的右侧墙(边框)旁边?