Heim > Web-Frontend > js-Tutorial > So implementieren Sie die Barrage-Komponente in nativem JavaScript

So implementieren Sie die Barrage-Komponente in nativem JavaScript

coldplay.xixi
Freigeben: 2020-10-09 16:32:29
nach vorne
2299 Leute haben es durchsucht

In der Kolumne „

JavaScript“ wird heute vorgestellt, wie Barrage-Komponenten mit nativem JavaScript implementiert werden.

So implementieren Sie die Barrage-Komponente in nativem JavaScript

Vorwort

Heutzutage verfügen fast alle Video-Websites über die Barrage-Funktion, daher werden wir heute natives JavaScript verwenden, um eine Barrage-Klasse zu kapseln. Diese Klasse hofft, über die folgenden Attribute und Instanzmethoden zu verfügen: JavaScript 封装一个弹幕类。这个类希望有如下属性和实例方法:

属性

  • el容器节点的选择器,容器节点应为绝对定位,设置好宽高
  • height 每条弹幕的高度
  • mode 弹幕模式,half则为一半容器高度,top为三分之一,full为占满
  • speed弹幕划过屏幕的时间
  • gapWidth后一条弹幕与前一条弹幕的距离

方法

  • pushData 添加弹幕元数据
  • addData持续加入弹幕
  • start开始调度弹幕
  • stop停止弹幕
  • restart 重新开始弹幕
  • clearData清空弹幕
  • close关闭
  • open重新显示弹幕

PS:有一些自封装的工具函数就不贴出来了,大概知道意思就好

初始化

引入JavaScript文件之后,我们希望如下使用,先采取默认配置。

let barrage = new Barrage({    el: '#container'})复制代码
Nach dem Login kopieren

参数初始化:

function Barrage(options) {    let {
        el,
        height,
        mode,
        speed,
        gapWidth,
    } = options    this.container = document.querySelector(el)    this.height = height || 30
    this.speed = speed || 15000 //2000ms
    this.gapWidth = gapWidth || 20
    this.list = []    this.mode = mode || 'half'
    this.boxSize = getBoxSize(this.container)    this.perSpeed = Math.round(this.boxSize.width / this.speed)    this.rows = initRows(this.boxSize, this.mode, this.height)    this.timeoutFuncs = []    this.indexs = []    this.idMap = []
}复制代码
Nach dem Login kopieren

先接受好参数然后初始化,下面看看getBoxSizeinitRows

function getBoxSize(box) {    let {
        height,
        width
    } = window.getComputedStyle(box)    return {        height: px2num(height),        width: px2num(width)
    }    function px2num(str) {        return Number(str.substring(0, str.indexOf('p')))
    }
}复制代码
Nach dem Login kopieren

通过getComputedStyle

Attribute

  • el Selektor für Containerknoten, Containerknoten sollten sein absolute Position, legen Sie die Breite und Höhe fest
  • height Die Höhe jedes Sperrfeuers
  • mode Sperrmodus, halb ist halb Die Die Höhe des Behälters beträgt ein Drittel, und „full“ ist voll
  • speedDie Zeit, die das Sperrfeuer braucht, um den Bildschirm zu überqueren
  • gapWidth </code >Der Abstand zwischen dem nächsten Aufzählungszeichen und dem vorherigen Aufzählungszeichen</li></ul><h2 data-id="heading-2">Methode <p><ul><li><code>pushData Aufzählungsbildschirm-Metadaten hinzufügen
  • addDataBarrage kontinuierlich hinzufügen
  • startPlanung von Barrage starten
  • stopStoppen Sie das Sperrfeuer
  • restart Starten Sie das Sperrfeuer erneut
  • clearDataLöschen Sie das Sperrfeuer
  • schließenSchließen
  • öffnenAnzeigen Sie die Sperre erneut

PS: Es gibt einige selbstgekapselte Werkzeugfunktionen, die ich gewonnen habe Ich poste es hier nicht, aber Sie wissen wahrscheinlich, was es bedeutet.

function initRows(box, mode, height) {    let pisor = getpisor(mode)
    rows = Math.ceil(box.height * pisor / height)    return rows
}function getpisor(mode) {    let pisor = .5
    switch (mode) {        case &#39;half&#39;:
            pisor = .5
            break
        case &#39;top&#39;:
            pisor = 1 / 3
            break;        case &#39;full&#39;:
            pisor = 1;            break
        default:            break;
    }    return pisor
}复制代码
Nach dem Login kopieren

Parameterinitialisierung:

