ホームページ > 記事 > ウェブフロントエンド > JSやCSSを使ってウォーターフォールフローレイアウトを実装する方法、いくつかの解決策を紹介
この記事では、ウォーターフォール フローのレイアウトを説明し、信頼できる 3 つの JS ソリューションと信頼できない CSS ソリューションを 3 つ紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。
実用性の精神で、今日は ウォーターフォール フロー レイアウト (昨日、弟に作り方を尋ねられました。長い間探しても見つかりませんでした。どうやらイントラネット ) に書かれていたことが分かりました。
デモ アドレス: http://www.lilnong.top/static/html/waterfall.html
たとえば、huapetal.com と Mogujie (以下に写真を掲載しました) では、これらの Web サイトはコンテンツを表示するときにウォーターフォール フロー レイアウトを使用します。
デザインドラフトを表示するページも作成したいと考えています (固定幅、可変高さ)。ウォーターフォール フローは優れたソリューションです。
ウォーターフォール フロー レイアウトの核心はグリッド レイアウトに基づいており、各行に含まれる項目リストの高さはランダムです (高さは独自のコンテンツに応じて動的に変化します)。リストはスタックに配置されます。最も重要なことは、スタック間に不要なスペースがないことです。上の写真を見て、私たちが話している滝の流れのレイアウトがどのようなものかを見てみましょう。
Mogujie | 花ペットネット | JD | VV | |
---|---|---|---|---|
サブチャネル | 絶対 |
、左から右、上から下へ。
inline | float | bootstrap-grid | ||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
列 | フレックス | |
---|---|---|
に設定するだけで済みます。
デフォルトは水平配置ですが、垂直配置に変更できます。配置と折り返しを許可し、コンテンツを固定の高さで折り返します。 絶対チャネル高さ計算スキーム
残りのチャンネル | 高さチャンネルの計算 | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
# 这里的方案就靠谱起来了,可以满足我们使用要求。 我们来回忆一下我们的需求:展示一些内容,内容有特性定宽,不定高。不定高一般是因为内容长度或者高度不一致导致的,常见内容又分为两种文字和图片。
获取图片高度// 用于获取图片的真实高度 naturalHeight: 1180 // 用于获取图片的真实宽度 naturalWidth: 1200 //用户获取图片当前的渲染高度(会受 css 影响) height: 98 //用户获取图片当前的渲染宽度(会受 css 影响) width: 100 // 可返回浏览器是否已完成对图像的加载。如果加载完成,则返回 true,否则返回 fasle。 complete 属性 // 可以监听到图片加载完成的动作 onload 基于上面的内容,那我们可以先判断 complete 属性, function getImageSize(img){ if(img.complete){ return Promise.resolve({ naturalHeight: img.naturalHeight, naturalWidth: img.naturalWidth, height: img.height, width: img.width, }) }else{ return new Promise((resolve, reject)=>{ img.addEventListener('load', ()=>{ resolve({ naturalHeight: img.naturalHeight, naturalWidth: img.naturalWidth, height: img.height, width: img.width, }) }) }) } } /* // 测试用例 el = document.createElement('img'); el.src = 'http://cors-www.lilnong.top/favicon.ico?'+Math.random() getImageSize(el).then(console.log).catch(console.error) setTimeout(()=>getImageSize(el).then(console.log).catch(console.error), 1000) */ absolute 计算高度方案因为普通的布局已经无法满足我们的需求,所以我们可以考虑通过 核心操作就是维护每个元素的 left、top,然后使用 left 和 top 去渲染到正确位置。 getListPosition(){ // 视口宽度 / 每列宽度 得出划分为几列 let col = this.screenWidth / this.itemWidth >> 0; var arr = []; for(var i = 0; i < col; i++) arr.push({ list: [], height: 0, }) // 遍历所有元素 this.listInfo.forEach((item,idx)=>{ // 找到最低的一列 var colIndex = 0; for(var i = 1; i < col; i++){ if(arr[colIndex].height > arr[i].height){ // colItem = arr[i] colIndex = i } } // 修改元素的信息 // 所属列 item.line = colIndex; // 计算之后的 top 距离 item.top = arr[colIndex].height+ 'px'; // 计算之后的 left 距离 item.left = colIndex * (this.itemWidth + 10) + 'px' // 累加操作 arr[colIndex].list.push(item); arr[colIndex].height += item.height + 10; }) return arr }, 通过计算,我们可以到,瀑布流布局下每个元素的位置,通过绝对定位就可以实现。 根据下标,来渲染到不同的通道 idx % 4因为上个方案用到了绝对定位,那么有没有不用绝对定位的方案呢?回到我们的问题点上 定宽,不定高,那我们完全可以通过分开渲染放弃 absolute 来实现。 jsGroupList(){ return this.list.reduce((s,n,idx)=>{ // 根据下标,直接分配所属列 s[idx % 4].push({idx: idx, item: n}) return s }, [[],[],[],[],]) }, 看开头是实现类似的功能的,但是有一个弊端(快来评论区回复呀)。 通过高度计算,然后分通道,避免 absolute因为上一个方案是按下标分类的,其实瀑布流是按高度分类的,所以我们分类条件换成最低的列。 jsGroupHeightList(){ var list = [ {height: 0, list: []},{height: 0, list: []}, {height: 0, list: []},{height: 0, list: []}, ] // 遍历每个元素 for(var i = 0; i < this.list.length; i++){ // 当元素有大小的时候在进行操作。 if(!this.listInfo[i].height) return list; // 默认第一个通道是最小高度列 var minHeightItem = list[0]; // 计算最小高度列 list.forEach(v=>{ if(v.height < minHeightItem.height) minHeightItem = v }) // 把新的元素高度累加到列中。 minHeightItem.height += this.listInfo[i].height // 把新的元素push到列中 minHeightItem.list.push({idx: i, item: this.list[i]}) } return list; }, 总结好了,到这里我能想到的方案就都介绍了。你还有什么方案吗?咱们可以在评论区讨论一下可行性。接下来就是我们的方案总结了。
更多编程相关知识,请访问:编程入门!! |
以上がJSやCSSを使ってウォーターフォールフローレイアウトを実装する方法、いくつかの解決策を紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。