每日 30 秒 ⏱ 對海量數據進行切割

簡介

數據分割、分頁、異步操做、DOM優化javascript

把數組按指定大小進行分組,能夠用於分頁、數據切割、異步操做數據。css

// 該源碼來自於 https://30secondsofcode.org
const chunk = (arr, size) =>
  Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
    arr.slice(i * size, i * size + size)
  );
複製代碼

代碼分析

Array.prototype.from 從一個相似數組或者可迭代對象中建立一個新的數組實例,相似數組 這個詞可能不少人都不是很清楚,相似數組是 javascript 中一個神奇的對象,只要擁有 length 就算是相似數組了。html

最多見的相似數組是函數中的 arguments 有長度和 arguments[0] 的調用方法,可是卻沒有數組的 push 等函數方法。利用 Array.prototype.from 則能夠把 相似數組 轉化爲 數組。這個代碼的巧妙之處在於用了 { length: 3 } 這樣的對象來快速 生成數組,而 Array.prototype.from 的第二個參數會對剛生成的數組進行循環遍歷至關於調用了 mapjava

在循環遍歷新生成數組時,使用了 Array.prototype.slice 的方法來實現了分割數據的效果,這個方法至關經常使用同窗們能夠記住它。git

使用場景

假設如今有一個消息列表數組裏面有一萬條數據讓你渲染到頁面上,大部分人會直接遍歷數組並拼接成 dom 一股腦的渲染到頁面上,這樣帶來的後果是大量的 dom 操做會花費不少時間致使頁面卡頓,且上下滑動頁面時也會卡頓。github

咱們不妨換個角度來看這個問題不管是手機屏幕仍是電腦屏幕用戶可見的頁面數據條目可能就十幾條。那爲何咱們要一次性渲染一萬多條,並且用戶也不見得會把全部數據都查看了。數組

那咱們是否能夠只渲染十幾條數據,其餘數據等用戶滾動了某個高度時再進行下一個十幾條數據的渲染。在分頁操做中,chunk 就能夠幫助咱們快速的進行分頁。微信

樣式
.news > div {
    text-align: center;
    height: 50px;
}
複製代碼
結構
<!-- 用於標識到頁面頂部了 -->
<div class="news-header"></div>
<!-- 新聞數據 -->
<div class="news"></div>
<!-- 用於標識到頁面底部了 -->
<div class="news-footer"></div>
複製代碼
腳本
// 模擬生成 1萬條數據,這裏就利用了 Array.from 來快速生成數據
const originNews = Array.from(
    { length: 10000 },
    (v, k) => ({ content: `新聞${k}` })
)

// 須要插入的容器
const element = document.querySelector('.news')[0]

// 建立視圖監聽
const loadObserver = new IntersectionObserver((entries) => {
    // 若是不可見,就返回
    if (entries[0].intersectionRatio <= 0) {
        return;
    }

    // 判斷是否有上一頁和下一頁
    const hasPrePage = page != 0
    const hasNextPage = page != news.length - 1

    const now = news[page]
    const pre = hasPrePage ? news[page - 1] : []
    const next = hasNextPage ? news[page + 1] : []

    // 傳遞錨點的座標 和 當前頁面顯示的數據
    render(pre.length, [ ...pre, ...now, ...next ])
    
    // 判斷是否須要翻頁,且防止數組越界
    page = entries[0].target.className == 'news-footer' || page === 0
        ? (hasNextPage ? page + 1 : page)
        : (hasPrePage ? page - 1 : page)
}, { threshold: [1] })

// 設置監聽
loadObserver.observe(document.querySelector('.news-header'))
loadObserver.observe(document.querySelector('.news-footer'))

// 根據當前頁面高度和新聞高度算出每一頁能夠放幾條數據
let pageNum = Math.ceil(document.body.clientHeight / 50)
let page = 0 // 當前顯示了第幾頁的數據
let news = chunk(originNews, pageNum) // 分頁後的數據

// 渲染新聞 並 跳轉到錨點
function render(last, data) {
    element.innerHTML = ''

    data.forEach((i, v) => element.innerHTML += v == last
        ? `<div id="news-herf">${i.content}</div>`
        : `<div>${i.content}</div>`
    )

    window.location.href = "#news-herf"
}

複製代碼

一塊兒成長

在困惑的城市裏總少不了並肩同行的 夥伴 讓咱們一塊兒成長。dom

  • 若是您想讓更多人看到文章能夠點個 點贊
  • 若是您想激勵小二能夠到 Github 給個 小星星
  • 若是您想與小二更多交流添加微信 m353839115

微信公衆號

本文原稿來自 PushMeTop異步

相關文章
相關標籤/搜索