Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在不使用jQuery的情况下获取元素的offset().top值?_Jquery_Angularjs_Window_Offset_Scrolltop - Fatal编程技术网

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

如何在不使用jQuery的情况下获取元素的offset().top值?,jquery,angularjs,window,offset,scrolltop,Jquery,Angularjs,Window,Offset,Scrolltop,我正在使用Angular框架编写一个单页应用程序。我是新手。我通过阅读帮助我理解jQuery和Angular之间的基本区别,我希望尽可能遵循这一指南,不要使用jQuery 除了jQuery有助于解决某些浏览器不兼容问题,并提供了一个有用的函数库,比如能够从窗口顶部知道元素的顶部位置,如$('element').offset().top。如果不重写此函数,任何普通Javascript似乎都无法实现,那么在哪一点上使用jQuery或类似jQuery的库不是更好吗 具体地说,我要做的是设置一个指令,一

我正在使用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');
                }
            })

        }
    }
}
directives.scrollfix=函数(){
返回{
限制:“C”,
链接:函数(范围、元素和窗口){
var$page=angular.element(窗口)
变量$el=元素[0]
var elScrollTopOriginal=$($el).offset().top-40
$page.bind('scroll',函数(){
var windowscorltop=$page[0]。pageYOffset
var elscorltop=$($el).offset().top
如果(windowScrollTop>elScrollTop-40){
elScrollTopOriginal=elScrollTop-40
css('position','fixed').css('top','40px').css('margin-left','3px');
}
否则如果(windowScrollTop
如果有更好的方法在Angular中实现这一点,而我还没有得到,我将非常感谢您的建议。

如果
$el
是实际的DOM对象,请使用:

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

Fiddle将显示,这将得到jquery的偏移顶部将提供给您的相同值

编辑:如注释中所述,这不包括滚动内容,下面是jQuery使用的代码

(2015年5月13日)


Patrick Evans接受的解决方案不考虑滚动。 为了证明这一点,我稍微改变了他的JSFIDLE:

css:添加一些随机高度,以确保我们有一些空间滚动

body{height:3000px;} 
设置一些滚动位置

jQuery(window).scrollTop(100);
因此,两个报告值现在不同:

2015年2月14日更新


jqLite等待有一个pull请求,包括它自己的偏移方法(考虑当前的滚动位置)。如果您想自己实现,请查看源代码:

您可以尝试元素[0]。scrollTop,在我看来,此解决方案速度更快


这里有一个更大的示例-

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

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

对我有用。有人知道这有什么坏处吗?

这里有一个不用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 };
}

对于Angular 2+,获取当前元素的偏移量(this.el.nativeElement在jquery中等于$(this)):


看起来这台电脑的跨浏览器兼容性也很好。谢谢。请注意,此解决方案不考虑当前的滚动位置,请参见下面我的答案。否,它不一样。这是一样的:
$el.getBoundingClientRect().top+document.body.scrollTop
那么jQuery使用的不仅仅是这些。。。你应该包括
getWindow
isWindow
等…@TJ,为什么?用户应该能够推断getWindow的功能,可以自己查找实用程序函数的代码,因为我已经链接了github repo,我相信添加代码只是为了解释一个实用程序函数会让答案变得混乱。公认的解决方案没有考虑当前的滚动位置,请参见下面的答案cvmlrobotics链接已失效。@user2602152谢谢您的评论,我已用最近找到的其他信息替换了失效链接。指向cvmlrobotics的链接已失效。当我使用元素.prepend()向DOM添加元素时;offsetTop和Left始终为0。但是,在元素检查器中,它不是0。offsetTop属性只返回相对于元素父级()的偏移量,而不像jQuery的offset()()那样返回整个文档的偏移量。在函数在摘要的第一次传递中查找$el后异步加载DOM元素的情况下,这有点繁琐。结合Darren提供的解决方案-我必须首先使用纯JS querySelector,将其包裹在角度元素中,然后才能调用道具。改造轮子(顺便说一句,不是通用的)肯定比使用“癌症”要好,是的,当然…@Regent并不是每个人都想包含一个巨大的库来完成一些原本可以用5行代码完成的事情。例如,jquery-2.1.3.min.js(83KB)不是一个巨大的文件。对于在许多地方使用jQuery的项目(不是AngularJS项目),情况如何?您是否建议编写one函数以缩短代码(可用于DOM)的长度?测试不好,有bug,没有良好的交叉浏览?我确实理解jQuery不应该在所有项目中使用,但是通过侮辱jQuery,你说它不应该在任何地方使用(顺便说一句,这是错误的说法),不是吗?我不确定我在哪里说过它“不应该在任何地方使用”。如果jQuery已经是一个需求,那么请确保使用它。但随着时间的推移和浏览器不兼容问题的解决,它的价值开始下降。虽然83kb在第一世界的光纤连接上可能不多,但大多数发展中国家就没有这么幸运了。作为一个JS库设计师,当你真的需要了解事物是如何工作的时候,那么多的帖子却不断地向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 };
}
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);
    }

}