it-swarm.com.de

Wie erhalte ich den offset (). Top-Wert eines Elements, ohne jQuery zu verwenden?

Ich programmiere eine einseitige Anwendung mit dem Angular Framework. Ich bin neu darin. Ich habe diese Anleitung gelesen, um die grundlegenden Unterschiede zwischen jQuery und Angular zu verstehen. Ich möchte diese Anleitung so weit wie möglich befolgen und NICHT jQuery verwenden.

Abgesehen davon, dass jQuery dabei hilft, einige der Inkompatibilitäten des Browsers zu umgehen, und eine nützliche Funktionsbibliothek bereitstellt, z. B. die obere Position eines Elements vom oberen Rand des Fensters aus zu kennen, wie in $('element').offset().top. Kein einfaches Javascript scheint in der Lage zu sein, sich ohne Umschreiben dieser Funktion zu nähern. Wäre es an diesem Punkt nicht eine bessere Idee, eine jQuery- oder jQuery-ähnliche Bibliothek zu verwenden?

Insbesondere versuche ich, eine Direktive einzurichten, die ein Element fixiert, sobald der obere Rand des Elements an eine bestimmte Position im Fenster verschoben wird. So sieht es aus:

directives.scrollfix = function () {
    return {
        restrict: 'C',
        link: function (scope, element, $window) {

            var $page = angular.element(window)
            var $el   = element[0]
            var elScrollTopOriginal = $($el).offset().top - 40

            $page.bind('scroll', function () {

                var windowScrollTop = $page[0].pageYOffset
                var elScrollTop     = $($el).offset().top

                if ( windowScrollTop > elScrollTop - 40) {
                    elScrollTopOriginal = elScrollTop - 40
                    element.css('position', 'fixed').css('top', '40px').css('margin-left', '3px');
                }
                else if ( windowScrollTop < elScrollTopOriginal) {
                    element.css('position', 'relative').css('top', '0').css('margin-left', '0');
                }
            })

        }
    }
}

Wenn es einen viel besseren Weg gibt, dies in Angular zu erreichen, den ich immer noch nicht verstehe, würde ich den Rat schätzen.

43
saikofish

verwenden Sie getBoundingClientRect wenn $el das eigentliche DOM-Objekt ist:

var top = $el.getBoundingClientRect().top;

JSFiddle

Fiddle wird zeigen, dass dies den gleichen Wert bekommt, den die versetzte Spitze von Jquery Ihnen gibt </ strike>

Edit: Wie in Kommentaren erwähnt, berücksichtigt dies nicht den gescrollten Inhalt. Nachfolgend finden Sie den von jQuery verwendeten Code

https://github.com/jquery/jquery/blob/master/src/offset.js (13.05.2015)

offset: function( options ) {
    //...

    var docElem, win, rect, doc,
        elem = this[ 0 ];

    if ( !elem ) {
        return;
    }

    rect = elem.getBoundingClientRect();

    // Make sure element is not hidden (display: none) or disconnected
    if ( rect.width || rect.height || elem.getClientRects().length ) {
        doc = elem.ownerDocument;
        win = getWindow( doc );
        docElem = doc.documentElement;

        return {
            top: rect.top + win.pageYOffset - docElem.clientTop,
            left: rect.left + win.pageXOffset - docElem.clientLeft
        };
    }
}
59
Patrick Evans

Hier ist eine Funktion, die dies ohne jQuery erledigt:

function getElementOffset(element)
{
    var de = document.documentElement;
    var box = element.getBoundingClientRect();
    var top = box.top + window.pageYOffset - de.clientTop;
    var left = box.left + window.pageXOffset - de.clientLeft;
    return { top: top, left: left };
}
45
Wolverine

Anscheinend können Sie einfach die prop-Methode für das Winkelelement verwenden:

var top = $el.prop('offsetTop');

Funktioniert bei mir. Weiß jemand einen Nachteil?

10
Darren

die akzeptierte Lösung von Patrick Evans berücksichtigt das Scrollen nicht. ich habe sein jsfiddle leicht verändert, um dies zu demonstrieren: 

css: Fügen Sie eine zufällige Höhe hinzu, um sicherzustellen, dass Sie etwas Platz zum Scrollen haben

body{height:3000px;} 

js: einige Scrollposition einstellen

jQuery(window).scrollTop(100);

daher unterscheiden sich die beiden gemeldeten Werte jetzt: http://jsfiddle.net/sNLMe/66/

UPDATE 14. Februar 2015

es gibt eine Pull-Anforderung für das Warten von jqLite, einschließlich seiner eigenen Offset-Methode (unter Berücksichtigung der aktuellen Bildlaufposition). Werfen Sie einen Blick auf die Quelle, falls Sie diese selbst implementieren möchten: https://github.com/angular/angular.js/pull/3799/files

3
schellmax

Sie können element [0] .scrollTop ausprobieren, meiner Meinung nach ist diese Lösung schneller. 

Hier haben Sie ein größeres Beispiel - http://cvmlrobotics.blogspot.de/2013/03/angularjs-get-element-offset-position.html

1
bmazurek

Für Angular 2+ wird der Versatz des aktuellen Elements abgerufen (this.el.nativeElement entspricht $ (this) in jquery)

export class MyComponent implements  OnInit {

constructor(private el: ElementRef) {}

    ngOnInit() {
      //This is the important line you can use in your function in the code
      //-------------------------------------------------------------------------- 
        let offset = this.el.nativeElement.getBoundingClientRect().top;
      //--------------------------------------------------------------------------    

        console.log(offset);
    }

}
0
Combine