Análisis de propiedades de scroll | Equipo técnico de JD Cloud

Recientemente, hay un proyecto que necesita usar js de forma nativa para desarrollar componentes deslizantes, y se usan con frecuencia varios atributos de los elementos dom, entre los cuales se encuentran en su mayoría varios tipos de atributos de altura y top, con nombres similares, y los significados son fáciles de confundir. . Por lo tanto, resumí especialmente los puntos de conocimiento de uso común Al final del artículo, desafiaremos a implementar un componente de desplazamiento móvil simple.

Para comprender la altura y la parte superior, debemos comenzar con el modelo de caja.Primero, familiaricémonos con el modelo de caja definido en css3. El área real ocupada por los elementos dom en la página se puede ilustrar con la siguiente imagen:

 Podemos pensar en él como un huevo, desde el exterior hacia el interior son

Área naranja - margen del margen exterior: cáscara de huevo

Área negra - borde borde: membrana de cáscara de huevo

Área verde - relleno del margen interior: albúmina

Área blanca - contenido contenido: yema de huevo

La parte que realmente nos importa es el contenido, que es la parte más nutritiva del huevo. Con tantas capas envueltas alrededor del contenido, sentiremos la densidad general de la estructura DOM en la página y no nos preocuparemos por la densidad del texto y las imágenes. Para describir mejor el modelo de caja, en la especificación web se definen algunas otras interfaces para describirlas, que son las protagonistas de las que hablaremos hoy:

 

En la imagen de arriba, describimos dos capas de elementos dom con una relación anidada. Tenga en cuenta que el área de contenido aquí es diferente de la imagen anterior. El área de contenido aquí también es un elemento dom independiente (es decir, también tiene su propio margen). y borde. , relleno y contenido!, en aras de la simplificación, los elementos secundarios ya no se dibujan específicamente), debido a que la altura total de los elementos secundarios es muy alta, incluso superando la altura del elemento principal, no puede ser completamente se muestra en el elemento principal (la parte invisible más allá de la que se usa se indica en gris), es decir, los dos constituyen una relación continua. Intentemos describir las siguientes propiedades:

一、clientHeight

Propiedad de solo lectura. clientHeight es en realidad la altura de la barra de desplazamiento vertical. En general, la barra de desplazamiento vertical debe estar cerca de los bordes superior e inferior, por lo que clientHeight = relleno superior e inferior + altura del contenido. No olvides que hay un caso especial, cuando hay una barra de desplazamiento horizontal, también debes considerar que la barra de desplazamiento horizontal ocupa parte del espacio de la barra de desplazamiento vertical, es decir: clientHeight = up and down padding + altura del contenido: altura de la barra de desplazamiento horizontal. Si usa un huevo como metáfora, clientHeight es un huevo sin cáscara.

Dos, clienteArriba

Propiedad de solo lectura. Describe el ancho del borde superior. El borde superior es fácil de recordarnos el grosor del cabello.La próxima vez frente al espejo, puede decirse a sí mismo: su clienteTop ha disminuido, pero también se ha vuelto más fuerte.

3. altura de compensación

Propiedad de solo lectura. offsetHeight es similar a clientHeight. La observación muestra que hay una capa adicional de borde que clientHeight: offsetHeight = clientHeight + bordes superior e inferior. Ahora volvemos al momento antes de pelar los huevos, y los huevos se sacan del agua y se lavan y se presentan con altura compensada.

Cuatro, desplazado Arriba

Propiedad de solo lectura. Devuelve la distancia del elemento actual en relación con el relleno superior de su elemento offsetParent. Esta distancia no incluye el ancho del borde de sí mismo y del elemento principal, de hecho: offsetTop = su propio margen superior + el relleno superior del elemento principal, que es equivalente al grosor del deflector entre el huevo y la caja de huevos.

Cinco, scrollHeight

Propiedad de solo lectura. Describe una medida de la altura del contenido de un elemento, incluido el contenido que no está visible a la vista debido al desbordamiento. Podemos modificarlo para mostrar el contenido invisible en el elemento principal. El elemento secundario se puede dividir en dos partes en la dirección vertical: el margen exterior y la altura de desplazamiento interior:

Para los elementos padre-hijo con una relación de desplazamiento, scrollHeight tiene diferentes significados:

(1) Para los elementos secundarios, dado que el elemento secundario en sí no contiene la parte de desbordamiento, su scrollHeight y clientHeight tienen el mismo valor

(2) Para el elemento principal, dado que el contenido del elemento principal es realmente "compatible" con el elemento secundario, su scrollHeight es la altura real después de "expandir" el área de contenido: elemento principal scrollHeight = offsetHeight del elemento secundario + child elemento Margen arriba y abajo + propio relleno arriba y abajo

Seis, desplazarse hacia arriba

