由於要適配iOS前端,因此在想最簡實現一個靜態數據的抽獎滾動欄,研究時直接用了當前運行的ReactJS框架實現,因而昨天先打了個草稿。經測試在iPhone6S Plus A1699 Version 12.1.2上顯示正常。前端
import React from 'react' class ScrollMessagePage { componentDidMount() { //消息關鍵字數據 const loanUserList = ['趙', '錢', '孫', '宋', '王', '徐', '丘', '駱', '高', '夏', '蔡', '田', '樊', '胡', '陳', '霍', '潘', '萬', '李', '洪', '莫', '王'] const loanMoneyList = [10, 12, 8, 5, 8, 7, 6, 23, 18, 10, 2, 1] const loanSexList = ['先生', '先生', '先生', '女士', '女士'] function getText() { const randomSex = loanSexList[parseInt(Math.random() * loanSexList.length)] const randomName = loanUserList[parseInt(Math.random() * loanUserList.length)] const randomMoney = loanMoneyList[parseInt(Math.random() * loanMoneyList.length)] return randomName + randomSex + '得到' + randomMoney + '元紅包' } let messageList = [] for (let i = 0; i < 3; i++) { messageList.push(getText()) } let box = document.getElementById('scroll-message') box.style.height = '30px' box.style.overflow = 'hidden' function createElement(text) { let Text = document.createElement('div') Text.style.height = '30px' Text.style.transition = 'margin-top 1s' Text.innerText = text box.appendChild(Text) } messageList.map(text => { createElement(text) }) this.timer = setInterval(() => { createElement(getText()) box.childNodes[1].style.marginTop = '-30px' box.removeChild(box.childNodes[0]) }, 3000) } componentWillUnMount() { clearInterval(this.timer) } render() { return ( <div className="match"> <div id="scroll-message"/> </div> ) } } export default ScrollMessagePage
通過今天的測試發現,在第一次加載計時器的時候滾動條會將滾動數據第二條數據快速跳過,形成很差的用戶體驗,另外頻繁的操做DOM也會形成性能損耗,因而使用了文檔碎片對滾動條進行優化react
let box = document.getElementById('scroll-message') let fragement = document.createDocumentFragment('div') let message = document.createElement('div') message.style.height = '30px' message.style.overflow = 'hidden' fragement.appendChild(message) function createElement(text, style, ele = message) { let Text = document.createElement('div') Text.style.height = '30px' Text.style.lineHeight = '30px' Text.style.transition = 'margin-top 1s' style && Object.keys(style).map(key => Text.style[key] = style[key]) Text.innerText = text ele.appendChild(Text) } let messageList = [] for (let i = 0; i < 2; i++) { messageList.push(getText()) } messageList.map((text, index) => createElement(text, index===0?{marginTop:'-30px'}:null)) this.timer = setInterval(() => { createElement(getText()) message.childNodes[1].style.marginTop = '-30px' message.removeChild(message.childNodes[0]) }, 3000) box.appendChild(fragement)
【如何修復數據跳過BUG】這次更新修復了滾動條在第一次計時器運行時跳過第二條數據的問題,發生問題的緣由是由於初始化公告欄數據的時候並未添加marginTop,在計時器執行以後第二條數據本來會替換第一條數據的位置,然而由於第一條數據被刪除因此跑到第一條數據位置上面,我經過直接將第二條數據初始化到第一條數據的位置解決了該問題。app
【處理性能損耗】使用計時器頻繁對dom進行操做,會使整個頁面頻繁進行DOM渲染,解決性能損耗的問題我參考 createDocumentFragment();方法實現,將該公告欄DOM插入到該方法建立的文檔碎片,將子元素插入到文檔片斷時不會引發頁面迴流。框架
小結dom
初次向你們分享個人想法,有更好的實現方法能夠評論留言,關於性能損耗的問題我認識有些不足,請你們多多指教。