Angular 2: Get position of HTML element
Asked Answered
V

3

25

I'm trying to implement a custom directive in Angular 2 for moving an arbitrary HTML element around. So far everything is working except that I don't now how to get the initial position of the HTML element when I click on it and want to start moving. I'm binding to the top and left styles of my HTML element with those two host bindings:

/** current Y position of the native element. */
@HostBinding('style.top.px') public positionTop: number;

/** current X position of the native element. */
@HostBinding('style.left.px') protected positionLeft: number;

The problem is that both of them are undefined at the beginning. I can only update the values which will also update the HTML element but I cannot read it? Is that suppose to be that way? And if yes what alternative do I have to retrieve the current position of the HTML element.

Vassal answered 3/3, 2017 at 10:9 Comment(0)
S
33
<div (click)="move()">xxx</div>
// get the host element
constructor(elRef:ElementRef) {}

move(ref: ElementRef) {
  console.log(this.elRef.nativeElement.offsetLeft);
}

See also https://mcmap.net/q/40543/-retrieve-the-position-x-y-of-an-html-element

Stichomythia answered 3/3, 2017 at 10:18 Comment(2)
But offset doesn't give me the relative position of the element?Vassal
Your question doesn't say anything about "relative". offsetLeft is just an example. The rest is the same as in plain JavaScript, this is why I added the link to my answer.Woollen
C
33

In typeScript you can get the position as follows:

@ViewChild('ElementRefName') element: ElementRef;

const {x, y} = this.element.nativeElement.getBoundingClientRect();
Comfit answered 4/12, 2018 at 15:44 Comment(4)
This solution won't work when the browser is not at 100% sizeDecile
What will work when the browser is not at 100% size?Ji
@ViewChild('ElementRefName') element: ElementRef; is an error now in Angular 13: error TS2564: Property 'element' has no initializer and is not definitely assigned in the constructor.Copaiba
@b264: that's just formality. You can solve it like that: @ViewChild('ElementRefName') element!: ElementRef; or @ViewChild('ElementRefName') element: ElementRef|undefined;Rata
S
10

in html:

<div (click)="getPosition($event)">xxx</div>

in typescript:

getPosition(event){
    let offsetLeft = 0;
    let offsetTop = 0;

    let el = event.srcElement;

    while(el){
        offsetLeft += el.offsetLeft;
        offsetTop += el.offsetTop;
        el = el.parentElement;
    }
    return { offsetTop:offsetTop , offsetLeft:offsetLeft }
}
Stop answered 21/9, 2018 at 13:53 Comment(2)
Testing this in an Angular app now and it's giving odd values (very high numbers). I don't believe a child's offset is the simple aggregation of all of it's parents offsets. I believe the correct property is offsetParent.Crocodilian
@Crocodilian Yes, I'm using offsetParent instead of parentElement and it appears to be working.Flasket

© 2022 - 2024 — McMap. All rights reserved.