如何在不使用jQuery的情况下获取元素的offset().top值?

sai*_*ish 44 jquery window offset scrolltop angularjs

我正在使用Angular框架编写单页应用程序.我是新手.我已阅读本指南,以帮助我理解jQuery和Angular之间的根本区别,我想尽可能地遵循本指南,而不是使用jQuery.

除了jQuery有助于解决一些浏览器不兼容问题并提供一个有用的函数库,比如能够从窗口顶部知道元素的顶部位置,如$('element').offset().top.没有普通的JavaScript似乎能够接近而不需要重写这个功能,在这一点岂不一个更好的主意,用一个jQuery或类似的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');
                }
            })

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果在Angular中有更好的方法来实现这一点,我仍然没有得到,我会很感激这个建议.

Pat*_*ans 60

使用getBoundingClientRectif $el是实际的DOM对象:

var top = $el.getBoundingClientRect().top;
Run Code Online (Sandbox Code Playgroud)

的jsfiddle

小提琴将显示这将获得与jquery的偏移顶部将给你的相同的值

编辑:如评论中所述,这不包括滚动内容,下面是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
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,此解决方案不考虑当前的滚动位置,请参阅下面的答案 (4认同)
  • 不,这不一样.这是一样的:`$ el.getBoundingClientRect().top + document.body.scrollTop` (3认同)

Pau*_* Go 45

这是一个没有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 };
}
Run Code Online (Sandbox Code Playgroud)

  • @Regent并不是每个人都希望包含一个巨大的库来做一些其他方式可以在5行代码中完成的事情. (17认同)
  • 我不确定我在哪里说它"不应该在任何地方使用".如果jQuery已经是一个要求,那么请确保使用它.但随着时间的推移和浏览器的不兼容性得到解决,它的价值开始减弱.虽然83kb在你的第一世界光纤连接上可能不是很多,但很多发展中国家并不是那么幸运.作为一个JS库设计师,令人沮丧的是,当你真正需要了解事情是如何运作的时候,有很多SO帖子不断向jQuery发帖.见http://youmightnotneedjquery.com/ (15认同)

Dar*_*ren 10

似乎你可以在角元素上使用prop方法:

var top = $el.prop('offsetTop');
Run Code Online (Sandbox Code Playgroud)

适合我.有谁知道这有什么缺点?