Table of Contents
Preface
Attribute
Method
Initialization
Insert data
Launch barrages
Other methods
Stop
Start again
Open and close
Clean up the barrages
Finally
Home Web Front-end JS Tutorial How to implement the barrage component in native JavaScript

How to implement the barrage component in native JavaScript

Oct 09, 2020 pm 04:32 PM
javascript Barrage

JavaScript column today introduces you to the method of implementing barrage components in native JavaScript.

How to implement the barrage component in native JavaScript

Preface

Nowadays, almost all video websites have barrage functions, so today we will encapsulate one ourselves using native JavaScript Barrage type. This class hopes to have the following attributes and instance methods:

Attribute

  • elThe selector of the container node. The container node should be absolutely positioned and the width and height should be set.
  • height The height of each barrage
  • mode In barrage mode, half is half the height of the container, and top is one-third. full is the time it takes for the barrage to cross the screen
  • speed
  • gapWidthThe distance between the next barrage and the previous barrage

Method

  • pushData Add barrage metadata
  • addDataContinue to join barrages
  • startStart scheduling barrage
  • stopStop barrage
  • restart Restart barrage
  • clearDataClear the barrage
  • closeClose
  • openRedisplay the barrage

PS: There are some self-encapsulated tool functions that I won’t post here. You just need to know the meaning.

Initialization

After introducing the JavaScript file, we hope to use it as follows , first adopt the default configuration.

1

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

Copy after login

Parameter initialization:

1

2

3

4

5

6

7

8

9

10

11

12

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 = []

}复制代码

Copy after login

Accept the parameters first and then initialize them. Let’s see how getBoxSize and initRows

1

2

3

4

5

6

7

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')))

    }

}复制代码

Copy after login

pass getComputedStyleapi calculates the width and height of the box, which is used to calculate the width and height of the container and will be used later.

1

2

3

4

5

6

7

8

9

10

11

12

13

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 'half':

            pisor = .5

            break

        case 'top':

            pisor = 1 / 3

            break;        case 'full':

            pisor = 1;            break

        default:            break;

    }    return pisor

}复制代码

Copy after login

Calculate how many lines the barrage should have based on the height. The number of lines will be used somewhere below.

Insert data

There are two ways to insert data, one is to add source data, and the other is to continuously add. Let’s first look at the method of adding source data:

1

2

3

4

5

6

7

8

9

10

11

12

13

this.pushData = function (data) {    this.initDom()    if (getType(data) == '[object Object]') {        //插入单条

        this.pushOne(data)

    }    if (getType(data) == '[object Array]') {        //插入多条

        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('p')

            p.classList = `barrage-list barrage-list-${i}`

            p.style.height = `${this.boxSize.height*getpisor(this.mode)/this.rows}px`

            this.container.appendChild(p)

        }

    }

}复制代码

Copy after login

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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

}复制代码

Copy after login

The method of continuously adding data is just to call the method of adding source data and start scheduling

1

2

this.addData = function (data) {    this.pushData(data)    this.start()

}复制代码

Copy after login

Launch barrages

Let’s take a look at the logic of launching barrages

1

2

3

4

5

6

7

8

9

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])

    }

}复制代码

Copy after login

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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('p'),

        parent = document.querySelector(`${el} .barrage-list-${i}`),

        width,

        pastTime

    p.innerHTML = item.content

    p.className = 'barrage-item'

    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);

}复制代码

Copy after login

1

2

3

4

5

6

7

8

9

10

//用css动画,整体还是比较流畅的this.run = function (item) {

    item.classList += ' running'

    item.style.left = "left:100%"

    item.style.display = ''

    item.style.animation = `run ${this.speed/1000}s linear`

    //已完成的打一个标记

    setTimeout(() => {

        item.classList+=' done'

    }, this.speed);

}复制代码

Copy after login

1

2

