最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - IntersectionObserver.observe is not an object, how to use IntersectionObserver - Stack Overflow

programmeradmin0浏览0评论

I am creating a table with sticky columns using css position: sticky. 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. Here is the 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: /

While it is certainly not perfect, I have acplished this by setting its left position at -1px so as soon as you start scrolling the table horizontally, it is styled. 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."

When I looked it up, it seems Object.observe is obsolete.

How would I go about using this javascript without using Object.observe, and how can I target all td's in the first column.

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.

Thank you!

I am creating a table with sticky columns using css position: sticky. 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. Here is the 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/g421kjcx/

While it is certainly not perfect, I have acplished this by setting its left position at -1px so as soon as you start scrolling the table horizontally, it is styled. 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."

When I looked it up, it seems Object.observe is obsolete.

How would I go about using this javascript without using Object.observe, and how can I target all td's in the first column.

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.

Thank you!

Share Improve this question asked Nov 7, 2019 at 23:00 noobdevnoobdev 311 silver badge2 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 4

Here is the jsfiddle: https://jsfiddle/g421kjcx/

Here is my response to your fiddle: https://jsfiddle/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.

1) the target of the observer is a single element (in this case). 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."

2) This is most likely because the JavaScript is running BEFORE the elements referred to even exist on the page. If this block of code is in the <head></head> part of the page, only a slight revision is needed to make it work:

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

By wrapping the observer activation in the onload, it won't run before the page finishes rendering. The other option is to move all of this JavaScript to the end of the page just before your </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.

3) Maybe like this?

([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:

.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. Here are the things I changed:

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. You may have good reason to assign class attributes on each td of each tr. 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. 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.

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

How's that for a nice, neat, and tidy solution? :) Final fiddle: https://jsfiddle/5nfb2qdy/5/

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论