亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

微信小程序?qū)崿F(xiàn)可以截斷的瀑布流組件的示例代碼

 更新時間:2022年01月23日 09:30:28   作者:豌豆公主技術(shù)部  
本文主要介紹了微信小程序?qū)崿F(xiàn)可以截斷的瀑布流組件

瀑布流是一種常見的布局方式,實現(xiàn)的方式有許多,比如直接分兩列,然后控制在左右兩列加入元素;還有一種方式就是通過絕對定位的方式來放置兩邊。本文所要介紹的瀑布流不同于常規(guī)的,因為瀑布流中間可能會被截斷:

對于上面的布局,如果強制分成兩列去做布局就不太適合了,因此我采用了絕對定位的方式來進行布局,由于瀑布流中的元素高度都不是固定的,因此我得想辦法獲取到每個元素的高度,然后判定元素到底是放一整行,還是左側(cè),亦或者右側(cè)。

首先我們來看下模板部分的實現(xiàn):

<view class="container" style="height:{{height}}px;">
?? ?<view wx:for="{{list}}" wx:key="index" style="{{item.style}}" class="wrapper">
?? ??? ?<abstract item="{{item}}"/>
?? ?</view>
</view>
<view wx:if="{{tmp}}" class="computed-zone">
?? ?<view class="wrapper">
?? ??? ?<abstract item="{{tmp}}"/>
?? ?</view>
</view>

模板比較簡單,一個 container 容器,然后循環(huán)數(shù)組,平級渲染出一堆 wrapper 容器。

wrapper 容器是一個絕對定位的包裹元素,wrapper 容器里面需要放置需要實際渲染的組件,為了靈活性更高一點,我把這個渲染組件設(shè)置成了虛擬節(jié)點,在使用組件的時候可以指定實際渲染的自定義組件。

因為 wrapper 元素是絕對定位的,因此我們需要手動去維護整個 container 容器的高度。

這里有個問題是,我們怎么獲取里面元素的高度呢?模板中的 computed-zone 就是來解決這個問題的,在將元素放置到數(shù)組之前,我們先把元素在 computed-zone 中進行渲染,然后通過 WXML api 來獲取其中元素的實際渲染尺寸,這樣我們就可以知道這個元素實際渲染的寬高度了。

有了每個元素的渲染尺寸信息之后,我們需要確認元素到底是占滿整行,還是占半邊:

  • 如果元素的渲染寬度跟容器一樣,那么就可以判斷這個元素沾滿一整行,需要將包裹容器 wrapper 設(shè)置為一整行的寬度;
  • 如果不滿足1條件,那么就需要基于左右元素的總高度,將 wrapper 放在左側(cè)或者右側(cè)。

分析下來,需要稍微寫點兒邏輯的就是對 wrapper 計算偏移量,處理到底放左邊還是放右邊,亦或者占滿整行,核心的代碼實現(xiàn)如下:

