Jadual Kandungan
前言
属性
方法
初始化
插入数据
发射弹幕
其余方法
停止
重新开始
打开关闭
清理弹幕
最后
Rumah hujung hadapan web tutorial js 原生JavaScript实现弹幕组件de方法

原生JavaScript实现弹幕组件de方法

Oct 09, 2020 pm 04:32 PM
javascript Barrage

JavaScript栏目今天为大家介绍原生JavaScript实现弹幕组件的方法。

原生JavaScript实现弹幕组件de方法

前言

如今几乎所有的视频网站都有弹幕功能,那么今天我们就自己用原生 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'})复制代码
Salin selepas log masuk

参数初始化:

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 = []
}复制代码
Salin selepas log masuk

先接受好参数然后初始化,下面看看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')))
    }
}复制代码
Salin selepas log masuk

通过getComputedStyleapi计算出盒子的宽高,这里用来计算容器的宽高,之后也会用到。

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
}复制代码
Salin selepas log masuk

根据高度算出弹幕应该有多少行,下面会有地方用到行数。

插入数据

有两种插入数据的方法,一种是添加源数据,一种是持续添加。先来看添加源数据的方法:

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(&#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)
        }
    }
}复制代码
Salin selepas log masuk
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
}复制代码
Salin selepas log masuk

持续加入数据的方法只是调用了添加源数据的方法,并且开始了调度而已

this.addData = function (data) {    this.pushData(data)    this.start()
}复制代码
Salin selepas log masuk

发射弹幕

下面来看看发射弹幕的逻辑

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])
    }
}复制代码
Salin selepas log masuk
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);
}复制代码
Salin selepas log masuk
//用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);
}复制代码
Salin selepas log masuk
//根据弹幕的宽度和gapWth,算出下一条弹幕应该出现的时间this.computeTime = function (width) {    let length = width + this.gapWidth    let time = Math.round(length / this.boxSize.width * this.speed/2)    return time
}复制代码
Salin selepas log masuk

动画css具体如下

@keyframes run {
    0% {        left: 100%;
    }

    50% {        left: 0
    }

    100% {        left: -100%;
    }
}.run {    animation-name: run;
}复制代码
Salin selepas log masuk

其余方法

停止

利用动画的paused属性停止

this.stop = function () {    let items = document.querySelectorAll(`${el} .barrage-item`);
    [...items].forEach(item => {
        item.className += &#39; pause&#39;
    })
}复制代码
Salin selepas log masuk
.pause {    animation-play-state: paused !important;
}复制代码
Salin selepas log masuk

重新开始

移除pause类即可

this.restart = function () {    let items = document.querySelectorAll(`${el} .barrage-item`);
    [...items].forEach(item => {
        removeClassName(item, &#39;pause&#39;)
    })
}复制代码
Salin selepas log masuk

打开关闭

做一个显示隐藏的逻辑即可

this.close = function () {    this.container.style.display = &#39;none&#39;}this.open = function () {    this.container.style.display = &#39;&#39;}复制代码
Salin selepas log masuk

清理弹幕

this.clearData = function () {    //清除list
    this.list = []    //清除dom
    document.querySelector(`${el}`).innerHTML = &#39;&#39;
    //清除timeout
    this.timeoutFuncs.forEach(fun => clearTimeout(fun))
}复制代码
Salin selepas log masuk

最后用一个定时器定时清理过期的弹幕:

setInterval(() => {    let items = document.querySelectorAll(`${el} .done`);
    [...items].forEach(item=>{
        item.parentNode.removeChild(item)
    })
}, this.speed*5);复制代码
Salin selepas log masuk

最后

感觉这个的实现还是有缺陷的,如果是你设计这么一个类,你会怎么设计呢?

相关免费学习推荐:javascript(视频)

Atas ialah kandungan terperinci 原生JavaScript实现弹幕组件de方法. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
3 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimana untuk melaksanakan sistem pengecaman pertuturan dalam talian menggunakan WebSocket dan JavaScript Bagaimana untuk melaksanakan sistem pengecaman pertuturan dalam talian menggunakan WebSocket dan JavaScript Dec 17, 2023 pm 02:54 PM

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

WebSocket dan JavaScript: teknologi utama untuk melaksanakan sistem pemantauan masa nyata WebSocket dan JavaScript: teknologi utama untuk melaksanakan sistem pemantauan masa nyata Dec 17, 2023 pm 05:30 PM

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Bagaimana untuk melaksanakan sistem tempahan dalam talian menggunakan WebSocket dan JavaScript Bagaimana untuk melaksanakan sistem tempahan dalam talian menggunakan WebSocket dan JavaScript Dec 17, 2023 am 09:39 AM

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian Dalam era digital hari ini, semakin banyak perniagaan dan perkhidmatan perlu menyediakan fungsi tempahan dalam talian. Adalah penting untuk melaksanakan sistem tempahan dalam talian yang cekap dan masa nyata. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian dan memberikan contoh kod khusus. 1. Apakah itu WebSocket? WebSocket ialah kaedah dupleks penuh pada sambungan TCP tunggal.

Cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata Cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata Dec 17, 2023 pm 12:09 PM

Pengenalan kepada cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata: Dengan populariti Internet dan kemajuan teknologi, semakin banyak restoran telah mula menyediakan perkhidmatan pesanan dalam talian. Untuk melaksanakan sistem pesanan dalam talian masa nyata, kami boleh menggunakan teknologi JavaScript dan WebSocket. WebSocket ialah protokol komunikasi dupleks penuh berdasarkan protokol TCP, yang boleh merealisasikan komunikasi dua hala masa nyata antara pelanggan dan pelayan. Dalam sistem pesanan dalam talian masa nyata, apabila pengguna memilih hidangan dan membuat pesanan

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Dec 17, 2023 pm 05:13 PM

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Tutorial JavaScript Mudah: Cara Mendapatkan Kod Status HTTP Tutorial JavaScript Mudah: Cara Mendapatkan Kod Status HTTP Jan 05, 2024 pm 06:08 PM

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

Bagaimana untuk menggunakan insertBefore dalam javascript Bagaimana untuk menggunakan insertBefore dalam javascript Nov 24, 2023 am 11:56 AM

Penggunaan: Dalam JavaScript, kaedah insertBefore() digunakan untuk memasukkan nod baharu dalam pepohon DOM. Kaedah ini memerlukan dua parameter: nod baharu untuk dimasukkan dan nod rujukan (iaitu nod di mana nod baharu akan dimasukkan).

Cara menutup rentetan muzik Kugou_Cara menutup rentetan muzik Kugou Cara menutup rentetan muzik Kugou_Cara menutup rentetan muzik Kugou Mar 26, 2024 am 08:56 AM

1. Mula-mula buka antara muka main balik muzik Kugou. 2. Kemudian klik Komen pada antara muka main balik. 3. Masukkan komen dan anda boleh lihat pilihan komen di atas. 4. Akhir sekali, pilih untuk menutup semakan dan kembali ke antara muka main balik.

See all articles