原生 JS 實現乙個瀑布流外掛程式

2021-09-14 03:19:34 字數 3306 閱讀 3256

瀑布流布局中的有乙個核心特點 —— 等寬不定等高,瀑布流布局在國內網**都有一定規模的使用,比如pinterest、花瓣網等等。那麼接下來就基於這個特點開始瀑布流探索之旅。

首先我們定義好乙個有 20 張的容器,

由於未知的 css 知識點,**最長的妹子把下面的空間都占用掉了。。。

接著正文,假如如上圖,每排有 5 列,那第 6 張應該出現前 5 張哪張的下面呢?當然是絕對定位到前 5 張高度最小的下方。

那第 7 張呢?這時候把第 6 張和在它上面的當作是乙個整體後,思路和上述是一致的。**實現如下:

wate***ll.prototype.init = function () 

let pointer = this.getminpointer(perlist) // 求出當前最小高度的陣列下標

for (let i = pernum; i < imglist.length; i++) px`

imglist[i].style.top = `$px`

perlist[pointer] = perlist[pointer] + imglist[i].offsetheight // 陣列最小的值加上相應的高度

pointer = this.getminpointer(perlist)

}}

細心的朋友也許發現了**中獲取的高度用到了offsetheight這個屬性,這個屬性的高度之和等於高度 + 內邊距 + 邊框,正因為此,我們用了 padding 而不是 margin 來設定與之間的距離。此外除了offsetheight屬性,此外還要理解offsetheightclientheightoffsettopscrolltop等屬性的區別,才能比較好的理解這個專案。css **簡單如下:

.wate***ll-box
至此完成了瀑布流的基本布局,效果圖如下:

實現了初始化函式 init 以後,下一步就要實現對 scroll 滾動事件進行監聽,從而實現當滾到父節點的底部有源源不斷的被載入出來的效果。這時候要考慮乙個點,是滾動到什麼位置時觸發載入函式呢?這個因人而異,我的做法是當滿足父容器高度 + 滾動距離 > 最後一張的 offsettop這個條件,即橙色線條 + 紫色線條 > 藍色線條時觸發載入函式,**如下:

因為父節點可能自定義節點,所以提供了對監聽 scroll 函式的封裝,**如下:

proto.bind = function () 

const util = ,

}

resize 事件的監聽與 scroll 事件監聽大同小異,當觸發了 resize 函式,呼叫 init 函式進行重置就行。

既然以開發外掛程式為目標,不能僅僅滿足於功能的實現,還要留出相應的操作空間給開發者自行處理。聯想到業務場景中瀑布流中下拉載入的一般都來自 ajax 非同步獲取,那麼載入的資料必然不能寫死在庫里,期望能實現如下呼叫(此處借鑑了 wate***ll 的使用方式),

const wate***ll = new wate***ll()

wate***ll.on("load", function () )

觀察呼叫方式,不難聯想到使用發布/訂閱模式來實現它,關於發布/訂閱模式,之前在 node.js 非同步異聞錄 有介紹它。其核心思想即通過訂閱函式將函式新增到快取中,然後通過發布函式實現非同步呼叫,下面給出其**實現:

function eventemitter() 

}eventemitter.prototype.on = function (eventname, func)

this.sub[eventname].push(func) // 新增事件***

}eventemitter.prototype.emit = function (eventname)

}

接著,要讓 wate***ll 能使用發布/訂閱模式,只需讓 wate***ll 繼承 eventemitter 函式,**實現如下:

function wate***ll(options = {}) 

wate***ll.prototype = object.create(eventemitter.prototype)

wate***ll.prototype.constructor = wate***ll

繼承方式的寫法吸收了基於建構函式繼承和基於原型鏈繼承兩種寫法的優點,以及使用object.create隔離了子類和父類,關於繼承更多方面的細節,可以另寫一篇文章了,此處點到為止。

為了防止 scroll 事件觸發多次載入,可以考慮用函式防抖與節流實現。在基於發布-訂閱模式的基礎上,定義了個 isloading 引數表示是否在載入中,並根據其布林值決定是否載入,**如下:

let isloading = false

const scroll = function ()

}proto.done = function () )

this.emit('done')

}

這時候需要在呼叫的地方加上wate***ll.done, 從而告知當前已經載入完畢,**如下:

const wate***ll = new wate***ll({})

wate***ll.on("load", function () )

專案位址

此外掛程式在 react 專案中的運用

專案簡陋,不足之處在所難免,歡迎留下你們寶貴的意見。

js原生實現瀑布流

1.確定瀏覽器顯示區域內,一行放多少列盒子 寬度一致,高度由內容撐開 1.1 獲取頁面寬度 1.2 獲取盒子寬度 1.3 顯示的列數 頁面寬度 盒子寬度 2.確定列數之後,先排列第一行 2.1 顯示的列數 頁面寬度 盒子寬度 間隙 2.2for迴圈裡判斷 當i 盒子的索引 小於column 列數 的...

瀑布布局流 原生js

首先html和css 然後單單左浮動是不會 插空 插入的,這裡就是我們的重點啦。首先 都是要絕對定位的。確定好乙個頁面有多少列,每插入一張就計算每一列的高度,取最短的那列插入,計算該插入的top和left再賦值,絕對定位定在那裡,就ok啦 function wate ll parent,pin el...

原生js寫瀑布流

準備用自學的jquery寫的,但是不熟悉api,忘得乾乾淨淨了,然後我覺得我直接用js寫比用jquery還要簡單一點 這是html布局 js 1.獲取視口的寬度,獲取每個的寬度 2.遍歷迴圈每個 3.設定top和left top 第一行設定為0,第二行開始 最小高度 left i imgw 必須等所...