this.pushData = function (data) {    this.initDom()    if (getType(data) == &#39;[object Object]&#39;) {        //插入单条
        this.pushOne(data)
    }    if (getType(data) == &#39;[object Array]&#39;) {        //插入多条
        this.pushArr(data)
    }
}this.initDom = function () {    if (!document.querySelector(`${el} .barrage-list`)) {        //注册dom节点
        for (let i = 0; i < this.rows; i++) {            let p = document.createElement(&#39;p&#39;)
            p.classList = `barrage-list barrage-list-${i}`
            p.style.height = `${this.boxSize.height*getpisor(this.mode)/this.rows}px`
            this.container.appendChild(p)
        }
    }
}复制代码
Nach dem Login kopieren

Akzeptieren Sie zuerst die Parameter und initialisieren Sie sie dann. Werfen wir einen Blick auf getBoxSize und initRows

this.pushOne = function (data) {    for (let i = 0; i < this.rows; i++) {        if (!this.list[i]) this.list[i] = []

    }    let leastRow = getLeastRow(this.list) //获取弹幕列表中最少的那一列,弹幕列表是一个二维数组
    this.list[leastRow].push(data)
}this.pushArr = function (data) {    let list = sliceRowList(this.rows, data)
    list.forEach((item, index) => {        if (this.list[index]) {            this.list[index] = this.list[index].concat(...item)
        } else {            this.list[index] = item
        }
    })
}//根据行数把一维的弹幕list切分成rows行的二维数组function sliceRowList(rows, list) {    let sliceList = [],
        perNum = Math.round(list.length / rows)    for (let i = 0; i < rows; i++) {        let arr = []        if (i == rows - 1) {
            arr = list.slice(i * perNum)
        } else {
            i == 0 ? arr = list.slice(0, perNum) : arr = list.slice(i * perNum, (i + 1) * perNum)
        }
        sliceList.push(arr)
    }    return sliceList
}复制代码
Nach dem Login kopieren

berechnet durch getComputedStyle api Aus der Breite und Höhe der Box werden die Breite und Höhe des Containers berechnet, die später auch verwendet werden.

this.addData = function (data) {    this.pushData(data)    this.start()
}复制代码
Nach dem Login kopieren

Berechnen Sie anhand der Höhe, wie viele Linien das Sperrwerk haben sollte. Die Anzahl der Linien wird irgendwo unten verwendet.

Daten einfügen

Es gibt zwei Möglichkeiten, Daten einzufügen: Eine besteht darin, Quelldaten hinzuzufügen, und die andere darin, kontinuierlich hinzuzufügen. Schauen wir uns zunächst die Methode zum Hinzufügen von Quelldaten an:

this.start = function () {    //开始调度list
    this.dispatchList(this.list)
}this.dispatchList = function (list) {    for (let i = 0; i < list.length; i++) {        this.dispatchRow(list[i], i)
    }
}this.dispatchRow = function (row, i) {    if (!this.indexs[i] && this.indexs[i] !== 0) {        this.indexs[i] = 0
    }    //真正的调度从这里开始,用一个实例变量存储好当前调度的下标。
    if (row[this.indexs[i]]) {        this.dispatchItem(row[this.indexs[i]], i, this.indexs[i])
    }
}复制代码
Nach dem Login kopieren
this.dispatchItem = function (item, i) {    //调度过一次的某条弹幕下一次在调度就不需要了
    if (!item || this.idMap[item.id]) {        return
    }    let index = this.indexs[i]    this.idMap[item.id] = item.id    let p = document.createElement(&#39;p&#39;),
        parent = document.querySelector(`${el} .barrage-list-${i}`),
        width,
        pastTime
    p.innerHTML = item.content
    p.className = &#39;barrage-item&#39;
    parent.appendChild(p)
    width = getBoxSize(p).width
    p.style = `width:${width}px;display:none`
    pastTime = this.computeTime(width) //计算出下一条弹幕应该出现的时间
    //弹幕飞一会~
    this.run(p)    if (index > this.list[i].length - 1) {        return
    }    let len = this.timeoutFuncs.length    //记录好定时器,后面清空
    this.timeoutFuncs[len] = setTimeout(() => {        this.indexs[i] = index + 1
        //递归调用下一条
        this.dispatchItem(this.list[i][index + 1], i, index + 1)
    }, pastTime);
}复制代码
Nach dem Login kopieren

Die Methode zum kontinuierlichen Hinzufügen von Daten besteht lediglich darin, die Methode zum Hinzufügen von Quelldaten aufzurufen und mit der Planung zu beginnen

//用css动画,整体还是比较流畅的this.run = function (item) {
    item.classList += &#39; running&#39;
    item.style.left = "left:100%"
    item.style.display = &#39;&#39;
    item.style.animation = `run ${this.speed/1000}s linear`
    //已完成的打一个标记
    setTimeout(() => {
        item.classList+=&#39; done&#39;
    }, this.speed);
}复制代码
Nach dem Login kopieren
//根据弹幕的宽度和gapWth,算出下一条弹幕应该出现的时间this.computeTime = function (width) {    let length = width + this.gapWidth    let time = Math.round(length / this.boxSize.width * this.speed/2)    return time
}复制代码
Nach dem Login kopieren
@keyframes run {
    0% {        left: 100%;
    }

    50% {        left: 0
    }

    100% {        left: -100%;
    }
}.run {    animation-name: run;
}复制代码
Nach dem Login kopieren
this.stop = function () {    let items = document.querySelectorAll(`${el} .barrage-item`);
    [...items].forEach(item => {
        item.className += &#39; pause&#39;
    })
}复制代码
Nach dem Login kopieren

Das Animations-CSS lautet wie folgt:

.pause {    animation-play-state: paused !important;
}复制代码
Nach dem Login kopieren

Die restlichen Methoden: reee

Öffnen und schließen

Erstellen Sie einfach eine Show-Hide-Logik Wie würden Sie eine solche Klasse gestalten?

Verwandte kostenlose Lernempfehlungen:

Javascript

(Video)

Das obige ist der detaillierte Inhalt vonSo implementieren Sie die Barrage-Komponente in nativem JavaScript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:juejin.im
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage