Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the offset().top value of an element without using jQuery?

I'm programming a single-page application using the Angular framework. I'm new to it. I've read this guide to 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.

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 be a better idea to use a jQuery or jQuery like library?

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.

like image 704
saikofish Avatar asked Sep 23 '13 06:09

saikofish


People also ask

What is offset () Top?

The offsetTop property returns the top position (in pixels) relative to the parent. The returned value includes: the top position, and margin of the element. the top padding, scrollbar and border of the parent.

How use offset top in Javascript?

jQuery offset() MethodThe offset() method set or returns the offset coordinates for the selected elements, relative to the document. When used to return the offset: This method returns the offset coordinates of the FIRST matched element. It returns an object with 2 properties; the top and left positions in pixels.

How do you offset top in CSS?

Use 'top' to offset the top of an element from the top of its position. top aligns the top side of an absolute element to the top side of its container.


2 Answers

use getBoundingClientRect if $el is the actual DOM object:

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

JSFiddle

Fiddle will show that this will get the same value that jquery's offset top will give you

Edit: as mentioned in comments this does not account for scrolled content, below is the code that jQuery uses

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         };     } } 
like image 155
Patrick Evans Avatar answered Sep 20 '22 01:09

Patrick Evans


Here is a function that will do it without 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 }; } 
like image 29
Paul Go Avatar answered Sep 20 '22 01:09

Paul Go