Beispielcode für den Song-Fortschrittsbalken in Vue

Beispielcode für den Song-Fortschrittsbalken in Vue

Beachten Sie, dass dies kein von vue-cli erstelltes Projekt ist. Es handelt sich um eine HTML-Datei, die durch Verweisen auf vue.js geschrieben wurde. Sie können sie verwenden, indem Sie sie einfach in eine HTML-Datei einfügen. Mein Musiklink wird nach einer gewissen Zeit ungültig. Sie müssen die Musik selbst vorbereiten. Es gibt Funktionen zum Ziehen und Klicken, um den Wiedergabefortschritt umzuschalten.

Demobilder

Bildbeschreibung hier einfügen

Code

<!DOCTYPE html>
<html lang="de">

<Kopf>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-kompatibel" content="IE=edge">
  <meta name="viewport" content="width=Gerätebreite, Anfangsmaßstab=1.0">
  <title>Dokument</title>
</Kopf>

<Text>
  <div id="app">
    <audio ref="audioRef" autoplay @canplay='canplay' @timeupdate='update'></audio>
    <button @click="play">Abspielen</button>
    <button @click="pause">Pause</button>
    <div Klasse="Fortschritt-Wrapper">
      <span class="Zeit Zeit-l">{{formatTime(currentTime)}}</span>
      <div Klasse="Fortschrittsbalken-Wrapper">
        <cpn :fortschritt=Fortschritt 
          @progress-changing="beiFortschrittsänderung" 
          @progress-changed='fortschrittGeändert'>
       </cpn>
      </div>
      <span class="time time-l">{{formatTime(Dauer)}}</span>
    </div>

  </div>

  <!-- Untergeordnete Komponente -->
  <Vorlagen-ID="myCpn">

    <div Klasse="Fortschrittsbalken">
      <!-- Schwarzer Streifen hinten-->
      <div Klasse="bar-inner" @click="clickProgress">
        <!-- Bereiche, die bespielt wurden-->
        <div class="Fortschritt" :style='FortschrittsStil' ref="Fortschritt">
        </div>
        <!-- btn -->
        <div Klasse = "progress-btn-wrapper" :style = "btnStyle" @touchstart.preventDefault = "onTouchStart"
          @touchmove.preventDefault='beiTouchMove' @touchend.preventDefault='beiTouchEnd' >
          <div Klasse = "Fortschritt-btn"></div>
        </div>
      </div>
    </div>
  </Vorlage>


  <script src="../../js/vue.js"></script>

  <Skript>
    audioEl = null
    const progressBtnWidth = 16
    // Unterkomponente const cpn = {
      Vorlage: "#myCpn",
      Requisiten: {
        Fortschritt:
          Typ: Nummer,
          Standard: 0
        }
      },
      Daten() {
        zurückkehren {
          Versatz: 0
        }
      },
      montiert() {

      },
      erstellt() {
        dies.berühren = {}
      },
      berechnet: {
        Fortschrittsstil() {
          gibt `Breite: ${this.offset}px` zurück
        },
        btnStyle() {
          // konsole.log('fds');
          gibt `transform: translate3d(${this.offset}px,0,0)` zurück
        },
      },
      betrachten:
        Fortschritt(neuerFortschritt) {
          // Breite des Fortschrittsbalkens const barWidth = this.$el.clientWidth - progressBtnWidth
          this.offset = Balkenbreite * neuer Fortschritt
        }
      },
      Methoden: {
        beiBerührenStart(e) {
          // console.log(e);
          this.touch.x1 = e.changedTouches[0].clientX
          // Anfangsbreite des gelben Fortschrittsbalkens this.touch.beginWidth = this.$refs.progress.clientWidth
          Konsole.log(dies.berühren);
        },
        beiBerührenBewegung(e) {
          // console.log(e);
          // x-Offset const delta = e.changedTouches[0].clientX - this.touch.x1
          // Vorherige Breite + der durch Ziehen dieses Mal hinzugefügte Versatz = die erwartete Länge des gelben Balkens const tempWidth = this.touch.beginWidth + delta
          // BarWidth erneut abrufen
          const barWidth = this.$el.clientWidth - progressBtnWidth
          // Gelbe Balkenlänge/Balkenbreite = Fortschritt Der aktuelle Fortschritt sollte sein: const progress = tempWidth / barWidth
          this.offset = Balkenbreite * Fortschritt
          this.$emit('Fortschrittsänderung', Fortschritt)
          // console.log("tempWidth", tempWidth);
          // console.log("Balkenbreite", Balkenbreite);
          // console.log("Fortschritt", Fortschritt);

        },
        onTouchEnd(e) {
          // console.log(e);
          const barWidth = this.$el.clientWidth - progressBtnWidth
          const Fortschritt = this.$refs.progress.clientWidth / barWidth
          dies.$emit('Fortschritt geändert', Fortschritt)
        },
        // Klicken Sie auf den Fortschrittsbalken clickProgress(e){
          // konsole.log("fds");
          console.log('getBoundingClientRect', this.$el.getBoundingClientRect());
          const rect = this.$el.getBoundingClientRect()
          // Die Breite des gelben Balkens const offsetWidth = e.pageX - rect.x
          const barWidth = this.$el.clientWidth - progressBtnWidth
          const Fortschritt = Offsetbreite / Balkenbreite
          dies.$emit('Fortschritt geändert', Fortschritt)
          console.log(Offsetbreite)
        }
      },
    }

    const app = new Vue({
      el: "#app",
      Daten: {
        Inhalt: 'fdasdf',
        Quelle: 'https://music.163.com/song/media/outer/url?id=1463165983.mp3',
        aktuelleZeit: 0,
        Dauer: 0,
        Anzeige: false,
        Fortschrittsänderung: false
      },
      Komponenten:
        cpn
      },

      montiert() {
        dies.$nextTick(() => {
          audioEl = dies.$refs.audioRef
          audioEl.src = diese.src
          // Standardmäßig pausieren audioEl.pause()
        })
      },
      berechnet: {
        Fortschritt() {
          gib diese.aktuelleZeit / diese.Dauer zurück
          console.log("Fortschritt", diese.aktuelleZeit / diese.Dauer);
        },

      },
      Methoden: {
        spielen() {
          audioEl.abspielen()
          this.isplay = true
        },
        pause() {
          audioEl.pause()
          this.isplay = falsch
          // konsole.log();
        },
        kannspielen(e) {
          // konsole.log(123456);
          konsole.log(e);
          diese.Dauer = e.Ziel.Dauer
        },
        aktualisieren(e) {
          wenn(!dieser.progressChanging){
            diese.aktuelleZeit = e.ziel.aktuelleZeit
          }
        },
        beiFortschrittsänderung(e) {
          // console.log("beiFortschrittsänderung", e);
          this.progressChanging = wahr
          // Ändern Sie den currentTime-Wert in Echtzeit this.currentTime = this.duration * e 
        },
        FortschrittGeändert(e){
          // console.log(e);
          this.progressChanging = falsch
          audioEl.currentTime = diese.currentTime = diese.duration * e 
          wenn(!dies.ist){
            Konsole.log("------");
            audioEl.abspielen()
          }
        },
        formatTime(Intervall) {
          // Intervall abgerundet Intervall = Intervall | 0
          // Wenn weniger als zwei Ziffern vorhanden sind, füllen Sie mit einer 0 auf
          let minute = ((Intervall / 60 | 0) + '')
          sei Sekunde = ((Intervall % 60 | 0) + '')
          let len ​​= minute.länge
          für (; Länge < 2; Länge++) {
            Minute = '0' + Minute
          }
          len = Sekunde.Länge
          für (; Länge < 2; Länge++) {
            Sekunde = '0' + Sekunde
          }
          return `${Minute}:${Sekunde}`
        },

      },
    })
  </Skript>
