4

In jQuery element.offset().top gives on fixed element current position from the document top. When I'm scrolling down it grows up when scrolling up the offset top value decreses.

Now I need the same behavior in Angular 4, but I'm something missing, my offset top value is still the same.

Please see the attached Plunker: https://embed.plnkr.co/3sDzpRcJMEN6lndw4MUB

 @Component({
  selector: '[my-app]',
  template: `
    <div>
      <h2>There is document top</h2>
      <div class="fixed-box" #fixedBox>
        <p>I'm fixed box</p>
        <p>I wanna know my offset from the document top (not viewport) in every scroll step</p>
        <p>My current position from the document top is: {{ fixedBoxOffsetTop }}px</p>
        <p>My current position from the document top is: {{ fixedBoxOffsetTopOtherMethod }}px</p>
      </div>
    </div>
  `,
})
export class App implements OnInit {
  fixedBoxOffsetTop: number  = 0;
  fixedBoxOffsetTopOtherMethod: number = 0;

  @ViewChild('fixedBox') fixedBox: ElementRef;

  constructor() {}

  ngOnInit() {}

  @HostListener("window:scroll", [])
  onWindowScroll() {
    this.fixedBoxOffsetTop = this.fixedBox.nativeElement.offsetTop; // This value looks like init value and doesn't change during scroll
    this.fixedBoxOffsetTopOtherMethod = this.fixedBox.nativeElement.getBoundingClientRect().top; // The same result as offsetTop
  }
}

Can anybody help?

1
  • You probably want to include the code in the body of your question. That link will certainly expire one day, leaving this question bereft of meaning. Commented Aug 1, 2017 at 20:29

2 Answers 2

7

You missed window and document offsets:

const rect = this.fixedBox.nativeElement.getBoundingClientRect();
this.fixedBoxOffsetTop = rect.top + window.pageYOffset - document.documentElement.clientTop;

Forked Plunker

Sign up to request clarification or add additional context in comments.

5 Comments

That's still not catering for window resizing... ;-)
@JGFMK He does not listen resize event. See this plnkr.co/edit/PLZfad6kQZuHR3qAqxWk?p=preview
plnkr.co/edit/Z0cSqqJJXWw6dpPeHMbs?p=preview - this does and outputs it initially. I think there is a way to bind multiple events to a handler too btw - github.com/TheLarkInn/angular2-multievent-bindings-plugin/blob/…
Learnt something there - didn't realise you could more than one HostListener on a single method...
Thank you, exactly what I was looking for. It's a pitty that you need for that two lines instead of one word. If somebody want one word, there is custom function: ` /** * Return element coordinates relative to document * @param element * @returns {number} */ getCurrentOffsetTop(element: ElementRef) { const rect = element.nativeElement.getBoundingClientRect(); return rect.top + window.pageYOffset - document.documentElement.clientTop; }`
-1

There is my method for that:

getCurrentOffsetTop(element: ElementRef) {
  const rect = element.nativeElement.getBoundingClientRect();
  return rect.top + window.pageYOffset - document.documentElement.clientTop;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.