Propiedad de lectura y escritura, puede obtener o establecer el número de píxeles que el contenido de un elemento se desplaza verticalmente. Esta es la primera propiedad que hemos encontrado hasta ahora que puede admitir configuraciones.

(1) En el estado inicial, el contenido no se desplaza verticalmente y su valor es 0

(2) Cuando el contenido se desplaza hacia abajo en dirección vertical, dado que la altura real del área de contenido es scrollHeight, la altura visualizable es clientHeight, y la parte adicional es que el valor de scrollTop en este momento es scrollHeight - clientHeight

Entonces se puede concluir que: 0 <= scrollTop <= scrollHeight - clientHeight

Siete, combate real

Después de aprender los atributos y la información anteriores, imitamos la función del componente de vista de desplazamiento del subprograma JD para implementar una función común de la versión H5 del componente deslizante: actualización desplegable y carga desplegable de la lista. Para lograr esta función, se puede dividir aproximadamente en tres puntos centrales:

(1) Desplazable: debe haber un caparazón no móvil y un área de contenido deslizable.

(2) Reconocimiento de gestos: a través del atributo táctil del terminal móvil, podemos comparar las posiciones de los dedos de touchend y touchstart para realizar el reconocimiento de gestos de forma sencilla.

(3) Activación de eventos: De acuerdo con la condición crítica de la posición de deslizamiento, se juzga si deben activarse eventos de actualización y carga.

Parte del código de implementación es el siguiente:

// scroller.js

export default class Scroller {
	constructor(el, option) {
		this._el = el
		this._parent = el.parentNode
		this._option = option
		this._pos = 0
		this._handleScrollStart = this.handleScrollStart.bind(this)
		this._handleScroll = this.handleScroll.bind(this)
		this.init()
	}
	init() {
		this._el.addEventListener('touchstart', this._handleScrollStart)
		this._el.addEventListener('touchend', this._handleScroll)
		if(this._option.auto) {
			this.handleRefresh()
		}
	}
	destroy() {
		this._el.removeEventListener('touchstart', this._handleScrollStart)
		this._el.removeEventListener('touchend', this._handleScroll)
	}
	handleScrollStart(e) {
		const touch = e.targetTouches[0] || e.changedTouches[0]
		this._pos = touch.clientY
	}
	handleScroll(e) {
		const touch = e.targetTouches[0] || e.changedTouches[0]
		const delta = touch.clientY - this._pos
		if(delta >= this._option.threhold) {
			// 手势向下,且下行滚动距离超过判定阈值
			if(this._parent.scrollTop == 0) {
				this.handleRefresh(e)
			}
		} else if(this._parent.scrollHeight > this._parent.clientHeight && delta <= -this._option.threhold){
			// 内容可滚动,且上行滚动距离超过判定阈值
			if(this._parent.scrollTop > this._parent.scrollHeight - this._parent.clientHeight - this._option.threhold){
				this.handleLoad(e)
			}
		}
	}
	handleRefresh(...params) {
		this._option.onRefresh && this._option.onRefresh.apply(this, params)
	}
	handleLoad(...params) {
		this._option.onRefresh && this._option.onLoad.apply(this, params)
	}
}

Llame a la demostración:

var inner = document.getElementsById('inner')
var list = []
var pageIndex = 1
function getMockData() {
	const newData = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(i => i+(pageIndex-1)*10)
	setTimeout(() => {
	    if(pageIndex==1) { list = newData } else if(pageIndex < 5) { list.push(...newData) } else { alert('没有更多内容了') }
	    pageIndex++
	    inner.innerHTML = list.map(i => `<div class="inner-item">${i}</div>`).join('')
	}, 300)
}
function onRefresh() {
	pageIndex = 1
	getMockData()
}
new Scroller(inner, {
	threhold: 20,
	onRefresh: onRefresh,
	onLoad: getMockData,
	auto: true
})

Puede probarlo usted mismo, y el efecto no es malo ~~~ Bienvenido al área de mensajes para discutir e intercambiar.

Autor: Jingdong Minorista Chen Zhen

Fuente: Comunidad de desarrolladores de JD Cloud

 

RustDesk 1.2: uso de Flutter para reescribir la versión de escritorio, compatible con la supuesta fuga de arquitectura del modelo GPT-4 de Wayland: contiene 1,8 billones de parámetros, utilizando un modelo experto mixto (MoE) Musk anunció el establecimiento de la empresa xAI deepin V23 adaptó con éxito las afirmaciones del proyecto WSL CentOS " Abierto a todos" Rust 1.71.0 Stable Release React ¿Está teniendo un momento Angular.js? Microsoft lanza una nueva fuente predeterminada, Aptos, para reemplazar CalibriMicrosoft : aumentar los esfuerzos para usar la versión Rust IntelliJ IDEA 2023.1.4 en Windows 11
{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/4090830/blog/10089164
Recomendado
Clasificación