</body>
<Stil>
  #app {
    Breite: 100 %;
  }

  .progress-wrapper {
    Anzeige: Flex;
    Breite: 80%;
    Polsterung: 10px 0;
    Elemente ausrichten: zentrieren;
    Rand: 0 automatisch;
  }

  .Zeit {
    Breite: 40px;
    flexibel: 0 0 40px;
    Schriftgröße: 8px;
    Rand: 0 automatisch;
    Polsterung: 0,8px;
  }

  .zeit-l {
    Textausrichtung: links;
  }

  .zeit-l {
    Textausrichtung: rechts;
  }

  .Fortschrittsbalken-Wrapper {
    biegen: 1;
  }

  /* Unterkomponentenstil */
  .Fortschrittsbalken {
    Höhe: 30px;
  }

  .bar-inner {
    Position: relativ;
    oben: 11px;
    Höhe: 8px;
    Hintergrundfarbe: rgba(87, 82, 82, 0,062);
    Rahmenradius: 5px;
  }

  .Fortschritt {
    Position: absolut;
    Höhe: 100%;
    Hintergrundfarbe: rgb(238, 238, 136);
  }

  .progress-btn-wrapper {
    Position: absolut;
    links: -8px;
    oben: -11px;
    Breite: 30px;
    Höhe: 30px;
  }

  .fortschritt-btn {
    Position: relativ;
    oben: 7px;
    links: 7px;
    Box-Größe: Rahmenbox;
    Breite: 16px;
    Höhe: 16px;
    Rand: 3px durchgezogenes RGB (189, 189, 218);
    Randradius: 50 %;
    Hintergrund: rgb(123, 192, 212);
  }