{
?? ?// 將 setData Promise 化,方便使用
?? ?$setData(data) {
?? ??? ?return new Promise(resolve => {
?? ??? ??? ?this.setData(data, () => {
?? ??? ??? ??? ?resolve();
?? ??? ??? ?});
?? ??? ?});
?? ?},
?? ?// 獲取元素的渲染尺寸
?? ?getRect(item) {
?? ??? ?return this.$setData({
?? ??? ??? ?tmp: item,
?? ??? ?}).then(() => {
?? ??? ??? ?return new Promise((resolve, reject) => {
?? ??? ??? ??? ?const query = this.createSelectorQuery(); // 注意要使用 this,不要再使用 wx 前綴了
?? ??? ??? ??? ?query.select('.computed-zone .wrapper').boundingClientRect();
?? ??? ??? ??? ?query.exec(ret => {
?? ??? ??? ??? ??? ?if (ret[0]) {
?? ??? ??? ??? ??? ??? ?resolve(ret[0]);
?? ??? ??? ??? ??? ?} else {
?? ??? ??? ??? ??? ??? ?reject('not found dom!');
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?});
?? ??? ??? ?});
?? ??? ?});
?? ?},
?? ?// 添加元素,內(nèi)部使用
?? ?addItem(item) {
?? ??? ?let tick = this.tick;
?? ??? ?return this.getRect(item).then(rect => {
?? ??? ??? ?if (tick !== this.tick) {
?? ??? ??? ??? ?return Promise.reject('tick');
?? ??? ??? ?}
?? ??? ??? ?const { margin } = this.data;
?? ??? ??? ?let { height, width } = rect;
?? ??? ??? ?const windowWidth = this.sysInfo.windowWidth;
?? ??? ??? ?let [ leftTotal, rightTotal ] = this.height; // leftTotal 左側(cè)欄高度,rightTotal 右側(cè)欄高度,
?? ??? ??? ?let marginPx = this.sysInfo.getPx(margin);
?? ??? ??? ?let style = '';

?? ??? ??? ?if (Math.abs(width - windowWidth) < 3) {
?? ??? ??? ??? ?// 占滿屏幕寬度
?? ??? ??? ??? ?style = `left:0;top:${ Math.max(leftTotal, rightTotal) }px;width:100%;`;
?? ??? ??? ??? ?leftTotal = rightTotal = Math.max(leftTotal + height, rightTotal + height);
?? ??? ??? ?} else if (rightTotal < leftTotal) {
?? ??? ??? ??? ?// 放入右邊
?? ??? ??? ??? ?style = `right:${ marginPx }px;top:${ rightTotal }px;`;
?? ??? ??? ??? ?rightTotal += height;
?? ??? ??? ?} else {
?? ??? ??? ??? ?// 放入左邊
?? ??? ??? ??? ?style = `left:${ marginPx }px;top:${ leftTotal }px;`;
?? ??? ??? ??? ?leftTotal += height;
?? ??? ??? ?}

?? ??? ??? ?const { list = [] } = this.data;
?? ??? ??? ?const targetKey = `list[${list.length}]`; // 利用直接操作數(shù)組下標(biāo)的方式來觸發(fā)數(shù)組修改,性能有很大提升
?? ??? ??? ?this.height = [leftTotal, rightTotal]; // 記錄最新的左右側(cè)高度
?? ??? ??? ?return this.$setData({
?? ??? ??? ??? ?[targetKey]: {
?? ??? ??? ??? ??? ?data: item,
?? ??? ??? ??? ??? ?style,
?? ??? ??? ??? ?},
?? ??? ??? ??? ?height: Math.max(leftTotal, rightTotal),
?? ??? ??? ?});
?? ??? ?});
?? ?},
?? ?// 實際添加元素使用,自建Promise隊列,保證順序一致
?? ?add(item) {
?? ??? ?let pending = this.pending || Promise.resolve();
?? ??? ?return this.pending = pending.then(() => {
?? ??? ??? ?return this.addItem(item);
?? ??? ?}).catch(err => {
?? ??? ??? ?console.error(err);
?? ??? ??? ?this.pending = null;
?? ??? ??? ?throw err;
?? ??? ?});
?? ?},
?? ?clear() {
?? ??? ?this.tick = tick++;
?? ??? ?this.height = [0, 0];
?? ??? ?this.pending = null;
?? ??? ?this.setData({
?? ??? ??? ?list: [],
?? ??? ??? ?height: 0,
?? ??? ?});
?? ?},
}

在使用該組件的時候我們就不能直接通過賦值數(shù)組的方式來渲染元素了,而是得通過組件實例方法add(item) 的方式,因為我實現(xiàn)了隊列,因此可以直接循環(huán) add 就行。如果關(guān)心狀態(tài)就判斷最后一個元素的 add 操作是否完成即可。

通過這種方式來實現(xiàn)的瀑布流靈活性相對較高,但是性能消耗也是不低的,需要挨個獲取元素的實際渲染尺寸,如果要支持窗口的resize的話,那消耗是恐怖。

對于需要看代碼細節(jié)的同學(xué),我將實際的demo放到了 Github 微信代碼片段,有需要的同學(xué)可以試一試。

基于上面的模型,其實也可以優(yōu)化成只渲染可視區(qū)范圍內(nèi)的元素,可以大大提升瀑布流的性能 

到此這篇關(guān)于微信小程序?qū)崿F(xiàn)可以截斷的瀑布流組件的示例代碼的文章就介紹到這了,更多相關(guān)小程序截斷的瀑布流組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript實現(xiàn)alert彈框效果

    JavaScript實現(xiàn)alert彈框效果

    這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)alert彈框效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Javascript中Null和undefined的簡單理解

    Javascript中Null和undefined的簡單理解

    在JavaScript中存在這樣兩種原始類型:Null與Undefined,這兩種類型常常會使JavaScript的開發(fā)人員產(chǎn)生疑惑,在什么時候是Null,什么時候又是Undefined,下面這篇文章主要給大家介紹了關(guān)于Javascript中Null和undefined的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • 實例解析Array和String方法

    實例解析Array和String方法

    本文主要對Array和String方法進行總結(jié),每一部分總結(jié)后有實例代碼,代碼中黃色框方法不改變原數(shù)組。PS:所有實例結(jié)果均一一運行所得。具有很好的參考價值,需要的朋友一起來看下吧
    2016-12-12
  • BootStrap實現(xiàn)文件上傳并帶有進度條效果

    BootStrap實現(xiàn)文件上傳并帶有進度條效果

    這篇文章主要介紹了BootStrap實現(xiàn)文件上傳并帶有進度條效果,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-09-09
  • JavaScript類的寫法

    JavaScript類的寫法

    這篇文章主要為大家詳細介紹了JavaScript類的寫法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • js實現(xiàn)簡易拖拽的示例

    js實現(xiàn)簡易拖拽的示例

    這篇文章主要介紹了js實現(xiàn)簡易拖拽的示例,幫助大家更好的理解和學(xué)習(xí)JavaScript,感興趣的朋友可以了解下
    2020-10-10
  • javascript 尚未實現(xiàn)錯誤解決辦法

    javascript 尚未實現(xiàn)錯誤解決辦法

    打開頁面的時候,F(xiàn)F下一切正常,但是當(dāng)我用IE6測試的時候,JS總執(zhí)行不下去了,提示“尚未實現(xiàn)”,無論怎么搞就搞不定。
    2008-11-11
  • JavaScript實現(xiàn)區(qū)塊鏈

    JavaScript實現(xiàn)區(qū)塊鏈

    很多朋友都聽說過比特幣和以太幣這樣的加密貨幣,但是只有極少數(shù)人懂得隱藏在它們背后的技術(shù),接下來通過本文給大家介紹用JavaScript來創(chuàng)建一個簡單的區(qū)塊鏈來演示它們的內(nèi)部究竟是如何工作的,感興趣的朋友一起看看吧
    2018-03-03
  • 細說webpack源碼之compile流程-rules參數(shù)處理技巧(2)

    細說webpack源碼之compile流程-rules參數(shù)處理技巧(2)

    這篇文章主要介紹了webpack源碼之compile流程-rules參數(shù)處理技巧的相關(guān)知識,需要的朋友參考下吧
    2017-12-12
  • JavaScript三種綁定事件方式及相互之間的區(qū)別分析

    JavaScript三種綁定事件方式及相互之間的區(qū)別分析

    這篇文章主要介紹了JavaScript三種綁定事件方式及相互之間的區(qū)別,結(jié)合具體實例形式分析了javascript事件綁定方式的基本實現(xiàn)方法與相互之間的區(qū)別,需要的朋友可以參考下
    2017-01-01

最新評論