简体   繁体   English

IntersectionObserver.observe 不是 object,如何使用 IntersectionObserver

[英]IntersectionObserver.observe is not an object, how to use IntersectionObserver

I am creating a table with sticky columns using css position: sticky.我正在使用 css position 创建一个带有粘性列的表:粘性。 I want to style the columns differently when they are "stuck".当它们“卡住”时,我想以不同的方式设置列的样式。 My first project involves styling the first column or.wdtscroll td:nth-child(1) when the second column partially slides over it.我的第一个项目涉及在第二列部分滑过第一列或 .wdtscroll td:nth-child(1) 时对其进行样式设置。 Here is the javascript这是 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)

Here is the jsfiddle: https://jsfiddle.net/g421kjcx/这是jsfiddle: https://jsfiddle.net/g421kjcx/

While it is certainly not perfect, I have accomplished this by setting its left position at -1px so as soon as you start scrolling the table horizontally, it is styled.虽然它肯定不是完美的,但我通过将其左侧 position 设置为 -1px 来实现这一点,因此一旦您开始水平滚动表格,它就会被样式化。 As you can see this is working but only for the top cell.如您所见,这是有效的,但仅适用于顶部单元格。

When I use this code on my website, it does not work and I get a warning stating: "TypeError: Argument 1 of IntersectionObserver.observe is not an object."当我在我的网站上使用此代码时,它不起作用并且我收到一条警告:“TypeError:IntersectionObserver.observe 的参数 1 不是 object。”

When I looked it up, it seems Object.observe is obsolete.当我查看它时,似乎 Object.observe 已过时。

How would I go about using this javascript without using Object.observe, and how can I target all td's in the first column.在不使用 Object.observe 的情况下,我将如何使用 javascript,以及如何针对第一列中的所有 td。

Bonus question: How would I style the second column or.wdtscroll td:nth-child(2) when it is stuck, even though it will never scroll past the viewport.额外问题:当第二列或 .wdtscroll td:nth-child(2) 卡住时,我将如何设置它的样式,即使它永远不会滚动到视口之外。

Thank you!谢谢!

Here is the jsfiddle: https://jsfiddle.net/g421kjcx/这是jsfiddle: https://jsfiddle.net/g421kjcx/

Here is my response to your fiddle: https://jsfiddle.net/5nfb2qdy/4/这是我对您的小提琴的回应: https://jsfiddle.net/5nfb2qdy/4/

I answered a range of questions you put in this post:我回答了你在这篇文章中提出的一系列问题:

As you can see this is working but only for the top cell.如您所见,这是有效的,但仅适用于顶部单元格。 ...how can I "target" all td's in the first column. ...我如何“定位”第一列中的所有 td。

1) the target of the observer is a single element (in this case). 1)观察者的目标是单个元素(在这种情况下)。 This means you can't rely on it for styling multiple elements.这意味着您不能依赖它来设置多个元素的样式。 Instead, do it this way:相反,这样做:

([e]) => {
    let all_td = document.querySelectorAll('.wdtscroll td:first-child')
    all_td.forEach(entry =>
        entry.classList.toggle('isSticky', e.intersectionRatio < 1)
    )
}

When I use this code on my website, it does not work and I get a warning stating: "TypeError: Argument 1 of IntersectionObserver.observe is not an object."当我在我的网站上使用此代码时,它不起作用并且我收到一条警告:“TypeError:IntersectionObserver.observe 的参数 1 不是 object。”

2) This is most likely because the JavaScript is running BEFORE the elements referred to even exist on the page. 2) 这很可能是因为 JavaScript 是在页面上提到的元素甚至存在之前运行的。 If this block of code is in the <head></head> part of the page, only a slight revision is needed to make it work:如果此代码块位于页面的<head></head>部分,则只需稍作修改即可使其工作:

window.onload = function(){
    observer.observe(stickyElm)
}

By wrapping the observer activation in the onload , it won't run before the page finishes rendering.通过将观察者激活包装在onload中,它不会在页面完成渲染之前运行。 The other option is to move all of this JavaScript to the end of the page just before your </body></html>另一种选择是将所有这些 JavaScript 移动到页面末尾,就在您的</body></html>之前

Bonus question: How would I style the second column or.wdtscroll td:nth-child(2) when it is stuck, even though it will never scroll past the viewport.额外问题:当第二列或 .wdtscroll td:nth-child(2) 卡住时,我将如何设置它的样式,即使它永远不会滚动到视口之外。

3) Maybe like this? 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)
    )
}

Also add this to the end of the CSS:还将此添加到 CSS 的末尾:

.wdtscroll tr td:nth-child(2).isSticky {
  background-color: pink;
}

4) Not a response to any of your questions but I noticed some problems with your CSS in general. 4) 没有回答您的任何问题,但我注意到您的 CSS 通常存在一些问题。 Here are the things I changed:以下是我更改的内容:

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) Lastly, a critique of the approach used to do the class assignments on the elements. 5)最后,对用于对元素进行 class 分配的方法进行批评。 You may have good reason to assign class attributes on each td of each tr .您可能有充分的理由在每个tr的每个td上分配 class 属性。 This can also be achieved more simply by assigning class attributes to the table itself with rules that apply styles to td:nth-child(1) and td:nth-child(2) with only 2 CSS rules.这也可以通过将 styles 应用于td:nth-child(1)td:nth-child(2)的规则将 class 属性分配给表本身来更简单地实现。 This would eliminate the need to loop through every row of the table in the JavaScript and leverage the feature of CSS to style bulk elements.这将消除遍历 JavaScript 中表的每一行的需要,并利用 CSS 的特性来设置大容量元素的样式。

CSS: CSS:

.wdtscroll.isSticky tr td:nth-child(1) {
  background-color: salmon;
}
.wdtscroll.isSticky tr td:nth-child(2) {
  background-color: pink;
}

JavaScript: 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)
}

How's that for a nice, neat, and tidy solution?一个漂亮、整洁、整洁的解决方案怎么样? :) Final fiddle: https://jsfiddle.net/5nfb2qdy/5/ :) 最后的小提琴: https://jsfiddle.net/5nfb2qdy/5/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM