Neste artigo, construiremos um componente slider da faixa React passo a passo usando apenas <div>. Vamos ativá-lo com suporte ao toque.
O que você pode fazer com um pedaço de cerca de 50 div?
Construa um controle deslizante a partir do zero. Se isso parece interessante, siga em frente.
A saída final será semelhante à animação abaixo.
Por favor, note que eu desenvolvi este componente como um exercício de ensino para os meus alunos do curso ReactJS – Beyond the Basics no Udemy , por isso pode ter alguns casos de limites (que eu vou corrigir como e quando encontrados).
Você pode usar um controle de intervalo HTML5 e personalizá-lo. Mas eu queria ter uma abordagem diferente e construir algo do zero. E o resultado é o que você vê aqui.
Nosso componente slider será composto pelos três elementos abaixo:
- Uma faixa de controle deslizante
- Os controles reais do controle deslizante
- O intervalo de seleção atual
Definindo o estado para nosso componente
Vamos começar definindo nosso estado. Estou mostrando apenas a parte importante do código. Para o código-fonte completo, por favor, consulte o link no final do artigo.
state = {
slots: 24,
começar: 0,
fim: 10,
labelMode: "mid", // mid, long
}
O estado contém as seguintes propriedades.
- slots: Total de slots a serem sorteados (neste caso eu estou usando como um seletor de tempo, então ele terá slots de 24 horas)
- start: o valor inicial da seleção
- end: o valor final da seleção
- labelMode: atualmente não utilizado. Mas pode ser usado para personalizar a renderização do rótulo de escala.
A parte de retorno do método render
Vamos agora dar uma olhada na parte de retorno do método render. O método render () será composto lentamente de pequenos pedaços de funcionalidade.
Retorna (
<div>
<h2> Reagir Slider </ h2>
<div className = "example-1">
<div className = "slider-container">
<div className = "escala do controle deslizante">
{escala}
</ div>
<div className = "slider">
{slider}
</ div>
<div className = "slider-selected-scale">
{currentScale}
</ div>
</ div>
</ div>
</ div>
);
Para quem lê no celular, a imagem abaixo pode ser útil, pois às vezes o Medium quebra a formatação do código.
Se você der uma olhada no código, existem apenas três partes importantes:
- variável de escala
- variável deslizante
- variável currentScale
As três variáveis ??acima serão responsáveis ??por renderizar as partes corretas do controle deslizante geral.
Dissecando o método render ()
Vamos inicializar algumas variáveis. A scale
, o slider
e o currentScale
JSX serão criados dentro do loop for definido abaixo.
render () {
let scale = [];
let slider = [];
let currentScale = [];
let minThumb = null;
deixe maxThumb = null
..... // resto do código
}
Crie o JSX para a variável 'scale'
Criar o JSX para a variável de escala é bem simples. Nós apenas percorremos o valor dos slots no estado e enviamos um <div> para a matriz de escala com a classe CSS necessária para estilização.
A condição if garante que apenas imprimimos o rótulo para i = 0, i = 12 ou i = 24 (tipo de intervalo médio). Por favor, sinta-se livre para personalizar isso.
para (let i = 0; i <= this.state.slots; i ++) {
let label = "";
if (i == 0 || i == 12 || i == 24) {
label = i;
}
scale.push (
<div
key = {i}
className = "slot-scale">
{rótulo}
</ div>
);
Aqui está o código em formato de imagem:
Crie o JSX para a variável 'currentScale'
Vamos continuar com o mesmo loop for e criar o JSX 'currentScale'. Ainda estamos dentro do mesmo loop, então cerca de 24 divs serão criados de acordo com o valor no valor this.state.slots.
O currentScale tem uma classe de 'slot-scale-selected'.
let currentLabel = "";
if (i === this.state.start || i === this.state.end) {
currentLabel = i;
}
currentScale.push (
<div
key = {i}
className = "slot-scale-selected">
{currentLabel}
</ div>
);
O código é bem parecido com o JSX 'scale' que criamos.
Crie o JSX para a variável 'slider'
Vamos escrever uma função para renderizar o 'slider' jsx. O controle deslizante precisa de dois polegares, um para min e um para max.
Vamos primeiro inicializar a variável thumb dependendo do valor 'i'. Se 'i' é o mesmo que this.state.start, então definimos a variável minThumb. Senão, se o valor de 'i' for o mesmo que this.state.end, então inicializamos a variável maxThumb.
if (i === this.state.start) {
minThumb = <this.MinSlider />
} else if (i === this.state.end) {
maxThumb = <this.MaxSlider />
} outro {
minThumb = null;
maxThumb = null;
}
Crie o JSX para o 'slider'
O código importante aqui é o evento dragover. Isso é necessário para que a queda de HTML funcione corretamente.
deixe lineClass = "linha";
if (i> = this.state.start && i <this.state.end) {
lineClass + = "selecionado na linha";
}
slider.push (
<div
data-slot = {i}
onDragOver = {this.onDragOver}
onTouchMove = {this.onDragOver}
onTouchEnd = {this.onDrop}
onDrop = {this.onDrop}
key = {i}
className = "slot">
<div data-slot = {i} className = {lineClass} />
<span className = "scale-mark"> </ span>
{minThumb}
{maxThumb}
</ div>
);
A variável deslizante precisa de duas partes adicionais de recursos para representar o min e o polegar max no controle deslizante.
O slider JSX possui manipuladores de eventos adicionais para lidar com o evento drop event / touchend. Vamos dar uma olhada nos manipuladores de eventos em breve.
O 'lineClass' estilos / processa a linha no controle deslizante, e a classe 'line-selected' estiliza o intervalo atualmente selecionado.
Vamos agora escrever a função MinSlider e MaxSlider fora do método render.
A função MinSlider () para renderizar o thumb min
Vamos dar uma olhada no código. Os suportes importantes são os eventos relacionados ao arrastar e ao atributo arrastável. O atributo arrastável tornará esse elemento arrastável.
Também estamos adicionando o manipulador de eventos de toque. Consulte o link na parte inferior do artigo para adicionar o polyfill de suporte ao toque para a API do HTML5.
MinSlider = () => {
Retorna (
<div data-slider = "min"
onDragStart = {this.onDragStart}
onTouchStart = {this.onDragStart}
class = "slider-thumb slider-thumb-min"> arrastável
</ div>
);
}
A função MaxSlider () para renderizar o thumb min
O MaxSlider é quase o mesmo que o MinSlider, exceto os dados e o className.
MaxSlider = () => {
Retorna (
<div data-slider = "max"
onDragStart = {this.onDragStart}
onTouchStart = {this.onDragStart}
class = "slider-thumb slider-thumb-max"> arrastável
</ div>
);
}
A imagem de código é dada abaixo para referência.
Manipulação de eventos
Vamos agora olhar para os manipuladores de eventos de arrastar / tocar definidos dentro de nosso <div> para controlar o movimento do elemento deslizante.
arraste sobre:
O evento dragover é necessário para suportar a zona de recebimento ao usar a API de arrastar / soltar HTML5. A única coisa que precisamos fazer aqui é invocar o preventDefault no objeto de evento.
onDragOver = (e) => {
e.preventDefault ();
}
dragstart:
O dragstart nos permite armazenar qual slider está sendo arrastado. Por favor, note que eu não estou usando o objeto dataTransfer aqui, mas simplesmente usando uma variável de instância para armazenar isso.
onDragStart = (e) => {
let slider = e.target.dataset.slider;
this.sliderType = controle deslizante;
}
O valor de e.target.dataset.slider é “min” ou “max”, indicando qual slider está sendo arrastado.
ondrop:
O evento ondrop captura onde o polegar está sendo descartado (em qual escala).
Este é o fluxo importante no evento ondrop:
- Agarre a fonte (se min / max polegar)
- Pegue o slot (onde a queda acontece)
- Validações
- Atualize o slot (no estado)
- Redefina o sliderType.
onDrop = (e, target) => {
deixe source = this.sliderType;
let slot = Number (e.target.dataset.slot);
if (isNaN (slot)) retorna;
if (fonte === "min") {
if (slot> = this.state.end) retorna;
this.setState ({
início: slot
}, () => {
console.log (this.state);
})
} else if (fonte === "max") {
if (slot <= this.state.start) retorna;
this.setState ({
end: slot
}, () => {
console.log (this.state);
})
}
this.sliderType = nulo;
}
O código-fonte completo e a demonstração podem ser vistos aqui http://jsbin.com/remodat/edit?output
Como estou usando recursos de arrastar e soltar HTML5 para adicionar suporte ao toque, adicione essa referência de polyfill ao arquivo html.
Bernardo-Castilho / dragdroptouch
dragdroptouch – Polyfill que permite o suporte a arrastar e soltar HTML5 em dispositivos móveis (touch). github.com
Todos
- Extraia a lógica para uma classe Component separada
- Teste e adicione customização.
História
- 21 de maio de 2018 – Primeiro lançamento
PS: Esse componente é resultado de uma tentativa de codificação muito rápida. Isso será refatorado.
Promoção : Se você gostaria de apoiar nosso currículo de código aberto em 12 a 20 semanas, então aqui está um cupom especial de 10 dólares para leitores médios para o meu próximo curso ao vivo ReactJS-Beyond no udemy (MEDIUM_500 é o código de cupom , que já está marcado no URL acima)