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.
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.
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.
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.
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 }; } }
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 }; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With