//根据弹幕的宽度和gapWth,算出下一条弹幕应该出现的时间this.computeTime = function (width) {    let length = width + this.gapWidth    let time = Math.round(length / this.boxSize.width * this.speed/2)    return time

}复制代码

Copy after login

The animation css is as follows

1

2

3

4

5

6

7

8

9

10

11

@keyframes run {

    0% {        left: 100%;

    }

 

    50% {        left: 0

    }

 

    100% {        left: -100%;

    }

}.run {    animation-name: run;

}复制代码

Copy after login

Other methods

Stop

Use the paused attribute of the animation to stop

1

2

3

4

5

this.stop = function () {    let items = document.querySelectorAll(`${el} .barrage-item`);

    [...items].forEach(item => {

        item.className += ' pause'

    })

}复制代码

Copy after login

1

2

.pause {    animation-play-state: paused !important;

}复制代码

Copy after login

Start again

Remove the pause class

1

2

3

4

5

this.restart = function () {    let items = document.querySelectorAll(`${el} .barrage-item`);

    [...items].forEach(item => {

        removeClassName(item, 'pause')

    })

}复制代码

Copy after login

Open and close

Just make a show-hidden logic

1

this.close = function () {    this.container.style.display = 'none'}this.open = function () {    this.container.style.display = ''}复制代码

Copy after login

Clean up the barrages

1

2

3

4

5

6

this.clearData = function () {    //清除list

    this.list = []    //清除dom

    document.querySelector(`${el}`).innerHTML = ''

    //清除timeout

    this.timeoutFuncs.forEach(fun => clearTimeout(fun))

}复制代码

Copy after login

Finally, use a timer to clean up the expired barrages:

1

2

3

4

5

setInterval(() => {    let items = document.querySelectorAll(`${el} .done`);

    [...items].forEach(item=>{

        item.parentNode.removeChild(item)

    })

}, this.speed*5);复制代码

Copy after login

Finally

I feel that the implementation of this is still flawed. If you designed it like this How would you design a class?

Related free learning recommendations: javascript(Video)

The above is the detailed content of How to implement the barrage component in native JavaScript. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot Article Tags

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to implement an online speech recognition system using WebSocket and JavaScript How to implement an online speech recognition system using WebSocket and JavaScript Dec 17, 2023 pm 02:54 PM

How to implement an online speech recognition system using WebSocket and JavaScript

WebSocket and JavaScript: key technologies for implementing real-time monitoring systems WebSocket and JavaScript: key technologies for implementing real-time monitoring systems Dec 17, 2023 pm 05:30 PM

WebSocket and JavaScript: key technologies for implementing real-time monitoring systems

How to implement an online reservation system using WebSocket and JavaScript How to implement an online reservation system using WebSocket and JavaScript Dec 17, 2023 am 09:39 AM

How to implement an online reservation system using WebSocket and JavaScript

How to use JavaScript and WebSocket to implement a real-time online ordering system How to use JavaScript and WebSocket to implement a real-time online ordering system Dec 17, 2023 pm 12:09 PM

How to use JavaScript and WebSocket to implement a real-time online ordering system

Simple JavaScript Tutorial: How to Get HTTP Status Code Simple JavaScript Tutorial: How to Get HTTP Status Code Jan 05, 2024 pm 06:08 PM

Simple JavaScript Tutorial: How to Get HTTP Status Code

JavaScript and WebSocket: Building an efficient real-time weather forecasting system JavaScript and WebSocket: Building an efficient real-time weather forecasting system Dec 17, 2023 pm 05:13 PM

JavaScript and WebSocket: Building an efficient real-time weather forecasting system

Where is the Youku barrage setting? Where is the Youku barrage setting? Feb 29, 2024 pm 09:49 PM

Where is the Youku barrage setting?

How to close Kugou music barrage_How to close Kugou music barrage How to close Kugou music barrage_How to close Kugou music barrage Mar 26, 2024 am 08:56 AM

How to close Kugou music barrage_How to close Kugou music barrage

See all articles