web-dev-qa-db-ja.com

jQueryを使用せずに要素のoffset()。top値を取得するにはどうすればよいですか?

Angularフレームワークを使用して、単一ページのアプリケーションをプログラミングしています。私はそれが初めてです。 このガイド を読んで、jQueryとAngularの基本的な違いを理解できるようにしました。できるだけこのガイダンスに従い、jQueryを使用しないでください。

JQueryは、ブラウザの非互換性を回避するのに役立ち、$('element').offset().topのようにウィンドウの上部から要素の上部の位置を知ることができるなど、便利な機能のライブラリを提供します。この関数を書き直さなければ、普通のJavascriptを近づけることはできないようです。どの時点でbejQueryまたはjQueryのようなライブラリを使用することをお勧めしますか。

具体的には、私がやろうとしているのは、ウィンドウの特定の位置までスクロールすると、その要素を修正するディレクティブを設定することです。これは次のようなものです。

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');
                }
            })

        }
    }
}

Angularでこれを達成するためのもっと良い方法がまだないのであれば、アドバイスをいただければ幸いです。

43
saikofish

$elが実際のDOMオブジェクトである場合、 getBoundingClientRect を使用します。

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

JSFiddle

Fiddleは、jqueryのoffset topが提供する値と同じ値を取得することを示します

Edit:コメントで述べたように、これはスクロールされたコンテンツを考慮しません。以下はjQueryが使用するコードです

https://github.com/jquery/jquery/blob/master/src/offset.js (5/13/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
        };
    }
}
60
Patrick Evans

JQueryなしでそれを行う関数を次に示します。

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
Paul Go

angular要素でpropメソッドを使用できるようです:

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

私のために働く。誰もこれの欠点を知っていますか?

10
Darren

patrick Evansが受け入れている解決策では、スクロールは考慮されていません。これを実証するために、彼のjsfiddleを少し変更しました。

css:スクロールするスペースを確保するために、ランダムな高さを追加します

body{height:3000px;} 

js:スクロール位置を設定します

jQuery(window).scrollTop(100);

その結果、報告された2つの値が異なるようになりました。 http://jsfiddle.net/sNLMe/66/

2015年2月14日更新

jqLit​​e待機には、独自のオフセットメソッド(現在のスクロール位置に注意)を含むプルリクエストがあります。自分で実装したい場合はソースを見てください: https://github.com/angular/angular.js/pull/3799/files

3
schellmax

Angular 2+の場合、現在の要素のオフセットを取得します(this.el.nativeElementはjqueryの$(this)と同等です):

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

Element [0] .scrollTopを試すことができますが、私の意見では、このソリューションはより高速です。

ここに大きな例があります- http://cvmlrobotics.blogspot.de/2013/03/angularjs-get-element-offset-position.html

0
bmazurek