4

If I write this codes in separate HTML, CSS and Javascript files and open it with a browser, sticky sharebar appears when the target observed in middle of viewport height, but in codepen appears when the target observed in bottom of viewport height. What is the reason?

{
    class StickyShareBar {
        constructor(element) {
            this.element = element;
            this.contentTarget = document.getElementsByClassName('js-sticky-sharebar-target');
            this.showClass = 'sticky-sharebar--on-target';
            this.threshold = '50%'; 
            this.initShareBar();
        }

        initShareBar() {
            if(this.contentTarget.length < 1) {
              this.element.addClass( this.showClass);
              return;
            }
            if(intersectionObserverSupported) {
              this.initObserver(); 
            } else {
              this.element.addClass(this.showClass);
            }
        }

        initObserver() {
            const self = this;
            var observer = new IntersectionObserver(
              function(entries, observer) { 
                self.element.classList.toggle( self.showClass, entries[0].isIntersecting);
              }, 
              {
               rootMargin: "0px 0px -"+this.threshold+" 0px"}
            );
            observer.observe(this.contentTarget[0]);
        }
    }

    const stickyShareBar = document.getElementsByClassName('js-sticky-sharebar'),
      intersectionObserverSupported = ('IntersectionObserver' in window && 'IntersectionObserverEntry' in window && 'intersectionRatio' in window.IntersectionObserverEntry.prototype);

    new StickyShareBar(stickyShareBar[0]); 
}
Heyran.rs
  • 501
  • 1
  • 10
  • 20

4 Answers4

5

It might be a problem with rootMargin and the fact that you are using an iframe

https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-rootmargin

https://github.com/w3c/IntersectionObserver/issues/372

Ivan V.
  • 7,593
  • 2
  • 36
  • 53
1

It's because of the targeted element. When the srcollbar can reach the targeted element ( js-sticky-sharebar-target ) then the event is fired. When the content container width is smaller the scroll wheel can't reach the targeted element. For this reason it's not showing on browser or small screens. I have changed the targeted element and placed it on the top. Now it's working as you expected.

Changed HTML:

<div class="container new-js-sticky-sharebar-target">

Changed JS:

this.contentTarget = document.getElementsByClassName('new-js-sticky-sharebar-target');

See Demo

Motahar Hossain
  • 567
  • 5
  • 10
  • I don't want to change the target element. I want to sharebar appears when the target reachs to center of viewport height. – Heyran.rs May 29 '20 at 08:03
1

The IntersectionObserver spec has been expanded to allow passing a Document as an argument to root. So if you pass the Document of the iframe as the argument for root it triggers a special case where it will consider the iframe's window as the viewport and hence it will work as expected. In something like codepen you probably have no control over this but outside of that it will fix your problem.

See https://github.com/w3c/IntersectionObserver/issues/372

bryanph
  • 993
  • 7
  • 18
0

I've had this exact same issue many times when using Intersection Observer in CodePen. Like others have said, it's because CodePen renders your work in an iframe and the rootMargin doesn't work the way you might expect because of that.

I have tried pretty much every solution that has been described in other threads and this is the only one I have gotten to work: https://codepen.io/nickcil/pen/MWbqOaJ

The solution is to wrap your HTML in a full width and height element that you set to position: fixed and overflow: auto. Then set that element as the root for your observer. rootMargin will now work as expected in your pen.