</Stil>

</html>

Kommentar

https://developer.mozilla.org/zh-CN/docs/Web/API/TouchEvent

Der Fortschrittsbalken in der Mitte ist ein Fortschrittsbalken-Baustein. Der schwarze Hintergrund zeigt die Gesamtlänge des Fortschritts. Der gelbe Balken links zeigt den aktuellen Wiedergabefortschritt. Der Schieberegler in der Mitte kann nach links und rechts gezogen werden, um den Fortschrittsbalken manuell zu ändern. Während der Wiedergabe wird der Fortschrittsbalken länger und der Schieberegler verschiebt sich nach rechts. Sie können den Schieberegler nach links und rechts ziehen, um den Wiedergabefortschritt zu ändern und die Zeit auf der linken Seite ändert sich.

Um den Wiedergabevorgang zu erreichen, wird auch der Fortschrittsbalken abgespielt. Was bestimmt den Status der Komponente? Er kann durch den Fortschritt bestimmt werden. Jeder Status der Komponente kann basierend auf dem Fortschritt bestimmt werden. Die übergeordnete Komponente übergibt einen digitalen Fortschrittstyp

Die Position des Btn und die Breite des gelben Fortschrittsbalkens werden basierend auf dem Fortschritt berechnet. Die Breite kann durch einen Datenversatz dargestellt werden (Daten definieren). Dann müssen wir den Fortschritt überwachen.

https://cn.vuejs.org/v2/api/#vm-el

Wissen zum Abrufen des Stamm-DOM-Elements

      betrachten:
        Fortschritt(neuerFortschritt) {
          // Breite des Fortschrittsbalkens const barWidth = this.$el.clientWidth - progressBtnWidth
          //Offset this.offset = Balkenbreite * neuer Fortschritt
        }
      }

Natürlich können Sie „computed“ verwenden, aber Sie sollten beachten, dass Sie die Breite von el nicht am Anfang abrufen können. „Computed“ berechnet einmal am Anfang, greift auf den Offset zu, wenn die Vorlage gerendert wird, und berechnet dann die Breite von el. Zu diesem Zeitpunkt wurde die Komponente noch nicht gemountet und kann nicht abgerufen werden. Wenn Sie „watch“ verwenden, wurde sie tatsächlich gerendert, wenn sich der Fortschritt ändert, sodass „clientWidth“ abgerufen werden kann. Da einige Logik später verarbeitet werden muss, ist es außerdem anfälliger für das Schreiben von Logik, sodass „watch“ zur Implementierung verwendet werden sollte.

Nachdem wir den Offset haben, müssen wir das DOM zuordnen und einen dynamischen Stil für den gelben Fortschrittsbalken und die Schaltfläche „Btn“ festlegen.

Bildbeschreibung hier einfügen

Beide Stile werden basierend auf dem Offset berechnet.

      berechnet: {
        FortschrittStyle(){
          gibt `Breite: ${this.offset}px` zurück
        },
        btnStyle() {
          gibt `transform: translate3d(${this.offset}px,0,0)` zurück
        }
      },

