So erstellen Sie eine Range-Slider-Komponente in React von Grund auf neu, indem Sie nur div und span verwenden

In diesem Artikel werden wir Schritt für Schritt eine React Range Slider-Komponente erstellen, indem wir nur

verwenden. Wir werden es mit Touch-Unterstützung aktivieren.

Was kann man mit einem Stück von etwa 50 machen?

Erstellen Sie ein Schieberegler-Steuerelement von Grund auf neu. Wenn das interessant klingt, dann folgen Sie ihm.

Die endgültige Ausgabe sieht wie die folgende Animation aus.

Bitte beachten Sie, dass ich diese Komponente als Unterrichtsübung für meine Schüler entwickelt habe ReactJS – Beyond the Basics-Kursdaher kann es einige Randfälle geben (die ich bei Bedarf beheben werde).

Sie könnten ein HTML5-Bereichssteuerelement verwenden und es anpassen. Aber ich wollte einen anderen Ansatz wählen und etwas von Grund auf neu aufbauen. Und das Ergebnis sehen Sie hier.

Unsere Slider-Komponente besteht aus den folgenden drei Elementen:

  • Ein Slider-Bereich
  • Der eigentliche Schieberegler steuert
  • Der aktuelle Auswahlbereich

Definieren des Zustands für unsere Komponente

Beginnen wir damit, unseren Zustand zu definieren. Ich zeige Ihnen nur den wichtigen Teil des Codes. Den vollständigen Quellcode finden Sie unter dem Link am Ende des Artikels.

state = {
      slots: 24,
      start: 0,
      end: 10,
      labelMode: "mid", // mid, long
}

Der Zustand enthält die folgenden Eigenschaften.

  • Slots: Gesamtzahl der zu ziehenden Slots (in diesem Fall verwende ich es als Zeitauswahl, also hat es 24-Stunden-Slots)
  • start: Der Startwert der Auswahl
  • end: Der Endwert der Auswahl
  • labelMode: Derzeit unbenutzt. Kann aber verwendet werden, um das Rendering der Skalenbeschriftung anzupassen.

Der Rückgabeteil der Rendermethode

Schauen wir uns nun den Rückgabeteil der Render-Methode an. Die Methode render() wird langsam aus kleinen Funktionsteilen zusammengesetzt.

return (
        <div>
          <h2>React Slider</h2>
          <div className="example-1">
            <div className="slider-container">
             <div className="slider-scale">
                 {scale}
              </div>
              <div className="slider">
                  {slider}
              </div>
              <div className="slider-selected-scale">
                  {currentScale}
              </div>
            </div>
          </div>
        </div>
);

Für diejenigen, die auf dem Handy lesen, kann das folgende Bild nützlich sein.

Wenn Sie sich den Code ansehen, gibt es nur drei wichtige Teile:

  • Skalierungsvariable
  • Slider-Variable
  • currentScale-Variable

Die drei obigen Variablen sind für das Rendern der richtigen Teile des gesamten Schiebereglers verantwortlich.

Analyse der render()-Methode

Lassen Sie uns einige Variablen initialisieren. Das scale, slider und currentScale JSX wird innerhalb der unten definierten for-Schleife erstellt.

render () {
 let scale = [];
 let slider=[];
 let currentScale = [];
 let minThumb = null;
 let maxThumb = null

..... // rest of the code 
}

Erstellen Sie die JSX für die Variable „scale“.

Das Erstellen des JSX für die Skalierungsvariable ist recht einfach. Wir durchlaufen einfach den Slots-Wert im Zustand und schieben ein

an das scale-Array mit der erforderlichen CSS-Klasse für das Styling.

Die if-Bedingung stellt sicher, dass wir das Etikett nur für i = 0, i = 12 oder i = 24 (eine Art mittlerer Bereich) drucken. Fühlen Sie bitte sich frei, dieses besonders anzufertigen.

for (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">
            {label}
          </div>
        );

Hier ist der Code im Bildformat:

Erstellen Sie die JSX für die Variable „currentScale“.

Lassen Sie uns nun mit der gleichen for-Schleife fortfahren und die ‘currentScale’ JSX erstellen. Wir befinden uns immer noch in derselben for-Schleife, also werden etwa 24 divs gemäß dem Wert in this.state.slots erstellt.

Die CurrentScale hat eine Klasse von ‘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>
 );

Der Code ist dem von uns erstellten „scale“ JSX ziemlich ähnlich.

Erstellen Sie die JSX für die Variable „slider“.

Lassen Sie uns eine Funktion schreiben, um das ‘slider’ jsx zu rendern. Der Schieberegler benötigt zwei Daumen, einen für min und einen für max.

Lassen Sie uns zunächst die thumb-Variable in Abhängigkeit vom ‘i’-Wert initialisieren. Wenn ‘i’ mit this.state.start identisch ist, setzen wir die Variable minThumb. Andernfalls, wenn der Wert von ‘i’ der gleiche wie this.state.end ist, initialisieren wir die maxThumb-Variable.

if (i === this.state.start) {
   minThumb = <this.MinSlider />
} else if (i === this.state.end) {
   maxThumb = <this.MaxSlider />
} else {
   minThumb = null;
   maxThumb = null;
}

