posicion - scroll jquery
¿Cómo obtengo el valor superior de offset(). De un elemento sin usar jQuery? (5)
Estoy programando una aplicación de una sola página usando el marco angular. Soy nuevo en eso. He leído esta guía para ayudarme a comprender las diferencias fundamentales entre jQuery y Angular, y me gustaría seguir esta guía tanto como sea posible y NO utilizar jQuery.
Excepto que jQuery ayuda a evitar algunas de las incompatibilidades del navegador y proporciona una útil biblioteca de funciones, como la posibilidad de conocer la posición superior de un elemento desde la parte superior de la ventana, como en $(''element'').offset().top
. No parece que JavaScript simple pueda acercarse sin reescribir esta función, ¿en ese momento no sería una mejor idea usar una biblioteca jQuery o jQuery?
Específicamente, lo que estoy tratando de hacer es configurar una directiva que corrige un elemento en su lugar una vez que la parte superior se desplaza a una posición determinada en la ventana. Esto es lo que parece:
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'');
}
})
}
}
}
Si hay una forma mucho mejor de lograr esto en Angular que todavía no estoy obteniendo, agradecería el consejo.
Aquí hay una función que lo hará sin 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 };
}
Parece que puedes usar el método prop en el elemento angular:
var top = $el.prop(''offsetTop'');
Funciona para mi. ¿Alguien sabe alguna desventaja de esto?
Puedes probar el elemento [0] .scrollTop, en mi opinión esta solución es más rápida.
Aquí tienes un ejemplo más grande: http://cvmlrobotics.blogspot.de/2013/03/angularjs-get-element-offset-position.html
la solución aceptada por Patrick Evans no tiene en cuenta el desplazamiento. He cambiado ligeramente su jsfiddle para demostrar esto:
CSS: agrega algo de altura aleatoria para asegurarte de que tenemos espacio suficiente para desplazarnos
body{height:3000px;}
js: establecer un poco de posición de desplazamiento
jQuery(window).scrollTop(100);
como resultado, los dos valores informados difieren ahora: http://jsfiddle.net/sNLMe/66/
ACTUALIZACIÓN 14 de febrero de 2015
hay una solicitud de extracción para la espera de jqLite, incluido su propio método de compensación (teniendo en cuenta la posición de desplazamiento actual). eche un vistazo a la fuente en caso de que quiera implementarla usted mismo: https://github.com/angular/angular.js/pull/3799/files
use getBoundingClientRect
si $el
es el objeto DOM real:
var top = $el.getBoundingClientRect().top;
Fiddle mostrará que obtendrá el mismo valor que la tapa compensada de jquery le dará
Editar : como se menciona en los comentarios, esto no tiene en cuenta el contenido desplazado, a continuación se muestra el código que jQuery usa
https://github.com/jquery/jquery/blob/master/src/offset.js (13/05/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
};
}
}