Berechnen wir nun seinen Stil basierend auf dem Offset. Wir akzeptieren das Fortschrittsattribut. Wenn sich der externe Fortschritt ändert, wird sein Offset basierend auf dem Fortschritt berechnet. Mit dem Offset kann sich der Stil ändern.

Frage: Flex 0 0 40px und Breite haben ähnliche Auswirkungen, aber in einigen Fällen wird das Flex-Layout komprimiert oder reduziert, was zu einer Komprimierung der Breite führt. Durch Festlegen der Breite können Sie also sicherstellen, dass sich unsere Breite nicht ändert.

Hier ist der Canplay-Ereignismonitor

Bildbeschreibung hier einfügen

Die übergeordnete Komponente berechnet den Wiedergabefortschritt der Eigenschaft: Wiedergabezeit/Gesamtzeit. Die Gesamtzeit wurde ermittelt. Die Wiedergabezeit kann mit einem Ereignis überwacht werden: timeupdate

Bildbeschreibung hier einfügen

Aktuelle Wirkung

Es ist ersichtlich, dass es sich um Sekunden handelt und die Zeit formatiert werden muss. Definieren Sie eine Werkzeugfunktion

IIFE: Selbstausführende Funktionscurrying und einige bitweise Operationen https://www.jianshu.com/p/a3202bc3f7a4

Bildbeschreibung hier einfügen

Bildbeschreibung hier einfügen

Eine Frage: Warum ist xxx.yyy|0 gleich xxx? Warum kann der Oder-Operator hier die Funktion des Rundens haben?

Wissen Padstart Methode

formatTime-Funktion

formatTime(Intervall) {
  // Intervall abgerundet Intervall = Intervall | 0
  // Wenn weniger als zwei Ziffern vorhanden sind, füllen Sie mit einer 0 auf
  const minute = ((Intervall / 60 | 0) + '').padstart(2, '0')
  const Sekunde = ((Intervall % 60 | 0) + '').padstart(2, '0')
  return `${Minute}:${Sekunde}`
}

Die Padstart-Methode kann jedoch nicht erkannt werden.

Also habe ich es einfach selbst geschrieben

        formatTime(Intervall) {
          // Intervall abgerundet Intervall = Intervall | 0
          // Wenn weniger als zwei Ziffern vorhanden sind, füllen Sie mit einer 0 auf
          let minute = ((Intervall / 60 | 0) + '')
          sei Sekunde = ((Intervall % 60 | 0) + '')
          let len ​​= minute.länge
          für(;len<2;len++){
            minute='0'+minute
          }
          len = Sekunde.Länge
          für(;len<2;len++){
            Sekunde='0'+Sekunde
          }
          return `${Minute}:${Sekunde}`
        }

Als nächstes schreiben Sie die interaktive Logik des Fortschrittsbalkens

Unterstützt Ziehen und Klicken

Die gängigsten auf Mobilgeräten sind ontouchstart ontouchmove ontouchend
https://developer.mozilla.org/zh-CN/docs/Web/API/TouchEvent

Wissensverhinderungsmodifikator

Fügen Sie dem Slider drei Ereignisse hinzu

      Methoden: {
        beiBerührenStart(e) {
          konsole.log(e);
        },
        beiBerührenBewegung(e) {
          konsole.log(e);
        },
        onTouchEnd(e) {
          konsole.log(e);
        }
      },

Es müssen zwei Informationen ermittelt werden: Zum einen muss man wissen, wo geklickt wurde, also was die horizontale Koordinate ist. Und die Breite des Fortschrittsbalkens links (Offset)