Erstellen Sie das JSX für den ‘Schieberegler’

Das wichtige Codestück hier ist das Dragover-Ereignis. Dies ist erforderlich, damit der HTML-Drop ordnungsgemäß funktioniert.

let lineClass = "line";
        
if (i >= this.state.start && i < this.state.end) {
   lineClass += " line-selected";
}
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>
 );

Die Slider-Variable benötigt zwei zusätzliche Features, um den minimalen und den maximalen Daumen auf dem Slider darzustellen.

Der Slider JSX verfügt über zusätzliche Event-Handler, die sich mit der Behandlung des Drop-Events/Touchend-Events befassen. Wir werden uns in Kürze die Event-Handler ansehen.

Die Klasse „lineClass“ formatiert/gerendert die Linie auf dem Schieberegler, und die Klasse „line-s selected“ formatiert den aktuell ausgewählten Bereich.

Lassen Sie uns nun die Funktionen MinSlider und MaxSlider außerhalb der Render-Methode schreiben.

Die Funktion MinSlider () zum Rendern des Min-Daumens

Werfen wir einen Blick auf den Code. Die wichtigen Requisiten sind die Drag-Ereignisse und das draggable-Attribut. Das draggable-Attribut macht dieses Element ziehbar.

Wir fügen auch den Touch-Event-Handler hinzu. Beziehen Sie sich auf den Link am Ende des Artikels, um Touch-Support-Polyfill für die HTML5-API hinzuzufügen.

MinSlider=()=> {
  return (
     <div data-slider="min" 
           onDragStart={this.onDragStart} 
           onTouchStart={this.onDragStart}
           draggable className="slider-thumb slider-thumb-min">
     </div>
  );
}

Die Funktion MaxSlider () zum Rendern des Min-Daumens

Der MaxSlider ist fast derselbe wie der MinSlider, abgesehen von den Daten und dem Klassennamen.

MaxSlider=()=> {
  return (
      <div data-slider="max" 
         onDragStart={this.onDragStart}  
         onTouchStart={this.onDragStart}
        draggable className="slider-thumb slider-thumb-max">        
      </div>
   );
}

Das Codebild ist unten als Referenz angegeben.

Handhabung des Events

Sehen wir uns nun die Drag/Touch-Event-Handler an, die in unserem

definiert sind, um die Bewegung des Slider-Elements zu steuern.

drüber ziehen:

Das Dragover-Ereignis ist erforderlich, um die Dropzone bei Verwendung der HTML5-Drag/Drop-API zu unterstützen. Das Einzige, was wir hier tun müssen, ist, preventDefault für das Ereignisobjekt aufzurufen.

onDragOver = (e) => {
    e.preventDefault();
}

Schleppstart:

Der Dragstart ermöglicht es uns zu speichern, welcher Slider gezogen wird. Bitte beachten Sie, dass ich hier nicht das dataTransfer-Objekt verwende, sondern einfach eine Instanzvariable verwende, um dies zu speichern.

onDragStart = (e) => {
   let slider = e.target.dataset.slider;
   this.sliderType = slider;
}

Der Wert von e.target.dataset.slider ist entweder „min“ oder „max“, was angibt, welcher Schieberegler gezogen wird.

einfallen:

Das ondrop-Ereignis erfasst, wo der Daumen abgelegt wird (auf welcher Skala).

Dies ist der wichtige Ablauf im ondrop-Ereignis:

  • Schnapp dir die Quelle (ob Min/Max-Daumen)
  • Holen Sie sich den Slot (wo der Drop passiert)
  • Validierungen
  • Aktualisieren Sie den Steckplatz (im Status)
  • Setzen Sie den sliderType zurück.
onDrop = (e, target) => {
      let source = this.sliderType;
      let slot = Number(e.target.dataset.slot);
      
     if (isNaN(slot)) return;
      
      if (source === "min") {
        if (slot >= this.state.end) return;
        this.setState({
          start: slot
        },()=>{
          console.log(this.state);
        })
      } else if (source === "max") {
        if (slot <= this.state.start) return;
        this.setState({
          end: slot
        },()=>{
          console.log(this.state);
        })
      }
     this.sliderType = null;
}

Der komplette Quellcode/und Demo kann eingesehen werden hier.

Da ich HTML5-Drag-and-Drop-Funktionen verwende, um Berührungen hinzuzufügen, fügen Sie bitte diese Polyfill-Referenz zu Ihrer HTML-Datei hinzu.

Bernardo-Castilho/dragdroptouch
_dragdroptouch – Polyfill, das HTML5-Drag-Drop-Unterstützung auf mobilen (Touch-)Geräten ermöglicht._github.com

Alle

  • Extrahieren Sie die Logik in eine separate Komponentenklasse
  • Testen Sie es und fügen Sie Anpassungen hinzu.

Geschichte

  • 21. Mai 2018 — Erste Veröffentlichung

PS: Diese Komponente ist das Ergebnis eines sehr schnellen Codierungsversuchs. Dies wird umgestaltet, es wurde ursprünglich veröffentlicht hier.

Similar Posts

Leave a Reply

Your email address will not be published.