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

I am creating a table with sticky columns using css position: sticky. I want to style the columns diffe

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/

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745388868a4625567.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信