知識
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏壧峁┍憬莸闹С郑?
您當(dāng)前位置>首頁 » 新聞資訊 » 小程序相關(guān) >
小程序直播-評論彈幕是如何“練”成的?
發(fā)表時間:2021-1-5
發(fā)布人:葵宇科技
瀏覽次數(shù):108
近期,電商直播業(yè)務(wù)熱火朝天,為了烘托直播間的氛圍,達(dá)到主播與觀眾的有效正反饋,彈幕、點(diǎn)贊、用戶行為提示三件套成為一個標(biāo)準(zhǔn)的直播間必不可少的裝備。兩個月前,作者曾解析了點(diǎn)贊動畫的實(shí)現(xiàn)原理,雖文筆粗糙,但在總結(jié)中,對技術(shù)原理有了更加透徹的理解。恰逢近期沉淀直播間業(yè)務(wù),重新封裝了彈幕組件,對代碼的設(shè)計有了新的理解,總結(jié)成一篇文章,與君共享。
提起彈幕(dànmù),大家都會想到「視頻彈幕」。視頻彈幕是指網(wǎng)友們在觀看視頻的同時參與評論,即所謂“即時反饋”, 評論以飛行形式橫穿屏幕,視覺效果類似多發(fā)密集的子彈飛速而過,故稱之為“彈幕”。“彈幕”最大的特點(diǎn)就是允許受眾在觀看直播的同時將評論內(nèi)容發(fā)送到服務(wù)器與直播同步播放,這可以讓觀眾的反饋瞬間產(chǎn)生,與主播發(fā)生即時互動,甚至可以形成隔空對話。
隨著手機(jī)豎屏直播時代的到來,彈幕也從原本的“橫穿飛行”,衍生出一種新的模式——在屏幕左下方豎向滾動。實(shí)際效果如下圖所示。
從效果圖上我們還看到有幾點(diǎn)重要信息:
- 歷史彈幕上屏:為了活躍氣氛,觀眾初次進(jìn)入直播間可以觀看前 30 條歷史彈幕。
- 即時彈幕消息上屏:即時收到的彈幕消息從底部上屏,并實(shí)現(xiàn)自動滾動。
- 個人評論消息上屏:個人評論的消息“優(yōu)先”上屏,不受即時消息堆積影響。
- 系統(tǒng)提示消息上屏:系統(tǒng)提示消息分兩種,一種是固定提示,固定在彈幕列表頭部,不會消失。另外一種是主播操作產(chǎn)生的臨時提示,跟彈幕消息一起,超過數(shù)量限制時,就會被清理。
看似簡單,實(shí)現(xiàn)的過程中卻需考慮如下幾點(diǎn):
- 即時消息堆積問題: 在李佳琦、薇婭等超級主播的直播間,每秒接收到的消息數(shù)以千計,如果不做“屏控”處理,且有計劃地過濾掉“低質(zhì)”彈幕,而是一股腦地將消息上屏,彈幕便會飛速滾動,那么觀眾和主播都無法有效地獲取內(nèi)容信息。
- 上屏彈幕堆積問題: 隨著時間的推移,上屏彈幕數(shù)量逐漸累積,如果不及時清理陳舊的
DOM
節(jié)點(diǎn),會導(dǎo)致系統(tǒng)卡頓,甚至程序崩潰。 - 用戶互動體驗(yàn)優(yōu)化問題: 當(dāng)用戶滾動彈幕時,需要暫停彈幕上屏邏輯,便于用戶進(jìn)行操作;當(dāng)彈幕滾動到底部時,自動恢復(fù)彈幕上屏邏輯;長期暫停的彈幕需要設(shè)有自動恢復(fù)機(jī)制,等等體驗(yàn)問題都是需要優(yōu)化的內(nèi)容。
- 歷史彈幕上屏問題: 如若 30 條歷史彈幕一窩蜂上屏,彈幕會飛速滾動,給用戶極差的體驗(yàn)觀感,需要制定策略實(shí)現(xiàn)分布式上屏。
一口吃不成胖子,先從效果圖顯示的布局入手,思考封裝這個組件,需要傳入哪些參數(shù),哪些是通過properties
由父組件傳入,哪些通過data
來維護(hù),與視圖進(jìn)行通信。
data = http://www.wxapp-union.com/{
toLast: 'item0', // 彈幕滾動索引
realBarrage: [], // 實(shí)際上屏的彈幕
};
properties = {
barrageHeight: {
type: Number,
value: 500,
}, // 彈幕容器高度
config: {
type: Object,
value: DEFAULT_CONFIG,
}, // 彈幕配置
tagConfig: {
type: Array,
value: TAG_DEFAULT_CONFIG,
}, // 標(biāo)簽配置信息
systemHint: {
type: String,
value: DEFAULT_SYSTEM_HINT,
}, // 系統(tǒng)提示信息
};
復(fù)制代碼
先來談?wù)?code>properties屬性:
- barrageHeight: Number類型,彈幕容器高度,可動態(tài)調(diào)節(jié),如下圖所示,超級彈幕出現(xiàn)時,需要縮小彈幕高度。
- systemHint:String類型,系統(tǒng)提示信息內(nèi)容,長期存在于彈幕列表頭部,默認(rèn)配置信息如下。
const DEFAULT_SYSTEM_HINT =
'系統(tǒng)提示:歡迎來到直播間!直享倡導(dǎo)綠色直播,文明互動,購買直播推薦商品時,請確認(rèn)購買鏈接描述與實(shí)際商品一致,避免上當(dāng)受騙。如遇違法違規(guī)現(xiàn)象,請立即舉報!';
復(fù)制代碼
- config:Object類型,彈幕配置信息, 可配置參數(shù)如下:
const DEFAULT_CONFIG = {
INTERVAL: 300, // 刷新頻率,默認(rèn)300ms
BARRAGE_MAX_COUNT: 50, // 上屏彈幕的最大數(shù)量
POOL_MAX_COUNT: 50, // 彈幕池(未上屏)彈幕上限
BARRAGE_MAX_FRAME: 6, // 屏控處理,每次同時上屏彈幕的數(shù)量
SLEEP_TIME: 5000, // 彈幕休眠時間,默認(rèn)5000ms
CHECK_SLEEP: true, // 是否休眠,休眠超過 SLEEP_TIME ,則開啟自動滾動
};
復(fù)制代碼
- tagConfig:Array類型,標(biāo)簽配置信息,主要用于自定義化標(biāo)簽的樣式和內(nèi)容,當(dāng)前的默認(rèn)配置如下:
const TAG_DEFAULT_CONFIG = [
{
bgColor: 'linear-gradient(to right, #fb3e3e, #ff834a)',
tagName: '主播',
},
{
bgColor: 'linear-gradient(to top, #ffb365, #ff8c17)',
tagName: '號主',
},
{
bgColor: 'linear-gradient(to left, #8bb1ff, #5195ff)',
tagName: '粉絲',
},
];
復(fù)制代碼
然后,再談?wù)?code>data屬性:
- realBarrage: Array類型,實(shí)際上屏的彈幕列表,分兩種,一種是評論消息,一種是系統(tǒng)消息。彈幕列表中每一項(xiàng)包含的屬性類型說明如下:
interface queueI {
name?: string; // 用戶昵稱
comment?: string; // 評論內(nèi)容
isMe?: boolean; // 是否自己發(fā)送的彈幕
tagIndex?: number; // 標(biāo)簽索引,可自定義,默認(rèn)情況 0-主播,1-號主,2-粉絲
systemInfo?: string; // 系統(tǒng)提示消息,如果存在這個屬性,則前面四個屬性無需存在
}
復(fù)制代碼
其中,name
、comment
為普通評論消息的必須屬性,systemInfo
為系統(tǒng)消息的必須屬性,兩者互斥。 彈幕數(shù)據(jù)tagIndex
屬性與標(biāo)簽配置信息中TAG_DEFAULT_CONFIG
數(shù)組的索引一一對應(yīng),默認(rèn)情況 0-主播,1-號主,2-粉絲。如果修改標(biāo)簽配置信息,那么tagIndex
屬性值的對應(yīng)關(guān)系也要重新梳理。
- toLast: String類型,彈幕索引,隨著新彈幕不斷上屏,彈幕列表需要實(shí)現(xiàn)自動滾動,小程序提供的
組件的scroll-into-view
屬性支持滾動到對應(yīng)的子元素 id,所以需要維護(hù)toLast
來指定。
知道了每個data
與properties
的含義,可以根據(jù)設(shè)計稿,對布局一把梭了。為了實(shí)現(xiàn)可滾動視圖區(qū)域,組件外層使用
包裹。用到的屬性如下表所示:
屬性 | 類型 | 說明 | 默認(rèn)值 | 必填 |
---|---|---|---|---|
scroll-y | boolean | 允許縱向滾動 | false | 否 |
scroll-with-animation | boolean | 在設(shè)置滾動條位置時使用動畫過渡 | false | 否 |
scroll-into-view | string | 值應(yīng)為某子元素 id(id 不能以數(shù)字開頭)。設(shè)置哪個方向可滾動,則在哪個方向滾動到該元素 | - | 否 |
lower-threshold | number/string | 距底部/右邊多遠(yuǎn)時,觸發(fā) scrolltolower 事件 | 50 | 否 |
bindscrolltolower | eventhandle | 滾動到底部/右邊時觸發(fā) | - | 否 |
bindscroll | eventhandle | 滾動時觸發(fā),event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY} | - | 否 |
bindtouchstart | eventhandle | 手指觸摸動作開始 | - | 否 |
bindtouchend | eventhandle | 手指觸摸動作開始 | - | 否 |
容器內(nèi)的子元素包含兩部分,一部分的直播間提示消息,放在滾動列表的頭部,永遠(yuǎn)不會被清理。另外一部分是即時消息,分為評論消息和系統(tǒng)消息,放在realBarrage
中,達(dá)到數(shù)量最大限制時會被清理。
視圖布局代碼如下所示:
<scroll-view class="live-barrage wr-class" style="max-height:{{barrageHeight}}rpx;" scroll-y="true" scroll-with-animation="true" scroll-into-view="{{toLast}}" bindtouchstart="barrageTouchStart" bindtouchend="barrageTouchEnd" lower-threshold="100" bindscroll="handleScrollBarrageContainer" bindscrolltolower="handleScrollBottom">
<view class="live-barrage-system system-class" id="item0">{{systemHint}}view>
<view class="{{item.systemInfo? 'live-barrage-system' : 'live-barrage-item item-class'}}" wx:for="{{realBarrage}}" wx:for-item="item" wx:key="index" id="item{{index+1}}">
<view class="live-barrage-item-content" wx:if="{{!item.systemInfo}}">
<view class="live-barrage-item-content-tag" wx:if="{{item.tagIndex >= 0 && tagConfig[item.tagIndex]}}" style="background-image: {{tagConfig[item.tagIndex].bgColor}}">
{{tagConfig[item.tagIndex].tagName}}
view>
<view class="{{item.isMe ? 'live-barrage-item-content-name-me' : 'live-barrage-item-content-name'}}">
{{item.name}}:\t
view>
{{item.comment}}
view>
<view wx:else>{{item.systemInfo}}view>
view>
scroll-view>
復(fù)制代碼
根據(jù)需求,對功能進(jìn)行思考和拆分,抽象出一個通用類,此處定義為QueueBarrage
。這個類維護(hù)兩個優(yōu)先級隊(duì)列,一個是彈幕池,一個是上屏彈幕。服務(wù)器推送的彈幕消息進(jìn)入彈幕池,池子里的彈幕需要進(jìn)行過濾重排、溢出處理。設(shè)置輪詢機(jī)制,對彈幕進(jìn)行分批次上屏,同時上屏彈幕也設(shè)有溢出處理策略。自己發(fā)送的彈幕不走彈幕池,直接上屏。
下列代碼是類的屬性定義和構(gòu)造器。
- queueList:彈幕池,包括所有未上屏的彈幕。
- barrageList:上屏的彈幕列表。
- changeCallback:彈幕上屏回調(diào),彈幕上屏邏輯是業(yè)務(wù)邏輯,需要以回調(diào)的形式傳入。
- config: 彈幕配置信息,通過創(chuàng)建類實(shí)例傳參,可以覆蓋默認(rèn)配置信息。
export default class QueueBarrage {
queueList: queueI[]; // 彈幕池,包括所有彈幕
barrageList: queueI[]; // 上屏彈幕
changeCallback; // 彈幕上屏回調(diào)
config; // 配置信息
isPaused: boolean; // 彈幕是否暫停
isActive: boolean; // 彈幕是否休眠
timer;
private checkActiveTimer;
constructor(config = {}) {
this.config = { ...defaultConFig, ...config };
this.queueList = [];
this.barrageList = [];
this.isPaused = false;
this.isActive = false;
this.flush();
}
}
復(fù)制代碼
前面提到過,在李佳琦、薇婭等超級主播的直播間,每秒接收到的消息數(shù)以千計,如果直接一股腦地將消息上屏,彈幕便會飛速滾動,那么觀眾和主播都無法有效地獲取內(nèi)容信息。因此,需要維護(hù)一個「彈幕池」,能對彈幕進(jìn)行優(yōu)先級排序,有效地過濾掉“低質(zhì)”彈幕,同時對池子的容量做限制,添加“溢出”處理策略。
代碼實(shí)現(xiàn)如下所示,將消息放入彈幕池,如果彈幕數(shù)量超出最大數(shù)量限制,則對彈幕進(jìn)行過濾,同時刪除超出的那部分彈幕。當(dāng)然,歷史彈幕信息為了保證上下文邏輯的嚴(yán)謹(jǐn)性,是無需進(jìn)行優(yōu)先級排序的,所以只需要截取超出的部分。為了區(qū)分兩種彈幕類型,本函數(shù)的第二個參數(shù)isFilter
用來控制是否進(jìn)行過濾。
barrageEnterQueue(queue: queueI[], isFilter = true) {
queue.forEach(v => {
this.queueList.push(v);
});
// 進(jìn)入直播間歷史彈幕不進(jìn)行過濾
if (this.queueList.length > this.config.POOL_MAX_COUNT) {
if (isFilter)
this.queueList = filter(this.queueList, this.config.POOL_MAX_COUNT);
else
this.queueList.splice(
0,
this.queueList.length - this.config.POOL_MAX_COUNT,
);
}
if (!this.isPaused) {
!this.timer && this.flush();
}
}
復(fù)制代碼
那么過濾規(guī)則是怎么樣的呢?這得視業(yè)務(wù)情況而定,下面貼出本業(yè)務(wù)的彈幕過濾邏輯:
- 無意義彈幕的權(quán)重降低 0.5
- 短彈幕的權(quán)重降低 0.2
自己發(fā)送的彈幕的權(quán)重提高 1.0
這里需要注意的是,自己發(fā)送的彈幕的權(quán)重優(yōu)先級是最高的,可以走彈幕池,通過過濾提高優(yōu)先級,但這需要一定的時間消耗。不走彈幕池,直接上屏是比較合理的實(shí)現(xiàn)方案。
const CONTENT_FIELD = 'comment';
const REG_MEANINGLESS = /^[\d\s\!\@\#\$\%\^\&\*\(\)\-\=]+$/;
// 權(quán)重計算規(guī)則
const rules = [
function meaningless(this: any, weight) {
return this[CONTENT_FIELD] && REG_MEANINGLESS.test(this[CONTENT_FIELD])
? weight - 0.5
: weight;
},
function barrage2short(this: any, weight) {
return this[CONTENT_FIELD] && this[CONTENT_FIELD].length < 3
? weight - 0.2
: weight;
},
];
復(fù)制代碼
接下來,便可根據(jù)權(quán)重計算規(guī)則對彈幕進(jìn)行排序且篩選。第一個參數(shù)是彈幕列表,第二個參數(shù)是最大數(shù)量限制。
export function filter(barrages, limit) => {
barrages.forEach(barrage => {
barrage.weight = rules.reduce((weight, rule) => {
return rule.call(barrage, weight);
}, 1);
});
return barrages
.sort((a, b) => b.weight - a.weight)
.slice(barrages.length - limit);
};
復(fù)制代碼
3.3 輪詢上屏
將消息放入彈幕池后,接下來的操作便是輪詢從彈幕池里取固定數(shù)量的彈幕上屏。實(shí)現(xiàn)邏輯如下所示:
- 第一步,從彈幕池里取出固定數(shù)量為
BARRAGE_MAX_FRAME
(默認(rèn)為 6)的彈幕,添加到barrageList
(上屏彈幕列表)中。如上效果圖所示,6 條彈幕同時上屏,正好在一個屏幕高度內(nèi),不影響用戶獲取內(nèi)容信息。 - 第二步,對
barrageList
列表做溢出處理,超出最大數(shù)量限制BARRAGE_MAX_COUNT
(默認(rèn)為 50),刪除列表頭部超出數(shù)量的彈幕。這樣可以將上屏彈幕的數(shù)量維持在一個最大閾值內(nèi)。如上效果圖所示,彈幕列表數(shù)量超出閾值,頭部的彈幕已經(jīng)被清理,用戶只能獲取最新的 50 條彈幕。 - 第三步,
barrageList
得到更新后,需要執(zhí)行changeCallback
回調(diào)做真正的上屏處理,這個回調(diào)涉及業(yè)務(wù)邏輯操作,需要在類實(shí)例化的時候進(jìn)行賦值。 - 使用
setTimeout
實(shí)現(xiàn)輪詢機(jī)制,每INTERVAL
ms(默認(rèn)為 300)執(zhí)行如上 3 步操作,如果上屏彈幕列表為空,表示沒有新的彈幕消息,則不執(zhí)行上屏回調(diào)處理。需要注意的是,這里用setTimeout
模擬setInterval
實(shí)現(xiàn)輪詢,這是因?yàn)楫?dāng)回調(diào)函數(shù)的執(zhí)行被阻塞時,setInterval
會產(chǎn)生回調(diào)堆積。
private flush() {
this.timer = setTimeout(() => {
if (this.queueList.length > 0) {
// 從彈幕池中取彈幕
this.barrageList = [
...this.barrageList,
...this.queueList.splice(0, this.config.BARRAGE_MAX_FRAME),
];
// 判斷上屏彈幕是否超過最大限制,如超過,刪除舊彈幕
if (this.barrageList.length > this.config.BARRAGE_MAX_COUNT) {
this.barrageList.splice(
0,
this.barrageList.length - this.config.BARRAGE_MAX_COUNT,
);
}
// 彈幕上屏
this.barrageList.length > 0 &&
this.changeCallback &&
this.changeCallback(this.barrageList);
}
this.flush();
}, this.config.INTERVAL);
}
// 彈幕上屏回調(diào)函數(shù)賦值
emitQueueChange(cb) {
this.changeCallback = cb;
}
復(fù)制代碼
用戶自己發(fā)送的彈幕,不走彈幕池過濾,無視網(wǎng)絡(luò)質(zhì)量,無條件優(yōu)先上屏。代碼如下所示:
// 自己的彈幕直出
barrageEnterQueueSelf(queue: queueI) {
this.barrageList.push(queue);
this.changeCallback && this.changeCallback(this.barrageList);
}
復(fù)制代碼
- 當(dāng)用戶滑動彈幕列表時,為了方便用戶執(zhí)行截圖、賦值、搜索等操作,彈幕上屏邏輯需要暫停。
- 當(dāng)用戶將列表滾動到底部時,恢復(fù)輪詢。
- 同時需要設(shè)置重啟機(jī)制,當(dāng)彈幕暫停時間超過
SLEEP_TIME
ms(默認(rèn)為 5000),且用戶不在執(zhí)行其它操作,彈幕恢復(fù)輪詢。
具體的處理邏輯如下所示:
// 檢查彈幕是否激活
setActiveAndAutoRestart() {
// 如果沒有開啟
if (!this.config.CHECK_SLEEP) return;
if (this.checkActiveTimer) {
clearTimeout(this.checkActiveTimer);
}
this.checkActiveTimer = setTimeout(() => {
this.restart();
}, this.config.SLEEP_TIME);
}
// 彈幕暫停滾動
pause() {
if (this.isPaused) return;
this.isPaused = true;
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
this.setActiveAndAutoRestart();
}
// 彈幕重新開始滾動
restart() {
if (!this.isPaused) return;
this.isPaused = false;
this.queueList.length && this.flush();
}
復(fù)制代碼
- attached,組件掛載時,創(chuàng)建
Barrage
類實(shí)例,設(shè)置彈幕上屏的實(shí)際回調(diào)方法,通過toLast
值指定列表滾動到該元素,通過更新realBarrage
數(shù)據(jù),來更新實(shí)際上屏的數(shù)據(jù)。 - detached,組件銷毀時,清除
Barrage
類實(shí)例,同時對定時器進(jìn)行清理。
attached() {
// 創(chuàng)建Barrage實(shí)例
this.barrage = new Barrage(this.properties.config);
// 初始化輪詢回調(diào)方法
this.barrage.emitQueueChange(data => {
this.setData({
toLast: `item${data.length}`,
realBarrage: data,
});
});
// 校準(zhǔn)彈幕容器高度
this.checkContainerClientHeight();
}
detached() {
this.barrage && this.barrage.destroy();
}
復(fù)制代碼
父組件可以通過 id 獲取彈幕組件的實(shí)例,從而調(diào)用其封裝的方法。用法如下所示:
<wr-live-barrage id="wr-live-barrage">wr-live-barrage>
復(fù)制代碼
// 獲取彈幕組件實(shí)例
getBarrageContext() {
if (!this.barrageContext) {
(this.barrageContext as any) = this.selectComponent('#wr-live-barrage');
}
return this.barrageContext;
}
// 調(diào)用方法示例
handleSendBarrage() {
(this.getBarrageContext() as any).sendBarrageBySelf(data);
}
復(fù)制代碼
彈幕組件暴露的三個方法如下表格所示:
API | 說明 | 參數(shù) | 默認(rèn)值 |
---|---|---|---|
multiPushBarrage | 初始化直播間時,填充數(shù)十條歷史彈幕數(shù)據(jù),組件已經(jīng)優(yōu)化,實(shí)現(xiàn)分布式上屏 | queueI[] | - |
sendBarrageEnterQueue | 將接收到的彈幕消息放入彈幕池, 第二個參數(shù)表示是否執(zhí)行彈幕過濾規(guī)則 | <queueI[], Boolean> | <-, true> |
sendBarrageBySelf | 自己發(fā)送的彈幕消息直接上屏 | queueI | - |
三個方法的代碼如下所示,都是將彈幕放入彈幕池,唯一的區(qū)別是自己發(fā)送的彈幕時,需要恢復(fù)輪詢機(jī)制。
// 自己發(fā)彈幕
sendBarrageBySelf(barrage) {
this.barrage.barrageEnterQueueSelf(barrage);
this.barrage.restart();
}
// 即時消息彈幕填充
sendBarrageEnterQueue(list, isFilter = true) {
this.barrage.barrageEnterQueue(list, isFilter);
}
// init直播間的時候,歷史彈幕填充
multiPushBarrage(list) {
this.sendBarrageEnterQueue(list, false);
}
復(fù)制代碼
實(shí)現(xiàn)監(jiān)聽滾到到底部,需要先來了解一下瀏覽器的scrollHegiht
、scrollTop
、clientHegiht
三個屬性。
- scrollHegiht: 文檔內(nèi)容實(shí)際高度,包括超出視窗的溢出部分。
- scrollTop: 滾動條滾動距離。
- clientHeight: 窗口可視范圍高度。
當(dāng) clientHeight
+ scrollTop
>= scrollHeight
時,表示已經(jīng)抵達(dá)內(nèi)容的底部了,可以加載更多內(nèi)容。
列表滾動時,由于當(dāng)前實(shí)際上屏的彈幕列表數(shù)量和內(nèi)容(內(nèi)容長度不一,有的 1 行,有的 2 行,有的 3 行)發(fā)生變化,需要先校準(zhǔn)容器的實(shí)際高度,方便后續(xù)做滾動到底部判斷。同時設(shè)置彈幕激活策略,靜止 n 秒后恢復(fù)滾動。
// 滾動容器會計算高度,并激活彈幕自動恢復(fù)
handleScrollBarrageContainer({ detail }) {
this.containerScrollHeight = detail.scrollHeight;
this.checkContainerClientHeight();
this.barrage.setActiveAndAutoRestart();
}
// 校準(zhǔn)彈幕容器高度
checkContainerClientHeight() {
if (!this.containerClientHieghtChecked) {
wx.createSelectorQuery()
.in(this as TrivialInstance)
.select('.live-barrage')
.fields(
{
size: true,
},
res => {
if (res) {
const { height = 0 } = res;
if (height === this.containerClientHeight) {
this.containerClientHieghtChecked = true;
}
this.containerClientHeight = height;
}
},
)
.exec();
}
}
復(fù)制代碼
列表滾動到底部,激活彈幕上屏邏輯。
// 滾動到底部,重新開啟刷新策略
handleScrollBottom() {
if (!this.barrageTouch) {
this.barrage.restart();
}
}
復(fù)制代碼
4.3.3 touch 事件監(jiān)聽
用戶觸摸屏幕動作開始時,暫停彈幕上屏邏輯。
barrageTouchStart() {
this.barrageTouch = true;
this.barrage.pause();
}
復(fù)制代碼
用戶觸摸動作結(jié)束時,判斷是否滾動到底部,如果是的話,恢復(fù)彈幕上屏邏輯
// 判斷彈幕是否到底
barrageTouchEnd() {
this.barrageTouch = false;
wx.createSelectorQuery()
.in(this as TrivialInstance)
.select('.live-barrage')
.fields(
{
scrollOffset: true,
},
({ scrollTop }) => {
if (
this.containerClientHeight + scrollTop + 5 >=
this.containerScrollHeight
) {
this.begainScroll = true;
this.barrage.restart();
}
},
)
.exec();
}
復(fù)制代碼
以上便是我對彈幕組件設(shè)計的理解,花了一個周末,時間略微倉促,寫作水平有限,在某些問題上解釋說明若有出入,還請批評指教!
相關(guān)案例查看更多
相關(guān)閱讀
- 云南小程序開發(fā)
- 國內(nèi)知名網(wǎng)站建設(shè)公司排名
- 昆明軟件定制公司
- 報廢車拆解管理系統(tǒng)
- 網(wǎng)站建設(shè)制作
- 河南小程序制作
- 云南小程序開發(fā)公司
- 云南小程序公司
- 前端
- 正規(guī)網(wǎng)站建設(shè)公司
- 汽車回收系統(tǒng)
- 汽車報廢軟件
- 昆明網(wǎng)絡(luò)公司
- 云南網(wǎng)站建設(shè)選
- 昆明軟件公司
- 文山小程序開發(fā)
- 云南網(wǎng)站建設(shè)哪家強(qiáng)
- 云南網(wǎng)絡(luò)營銷
- 云南省住房建設(shè)廳網(wǎng)站
- 小程序
- 網(wǎng)站建設(shè)費(fèi)用
- 汽車報廢回收軟件
- 網(wǎng)站建設(shè)特性
- 英文網(wǎng)站建設(shè)公司
- 云南小程序被騙
- 大理網(wǎng)站建設(shè)公司
- 開發(fā)框架
- 小程序開發(fā)公司
- uniapp開發(fā)小程序
- 云南網(wǎng)站建設(shè)公司地址