[screenX clientX pageX konzept

Da die Position der horizontalen Achse auch während des Touchmove ermittelt werden muss, können die Daten an ein gemeinsames Objekt gebunden werden. Ein Objekt kann in der erstellten Hook-Funktion definiert werden.

      erstellt() {
        dies.berühren = {}
      },

Nachdem er dem gelben Balken einen Schiedsrichter gegeben hatte

        beiBerührenStart(e) {
          // console.log(e);
          this.touch.x1=e.changedTouches[0].clientX
          // Anfangsbreite des gelben Fortschrittsbalkens this.touch.beginWidth = this.$refs.progress.clientWidth
          Konsole.log(dies.berühren);
        },
        beiBerührenStart(e) {
          // console.log(e);
          this.touch.x1=e.changedTouches[0].clientX
          // Anfangsbreite des gelben Fortschrittsbalkens this.touch.beginWidth = this.$refs.progress.clientWidth
          Konsole.log(dies.berühren);
        },
        beiBerührenBewegung(e) {
          // console.log(e);
          // x-Offset const delta = e.changedTouches[0].clientX-this.touch.x1
          // Vorherige Breite + der durch Ziehen dieses Mal hinzugefügte Versatz = die erwartete Länge des gelben Balkens const tempWidth = this.touch.beginWidth + delta
          // BarWidth erneut abrufen
          const barWidth = this.$el.clientWidth - progressBtnWidth
          // Gelber Balken Länge/Balkenbreite = Fortschritt Der aktuelle Fortschritt const Fortschritt = tempWidth/Balkenbreite
          this.offset = Balkenbreite * Fortschritt
          // console.log("tempWidth", tempWidth);
          // console.log("Balkenbreite", Balkenbreite);
          // console.log("Fortschritt", Fortschritt);

        },

Lassen Sie uns das klären. Das ultimative Ziel ist, den Versatz zu ermitteln. Der Versatz wird durch Fortschritt und Balkenbreite bestimmt. Wie berechnet man hier den Fortschritt? Sie müssen die aktuelle Breite des gelben Balkens durch die Gesamtbreite dividieren. Die Breite des gelben Balkens ist die Anfangsbreite + die x-Distanz dieser Folie. Dann ist es einfach, die Balkenbreite zu ermitteln, und dann können Sie sie berechnen.

Finden Sie, dass das überflüssig ist? Können wir nicht einfach die ursprüngliche Breite des gelben Balkens + die Länge dieser Folie verwenden? Warum müssen wir den Fortschritt berechnen? Weil wir die Außenwelt wissen lassen müssen, dass sich der Fortschritt des Songs geändert hat, und wir müssen dafür sorgen, dass sie übereinstimmen. Letztendlich müssen wir den Ton ändern. Dies geschieht mit der übergeordneten Komponente. Jetzt implementieren wir nur das Ziehen, also müssen wir Ereignisse auslösen. Hier lösen wir zwei benutzerdefinierte Ereignisse aus, ein Fortschrittsänderungsereignis, das bedeutet, dass der Finger noch im Ziehvorgang ist und nicht weggegangen ist. Wenn der Finger weggeht, wird ein Fortschrittsänderungsereignis ausgelöst, um den neuen Fortschritt weiterzugeben.

Ändern Sie den Wert von currentTime in Echtzeit

Bildbeschreibung hier einfügen

Dies dient zum Ändern der aktuellen Zeit beim Ziehen und zum Ändern der Musik, wenn die Hand losgelassen wird.

Bildbeschreibung hier einfügen

Wir haben jedoch festgestellt, dass es im angehaltenen Zustand gezogen werden kann, beim Ziehen während der Wiedergabe jedoch ein Problem auftritt.

Optimierung: Wenn der Effekt beim Ändern angehalten wird, lassen Sie ihn abspielen. Zu diesem Zeitpunkt müssen Sie eine Anzeige definieren, die umschaltet, wenn Sie auf „Wiedergabe/Pause“ klicken.

Bildbeschreibung hier einfügen

Beheben wir nun den Fehler. Beim Abspielen verursacht das Ziehen des Fortschritts Probleme. Warum? Indem wir progressChanging überwachen, ändern wir die aktuelle Zeit. Sobald sich die aktuelle Zeit ändert, führt progress eine neue Berechnung basierend auf der aktuellen Zeit durch und übergibt sie dann an die untergeordnete Komponente. Die untergeordnete Komponente tritt in diese Logik ein.

Bildbeschreibung hier einfügen

Der Offset wird neu berechnet.

Schließlich wird dies abdecken

Bildbeschreibung hier einfügen

Während der Aktualisierung sollte eine gewisse Kontrolle erfolgen und während des Änderungsvorgangs ein Flag hinzugefügt werden.

Bildbeschreibung hier einfügen

Das heißt, wenn in der Aktualisierungsfunktion eine Änderung während des Ziehens erfolgt, darf currentTime nicht geändert werden. Während der Änderung wird davon ausgegangen, dass der Fortschrittsbalken geändert wird, und die Änderung des Fortschrittsbalkens hat eine hohe Priorität. Die Priorität einer Änderung von currentTime, die durch die eigene Wiedergabe verursacht wird, ist relativ niedrig.

Das ist es.

Zusätzlich zum Ziehen möchten wir auch klicken, um an die entsprechende Position zu springen.

Knowledge WebAPI – Die Methode getBoundingClientRect gibt die Größe des Elements und seine Position relativ zum Ansichtsfenster zurück (holen Sie sich das kürzere).

Bildbeschreibung hier einfügen

Verwenden Sie pagex, um die lange Version zu erhalten

        KlickFortschritt(e){
          // konsole.log("fds");
          console.log('getBoundingClientRect', this.$el.getBoundingClientRect());
          const rect = this.$el.getBoundingClientRect()
          // Die Breite des gelben Balkens const offsetWidth = e.pageX - rect.x
          const barWidth = this.$el.clientWidth - progressBtnWidth
          const Fortschritt = Offsetbreite / Balkenbreite
          dies.$emit('Fortschritt geändert', Fortschritt)
          console.log(Offsetbreite)
        }

Dies ist das Ende dieses Artikels über die Vue Song-Fortschrittsbalken-Demo. Weitere relevante Inhalte zum Vue Song-Fortschrittsbalken finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Vue2.0 + SVG realisiert die kreisförmige Fortschrittsbalkenkomponente der Musikwiedergabe
  • Vue2.0 implementiert Fortschrittsbalkenkomponente für Musik-/Videowiedergabe
  • vue.js + ElementUI realisiert den Effekt des Fortschrittsbalkens, der zur Kennwortstärke auffordert
  • Fortschrittsbalkenfunktion beim Laden der Vue-Seite (Beispielcode)

<<:  Lösen Sie das Problem der Docker-Protokollmontage

>>:  MySQL 8.0.22 Zip-komprimierte Paketversion (kostenlose Installation) Download, Installations- und Konfigurationsschritte detailliert

Artikel empfehlen

vue2.x-Konfiguration von vue.config.js zur Projektoptimierung

Inhaltsverzeichnis Vorwort vue.config.js-Konfigur...

Grafisches Tutorial zur Installation und Konfiguration von MySQL 8.0.11

Die Installations- und Konfigurationsmethoden von...

So lösen Sie das Problem verschwommener kleiner Symbole auf Mobilgeräten

Vorwort Zuvor habe ich über das Problem der verti...

Zusammenfassung häufig verwendeter Escape-Zeichen in HTML

Die in HTML häufig verwendeten Escape-Zeichen wer...

Detaillierte Erklärung langsamer MySQL-Abfragen

Informationen zu MySQL-Vorgängen abfragen Status ...

Eine kurze Diskussion über das Funktionswissen von Python

Inhaltsverzeichnis Zwei Hauptkategorien von Funkt...

Grafisches Tutorial zur Installation und Verwendung von MySQL 5.7.17

MySQL ist ein relationales Datenbankverwaltungssy...

Das WeChat-Applet zeichnet die Bewegungsbahn des Benutzers auf

Inhaltsverzeichnis Konfiguration hinzufügen JSON-...

4 Lösungen für CSS-Browserkompatibilitätsprobleme

Frontend ist ein harter Job, nicht nur weil sich ...

Next.js – Erste Schritte-Tutorial

Inhaltsverzeichnis Einführung Erstellen eines Nex...

Zusammenfassung der Spring Boot Docker-Verpackungstools

Inhaltsverzeichnis Spring Boot Docker Spring-Boot...

Schritte zum Exportieren der Felder und zugehörigen Attribute von MySQL-Tabellen

Müssen die Felder und Eigenschaften der Tabelle i...