如何在不使用 jQuery 的情况下获取元素的 offset().top 值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18953144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I get the offset().top value of an element without using jQuery?
提问by saikofish
I'm programming a single-page application using the Angular framework. I'm new to it. I've read this guideto help me understand the fundamental differences between jQuery and Angular and I'd like to follow this guidance as much as possible and NOT use jQuery.
我正在使用 Angular 框架编写单页应用程序。我是新手。我已阅读本指南以帮助我了解 jQuery 和 Angular 之间的根本区别,我想尽可能地遵循此指南,而不是使用 jQuery。
Except that jQuery helps get around some of the browser incompatibilities and provides a useful library of functions, like being able to know the top position of an element from the top of the window, as in $('element').offset().top
. No plain Javascript seems to be able to come close without rewriting this function, at which point wouldn't it bea better idea to use a jQuery or jQuery like library?
除了 jQuery 帮助解决一些浏览器不兼容问题并提供有用的函数库之外,例如能够从窗口顶部知道元素的顶部位置,如$('element').offset().top
. 没有普通的JavaScript似乎能够接近而不需要重写这个功能,在这一点岂不是一个更好的主意,用一个jQuery或类似的jQuery库?
Specifically, what I'm trying to do is set up a directive that fixes an element in place once the top of it is scrolled to a certain position in the window. Here's what it looks like:
具体来说,我想要做的是设置一个指令,一旦元素的顶部滚动到窗口中的某个位置,该指令就将元素固定到位。这是它的样子:
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');
}
})
}
}
}
If there's a much better way to achieve this in Angular that I'm still just not getting, I'd appreciate the advice.
如果在 Angular 中有更好的方法来实现这一点,但我仍然没有得到,我会很感激你的建议。
回答by Patrick Evans
use getBoundingClientRect
if $el
is the actual DOM object:
使用getBoundingClientRect
if$el
是实际的 DOM 对象:
var top = $el.getBoundingClientRect().top;
Fiddle will show that this will get the same value that jquery's offset top will give you
Fiddle 将显示这将获得与 jquery 的偏移量 top 将给您相同的值
Edit: as mentioned in comments this does not account for scrolled content, below is the code that jQuery uses
编辑:如评论中所述,这不考虑滚动内容,以下是 jQuery 使用的代码
https://github.com/jquery/jquery/blob/master/src/offset.js(5/13/2015)
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
};
}
}
回答by Paul Go
Here is a function that will do it without jQuery:
这是一个无需 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 };
}
回答by Darren
Seems you can just use the prop method on the angular element:
似乎您可以在角度元素上使用 prop 方法:
var top = $el.prop('offsetTop');
Works for me. Does anyone know any downside to this?
为我工作。有谁知道这有什么缺点吗?
回答by schellmax
the accepted solution by Patrick Evans doesn't take scrolling into account. i've slightly changed his jsfiddle to demonstrate this:
Patrick Evans 接受的解决方案没有考虑滚动。我稍微改变了他的 jsfiddle 来证明这一点:
css: add some random height to make sure we got some space to scroll
css:添加一些随机高度以确保我们有一些空间可以滚动
body{height:3000px;}
js: set some scroll position
js:设置一些滚动位置
jQuery(window).scrollTop(100);
as a result the two reported values differ now: http://jsfiddle.net/sNLMe/66/
因此,两个报告的值现在不同:http: //jsfiddle.net/sNLMe/66/
UPDATE Feb. 14 2015
2015 年 2 月 14 日更新
there is a pull request for jqLite waiting, including its own offset method (taking care of current scroll position). have a look at the source in case you want to implement it yourself: https://github.com/angular/angular.js/pull/3799/files
有一个 jqLite 等待的拉取请求,包括它自己的偏移方法(处理当前滚动位置)。如果您想自己实现它,请查看源代码:https: //github.com/angular/angular.js/pull/3799/files
回答by bmazurek
You can try element[0].scrollTop, in my opinion this solution is faster.
你可以试试 element[0].scrollTop,在我看来这个解决方案更快。
Here you have bigger example - http://cvmlrobotics.blogspot.de/2013/03/angularjs-get-element-offset-position.html
这里有更大的例子 - http://cvmlrobotics.blogspot.de/2013/03/angularjs-get-element-offset-position.html
回答by Combine
For Angular 2+ to get the offset of the current element (this.el.nativeElement is equvalent of $(this) in jquery):
对于 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);
}
}