[Diccionario front-end] Comparación de 4 formas de lograr un techo rodante

Prefacio

La primera solicitud que recibí de la segunda empresa a la que me uní fue para reparar el efecto de techo rodante que anteriormente se subcontrataba. Me preguntaba por qué hay un error en un techo de desplazamiento. Más tarde verifiqué el código y descubrí que el atributo offsetTop se usó directamente y no se realizó ningún tratamiento de compatibilidad.

offsetTop

Se utiliza para obtener la distancia (valor de compensación) desde el elemento actual hasta la parte superior del padre de posicionamiento (element.offsetParent).

La definición de posicionamiento padre offsetParent es: el elemento padre de la posición más cercana! = Estático al elemento actual.

Quizás la persona que escribió este código no se dio cuenta de la condición secundaria de "localizar al padre".

Más adelante, en el proyecto, siempre habrá el efecto del techo rodante que debe realizarse. Ahora daré una introducción detallada a los 4 métodos de techo rodante que conozco.

Tabla de contenido

  1. Posición de uso: pegajosa para lograr

  2. Utilice la implementación superior offset (). De JQuery

  3. Utilice la implementación nativa offsetTop

  4. Utilice obj.getBoundingClientRect (). Top para lograr

¿Conoce los cuatro métodos anteriores? El código relevante se ha subido a GitHub ( https://github.com/wanqihua/The-dictionary-of-front-end-test), y los interesados ​​pueden clonar el código y ejecutarlo localmente. Espero dar un apoyo estrella.

Cuatro formas de lograr

Uno, posición de uso: pegajosa para lograr

1. ¿Qué es el posicionamiento fijo?

El posicionamiento fijo es equivalente a la combinación de posicionamiento relativo relativo y posicionamiento fijo; durante el proceso de desplazamiento de los elementos de la página, cuando la distancia entre un elemento y su elemento principal alcanza el requisito de posicionamiento fijo; el efecto relativo del posicionamiento relativo del elemento se convierte en un posicionamiento fijo fijo Efecto.

2. ¿Cómo se usa?

Condiciones de Uso:

  1. El elemento padre no puede tener desbordamiento: oculto o desbordamiento: atributos automáticos

  2. Debe especificar uno de los 4 valores superior, inferior, izquierdo, derecho; de lo contrario, solo estará en posición relativa

  3. La altura del elemento principal no puede ser menor que la altura del elemento adhesivo

  4. El elemento adhesivo solo tiene efecto dentro de su elemento principal

Este efecto se puede lograr agregando los siguientes estilos a los elementos que deben desplazarse y al techo:

.sticky {

    position: -webkit-sticky;

    position: sticky;

    top: 0;

}

3. ¿Es este atributo fácil de usar?

Primero echemos un vistazo a la compatibilidad de este atributo en ¿Puedo usar:
[Diccionario front-end] Comparación de 4 formas de lograr un techo rodante

Se puede observar que la compatibilidad de este atributo no es muy buena, porque esta API es solo un atributo experimental. Sin embargo, la compatibilidad de esta API en el sistema IOS sigue siendo relativamente buena.

Por lo tanto, si usamos esta API en un entorno de producción, generalmente la usaremos en combinación con los siguientes métodos.

En segundo lugar, use la implementación offset (). Top de JQuery

Sabemos que JQuery encapsula la API para manipular DOM y leer las propiedades de cálculo de DOM. Basado en la combinación de offset (). Top y scrollTop (), también podemos lograr el efecto de desplazamiento de techo.

...

window.addEventListener('scroll', self.handleScrollOne);

...

handleScrollOne: function() {

    let self = this;

    let scrollTop = $('html').scrollTop();

    let offsetTop = $('.title_box').offset().top;

    self.titleFixed = scrollTop > offsetTop;

}

...

Esto es ciertamente posible, pero dado que JQuery se está retirando lentamente de la etapa de la historia, intentamos no usar la API de JQuery en el código. Podemos manejar el offsetTop nativo nosotros mismos basándonos en el código fuente de offset (). Top. Entonces hay una tercera forma.

scrolloTop () tiene problemas de compatibilidad. En los navegadores WeChat, IE y algunas versiones de Firefox, el valor de $ ('html'). scrollTop () será 0, por lo que casi no hay compatibilidad del tercer esquema .

En tercer lugar, use la implementación nativa offsetTop

Sabemos que offsetTop es el desplazamiento relativo al padre de posicionamiento. Si el elemento que necesita desplazarse hacia la parte superior parece posicionar el elemento padre, entonces offsetTop no obtiene la distancia entre el elemento y la parte superior de la página.

Podemos hacer el siguiente procesamiento en offsetTop nosotros mismos:

getOffset: function(obj,direction){

    let offsetL = 0;

    let offsetT = 0;

    while( obj!== window.document.body && obj !== null ){

        offsetL += obj.offsetLeft;

        offsetT += obj.offsetTop;

        obj = obj.offsetParent;

    }

    if(direction === 'left'){

        return offsetL;

    }else {

        return offsetT;

    }

}

utilizar:

...

window.addEventListener('scroll', self.handleScrollTwo);

...

handleScrollTwo: function() {

    let self = this;

    let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;

    let offsetTop = self.getOffset(self.$refs.pride_tab_fixed);

    self.titleFixed = scrollTop > offsetTop;

}

...

¿Ve algunos problemas con los dos métodos anteriores?

¿Necesitamos usar el valor de scrollTop-offsetTop para lograr el efecto de desplazamiento del techo? la respuesta es negativa.

Veamos juntos la cuarta opción.

Cuarto, use obj.getBoundingClientRect (). Top para lograr

definición:

Esta API puede indicarle la distancia de un elemento en la página en relación con la ventana del navegador.

utilizar:

Para el techo de la pestaña, puede usar obj.getBoundingClientRect (). Top en lugar de scrollTop-offsetTop, el código es el siguiente:

// html

<div class="pride_tab_fixed" ref="pride_tab_fixed">

    <div class="pride_tab" :class="titleFixed == true ? 'isFixed' :''">

        // some code

    </div>

</div>

// vue

export default {

    data(){

      return{

        titleFixed: false

      }

    },

    activated(){

      this.titleFixed = false;

      window.addEventListener('scroll', this.handleScroll);

    },

    methods: {

      //滚动监听,头部固定

      handleScroll: function () {

        let offsetTop = this.$refs.pride_tab_fixed.getBoundingClientRect().top;

        this.titleFixed = offsetTop < 0;

        // some code

      }

    }

  }

La diferencia entre offsetTop y getBoundingClientRect ()

1. getBoundingClientRect ():

Se utiliza para obtener la posición de la parte izquierda, superior, derecha e inferior de un elemento en la página en relación con la ventana del navegador. No incluye la parte enrollada del documento.

Esta función devuelve un objeto objeto con 6 atributos: superior, derecha, inferior, izquierda, ancho, alto. (En IE, las coordenadas predeterminadas se calculan a partir de (2,2), y solo se devuelven cuatro valores de superior, izquierda, derecha e inferior)

2. offsetTop:

Se utiliza para obtener la distancia (valor de compensación) desde el elemento actual hasta la parte superior del padre de posicionamiento (element.offsetParent).

La definición de posicionamiento padre offsetParent es: el elemento padre de la posición más cercana! = Estático al elemento actual.

Los métodos offsetTop y offsetParent se combinan para obtener la distancia desde el elemento hasta el margen superior del cuerpo. el código se muestra a continuación:

getOffset: function(obj,direction){

    let offsetL = 0;

    let offsetT = 0;

    while( obj!== window.document.body && obj !== null ){

        offsetL += obj.offsetLeft;

        offsetT += obj.offsetTop;

        obj = obj.offsetParent;

    }

    if(direction === 'left'){

        return offsetL;

    }else {

        return offsetT;

    }

}

Conocimiento extendido

offsetWidth:

El tamaño del espacio ocupado por el elemento en la dirección horizontal:
offsetWidth = border-left + padding-left + width + padding-right + border-right

offsetHeight:

El tamaño del espacio ocupado por el elemento en la dirección vertical:
offsetHeight = border-top + padding-top + height + padding-bottom + border-bottom

Nota: Si hay una barra de desplazamiento vertical, offsetWidth también incluye el ancho de la barra de desplazamiento vertical; si hay una barra de desplazamiento horizontal, offsetHeight también incluye la altura de la barra de desplazamiento horizontal;

offsetTop:

La distancia de píxeles entre el borde exterior superior del elemento y el borde interior superior del elemento offsetParent;

offsetLeft:

La distancia en píxeles desde el borde exterior izquierdo del elemento al borde interior izquierdo del elemento offsetParent;

Precauciones

  1. Todos los atributos de compensación son de solo lectura;

  2. Si display: none se establece para el elemento, su atributo de desplazamiento es todo 0;

  3. Cada vez que acceda al atributo de compensación, debe volver a calcular (guardar la variable);

  4. Al usarlo, puede parecer que el DOM no está inicializado y el atributo se lee. En este momento, se devolverá 0; para este problema, debemos esperar hasta que se inicialice el elemento DOM antes de ejecutar.

Dos problemas encontrados

1. El momento de succión se acompaña de fluctuación

La razón de la fluctuación es porque: cuando la posición del elemento superior se vuelve fija, el elemento está fuera del flujo de documentos y el siguiente elemento se llena. Es esta operación de llenado de bits la que causa la fluctuación.

solución

Agregue un elemento principal de igual altura a este elemento de techo. Supervisamos el valor superior getBoundingClientRect (). De este elemento principal para lograr el efecto de techo, a saber:

<div class="title_box" ref="pride_tab_fixed">

    <div class="title" :class="titleFixed == true ? 'isFixed' :''">

    使用 `obj.getBoundingClientRect().top` 实现

    </div>

</div>

Esta solución puede resolver el error de jitter.

En segundo lugar, el efecto techo no se puede responder a tiempo

Este problema es mi dolor de cabeza, antes no me importaba. No presté atención a este problema hasta que un día usé Meituan para pedir comida para llevar.

descripción:

  1. Cuando la página se desplaza hacia abajo, el elemento de techo debe esperar a que se detenga el desplazamiento de la página antes de que aparezca el efecto de techo.

  2. Cuando la página se desplaza hacia arriba, el elemento de techo no volverá a su forma original cuando se desplaza hacia el elemento de techo para restaurar la posición del flujo de documentos, pero volverá a su forma original después de que la página deje de desplazarse

Razón: El evento de monitoreo de desplazamiento no se puede monitorear en tiempo real en el sistema ios y sus eventos relacionados se activan cuando el desplazamiento se detiene.

solución:

¿Recuerda la posición: pegajosa en el primer esquema? Este atributo tiene buena compatibilidad en sistemas superiores a IOS6, por lo que podemos distinguir entre dispositivos IOS y Android para hacer dos procesamientos.

IOS usa position: sticky y Android usa el desplazamiento para monitorear el valor de getBoundingClientRect (). Top.

¿Qué pasa si la versión de IOS es demasiado baja? Aquí hay una idea: window.requestAnimationFrame ().

Serie de diccionarios front-end

La serie "Diccionario de interfaz de usuario" seguirá actualizándose. En cada número, hablaré de un punto de conocimiento que aparece con frecuencia. Espero que encuentres algún lugar impreciso o incorrecto en el texto durante el proceso de lectura, te estaré muy agradecido, si puedes ganar algo con esta serie, también seré muy feliz.

Contenido: La introducción de puntos de conocimiento relacionados con el front-end y la red, con aplicación práctica como ayuda.

Propósito: Esta serie de artículos puede ayudar un poco a los lectores y resolver algunas confusiones.

Espero que pueda darme algunos consejos y sugerencias.

Si crees que mi artículo está bien escrito, ¡sígueme!

Supongo que te gusta

Origin blog.51cto.com/15077552/2596506
Recomendado
Clasificación