JSを使用したウォーターフォールフロープラグインの実装方法
この記事では、ネイティブ JS ウォーターフォール プラグインの詳細な分析とコード関連の説明を提供します。興味のある読者は参照してください。
滝の流れのレイアウトの写真には、同じ幅と可変の高さという核となる機能があり、Pinterest や Huaban.com などの国内 Web サイトで一定の規模で使用されています。そして、この特徴に基づいて、滝の流れ探索の旅を開始します。
基本的な関数の実装
まず、20 枚の画像を含むコンテナを定義します
<body> <style> #waterfall { position: relative; } .waterfall-box { float: left; width: 200px; } </style> </body> <p id="waterfall"> <img src="images/1.png" class="waterfall-box"> <img src="images/2.png" class="waterfall-box"> <img src="images/3.png" class="waterfall-box"> <img src="images/4.png" class="waterfall-box"> <img src="images/5.png" class="waterfall-box"> <img src="images/6.png" class="waterfall-box"> ... </p> 由于未知的 css 知识点,丝袜最长的妹子把下面的空间都占用掉了。。。 接着正文,假如如上图,每排有 5 列,那第 6 张图片应该出现前 5 张图片哪张的下面呢?当然是绝对定位到前 5 张图片高度最小的图片下方。 那第 7 张图片呢?这时候把第 6 张图片和在它上面的图片当作是一个整体后,思路和上述是一致的。代码实现如下: Waterfall.prototype.init = function () { ... const perNum = this.getPerNum() // 获取每排图片数 const perList = [] // 存储第一列的各图片的高度 for (let i = 0; i < perNum; i++) { perList.push(imgList[i].offsetHeight) } let pointer = this.getMinPointer(perList) // 求出当前最小高度的数组下标 for (let i = perNum; i < imgList.length; i++) { imgList[i].style.position = 'absolute' // 核心语句 imgList[i].style.left = `${imgList[pointer].offsetLeft}px` imgList[i].style.top = `${perList[pointer]}px` perList[pointer] = perList[pointer] + imgList[i].offsetHeight // 数组最小的值加上相应图片的高度 pointer = this.getMinPointer(perList) } }
注意深い人は、コード内で画像の高さを取得するために offsetHeight
属性が使用されていることを発見したかもしれません。この属性の高さの合計は、画像の高さ + パディング + ボーダー
に等しいため、マージンの代わりにパディングを使用して画像間の距離を設定します。 offsetHeight
属性に加えて、offsetHeight
、clientHeight
、offsetTop
、および scrollTop についても理解する必要があります。 </code > 属性の違いを比較することによってのみ、このプロジェクトをより深く理解することができます。 CSS コードは次のように単純です: <code>offsetHeight
这个属性,这个属性的高度之和等于图片高度 + 内边距 + 边框
,正因为此,我们用了 padding 而不是 margin 来设置图片与图片之间的距离。此外除了offsetHeight
属性,此外还要理解 offsetHeight
、clientHeight
、offsetTop
、scrollTop
等属性的区别,才能比较好的理解这个项目。css 代码简单如下:
.waterfall-box { float: left; width: 200px; padding-left: 10px; padding-bottom: 10px; }
scroll、resize 事件监听的实现
实现了初始化函数 init 以后,下一步就要实现对 scroll 滚动事件进行监听,从而实现当滚到父节点的底部有源源不断的图片被加载出来的效果。这时候要考虑一个点,是滚动到什么位置时触发加载函数呢?这个因人而异,我的做法是当满足 父容器高度 + 滚动距离 > 最后一张图片的 offsetTop
这个条件,即橙色线条 + 紫色线条 > 蓝色线条时触发加载函数,代码如下:
window.onscroll = function() { // ... if (scrollPX + bsHeight > imgList[imgList.length - 1].offsetTop) {// 浏览器高度 + 滚动距离 > 最后一张图片的 offsetTop const fragment = document.createDocumentFragment() for(let i = 0; i < 20; i++) { const img = document.createElement('img') img.setAttribute('src', `images/${i+1}.png`) img.setAttribute('class', 'waterfall-box') fragment.appendChild(img) } $waterfall.appendChild(fragment) } }
因为父节点可能自定义节点,所以提供了对监听 scroll 函数的封装,代码如下:
proto.bind = function () { const bindScrollElem = document.getElementById(this.opts.scrollElem) util.addEventListener(bindScrollElem || window, 'scroll', scroll.bind(this)) } const util = { addEventListener: function (elem, evName, func) { elem.addEventListener(evName, func, false) }, }
resize 事件的监听与 scroll 事件监听大同小异,当触发了 resize 函数,调用 init 函数进行重置就行。
使用发布-订阅模式和继承实现监听绑定
既然以开发插件为目标,不能仅仅满足于功能的实现,还要留出相应的操作空间给开发者自行处理。联想到业务场景中瀑布流中下拉加载的图片一般都来自 Ajax 异步获取,那么加载的数据必然不能写死在库里,期望能实现如下调用(此处借鉴了 waterfall 的使用方式),
const waterfall = new Waterfall({options}) waterfall.on("load", function () { // 此处进行 ajax 同步/异步添加图片 })
观察调用方式,不难联想到使用发布/订阅模式来实现它,关于发布/订阅模式,之前在 Node.js 异步异闻录 有介绍它。其核心思想即通过订阅函数将函数添加到缓存中,然后通过发布函数实现异步调用,下面给出其代码实现:
function eventEmitter() { this.sub = {} } eventEmitter.prototype.on = function (eventName, func) { // 订阅函数 if (!this.sub[eventName]) { this.sub[eventName] = [] } this.sub[eventName].push(func) // 添加事件监听器 } eventEmitter.prototype.emit = function (eventName) { // 发布函数 const argsList = Array.prototype.slice.call(arguments, 1) for (let i = 0, length = this.sub[eventName].length; i < length; i++) { this.sub[eventName][i].apply(this, argsList) // 调用事件监听器 } }
接着,要让 Waterfall 能使用发布/订阅模式,只需让 Waterfall 继承 eventEmitter 函数,代码实现如下:
function Waterfall(options = {}) { eventEmitter.call(this) this.init(options) // 这个 this 是 new 的时候,绑上去的 } Waterfall.prototype = Object.create(eventEmitter.prototype) Waterfall.prototype.constructor = Waterfall
继承方式的写法吸收了基于构造函数继承和基于原型链继承两种写法的优点,以及使用 Object.create
隔离了子类和父类,关于继承更多方面的细节,可以另写一篇文章了,此处点到为止。
小优化
为了防止 scroll 事件触发多次加载图片,可以考虑用函数防抖与节流实现。在基于发布-订阅模式的基础上,定义了个 isLoading 参数表示是否在加载中,并根据其布尔值决定是否加载,代码如下:
let isLoading = false const scroll = function () { if (isLoading) return false // 避免一次触发事件多次 if (scrollPX + bsHeight > imgList[imgList.length - 1].offsetTop) { // 浏览器高度 + 滚动距离 > 最后一张图片的 offsetTop isLoading = true this.emit('load') } } proto.done = function () { this.on('done', function () { isLoading = false ... }) this.emit('done') }
这时候需要在调用的地方加上 waterfall.done
const waterfall = new Waterfall({}) waterfall.on("load", function () { // 异步/同步加载图片 waterfall.done() })
初期化関数 init を実装した後の次のステップは、スクロール イベントの監視を実装することです。スクロールに到達すると、親ノードの下部に画像の安定したストリームが読み込まれる効果があります。このとき考慮すべき点は、スクロール時にローディング関数がどの位置でトリガーされるかということです。これは人によって異なります。私のアプローチは、親コンテナの高さ + 最後の画像のオフセット上部
の条件が満たされたときに読み込みをトリガーすることです。つまり、オレンジ色の線 + 紫色の線 > 青です。 line 関数のコードは次のとおりです。
親ノードがノードをカスタマイズする可能性があるため、スクロール監視関数のカプセル化が提供されます。 コードは次のとおりです。 rrreee サイズ変更イベント監視はスクロール イベント監視と似ています。サイズ変更関数がトリガーされたら、init を呼び出して関数をリセットするだけです。
パブリッシュ・サブスクライブ・モデルと継承を使用してリスニング・バインディングを実装します目的はプラグインの開発であるため、機能の実現に満足するだけではなく、開発者が独自に処理できる対応する操作スペースも残しておきます。 。ビジネス シナリオでウォーターフォール フローで画像をドロップダウンで読み込むことを考えると、通常、画像は Ajax を通じて非同期で取得されるため、読み込まれたデータはライブラリにハードコーディングされてはなりません。次の呼び出しを実装できることが期待されます。ウォーターフォールの使用から教訓を得ます)、
rrreee呼び出しメソッドを観察すると、パブリッシュ/サブスクライブ モデルを使用して実装することを考えるのは難しくありません。パブリッシュ/サブスクライブ モデルについては、以前に Node で導入されました。 .js の非同期非同期レコード。中心となるアイデアは、サブスクリプション関数を通じてキャッシュに関数を追加し、パブリッシュ関数を通じて非同期呼び出しを実装することです。コードの実装は次のとおりです。 rrreee 次に、ウォーターフォールがパブリッシュ/サブスクライブ モードを使用できるようにします。ウォーターフォールにeventEmitter Functionを継承させるだけで、コードは次のように実装されます:
rrreee継承メソッドは、コンストラクター継承とプロトタイプチェーン継承に基づく 2 つの記述方法の利点を吸収し、Object を使用します。分離のための .create
サブクラスと親クラスができたので、継承の詳細については別の記事を書くことができるので、ここで終了します。 🎜🎜🎜小規模な最適化🎜🎜🎜 スクロール イベントによって画像の複数の読み込みがトリガーされるのを防ぐために、関数手ぶれ補正とスロットルの使用を検討できます。パブリッシュ/サブスクライブ モデルに基づいて、ロード中かどうかを示す isLoading パラメーターが定義され、そのブール値に基づいてロードするかどうかが決定されます。コードは次のとおりです。 🎜rrreee
これで。現在のイメージがロードされたことを通知するために waterfall.done
を追加します。 コードは次のとおりです: 🎜rrreee🎜 上記は、私が全員のためにコンパイルしたものです。 . 今後も皆様のお役に立てれば幸いです。 🎜🎜関連記事: 🎜🎜🎜Vue コンポーネントと Route のライフサイクル (詳細なチュートリアル) 🎜🎜🎜🎜SpringMVC を使用して vue クロスドメインリクエストを解決する🎜🎜🎜🎜 webpack 4.0.0-beta.0 バージョンの新機能 (詳細なチュートリアル) 🎜 🎜
以上がJSを使用したウォーターフォールフロープラグインの実装方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











純粋な CSS を使用してウォーターフォール フロー レイアウトを実装する方法とテクニック。ウォーターフォール レイアウト (ウォーターフォール レイアウト) は、Web デザインで一般的なレイアウト方法です。コンテンツを高さの異なる複数の列に配置して画像を形成します。ウォーターフォールのような視覚効果です。このレイアウトは、写真表示や商品表示など、大量のコンテンツを表示する必要がある場面でよく使用され、ユーザーエクスペリエンスが優れています。ウォーターフォール レイアウトを実装するにはさまざまな方法があり、JavaScript または CSS を使用して実行できます。

ネイティブ JS で append() メソッドを実装するには、特定のコード サンプルが必要です。JavaScript コードを作成するとき、多くの場合、Web ページ内の指定された要素に新しいコンテンツを追加する必要があります。一般的な操作は、innerHTML 属性を使用して要素の HTML コンテンツを設定することです。ただし、innerHTML 属性を使用すると、要素内のイベント リスナーやスタイルなどが失われる場合があります。コンテンツを追加する機能をより適切に実装するために、append() メソッドを自分で実装できます。 append() メソッドは次のことができます。

CSSでウォーターフォールフローを実装するにはどうすればよいですか?次の記事では、CSSを使用してウォーターフォールフローを実装する2つの方法を紹介します。

HTML と CSS を使用してウォーターフォール フロー カード レイアウトを実装する方法 Web 開発では、ウォーターフォール フロー カード レイアウトは一般的でクールな表示方法です。ウォーターフォール フロー レイアウトはカードの不規則な形状が特徴で、コンテンツの量と画面サイズに応じて高さと位置が自動的に調整され、ページがより魅力的でインタラクティブになります。この記事では、HTML と CSS を使用してウォーターフォール フロー カード レイアウトを実装する方法を紹介し、具体的なコード例を示します。 1. HTML 構造 まず、HTML 構造を作成する必要があります。この例では、

CSS レイアウト チュートリアル: ウォーターフォール カード レイアウトを実装する最良の方法 はじめに: 最新の Web デザインでは、ウォーターフォール カード レイアウトは非常に人気のあるレイアウト方法です。大量のコンテンツを効果的に表示し、さまざまな画面サイズに適応できるため、ユーザーに優れたブラウジング体験を提供できます。この記事では、ウォーターフォール カード レイアウトを実装する最適な方法について説明し、具体的なコード例を示します。 1. ウォーターフォール フロー レイアウト実装の原則 ウォーターフォール フロー レイアウトの原則は、さまざまなコンテンツの高さに応じて、一定のルールに従ってカードを異なる位置に配置することです。

Vue を使用してウォーターフォール レイアウト効果を実装する方法. ウォーターフォール レイアウトは、一般的な Web ページのレイアウト方法です。さまざまな高さに応じてコンテンツを自動的に配置して、滝のような効果を形成できます。フロントエンド開発では、Vueフレームワークを利用してウォーターフォールレイアウト効果を実装することができますので、具体的な実装方法とコード例を紹介します。 Vue および Masonry レイアウト ライブラリを導入します。まず、HTML ファイルに Vue および Masonry レイアウト ライブラリの CDN リンクを導入します。コードは次のとおりです: <script

モバイル デバイスの人気に伴い、WeChat ミニ プログラムはますます多くの企業や個人に選ばれるようになりました。しかし、小規模なプログラムの開発プロセスでは、ウォーターフォール フロー効果を実現するのは困難な作業です。この記事では、PHP を使用して WeChat アプレットにテキスト ウォーターフォール フロー効果を実装する方法を紹介します。 1. 滝流効果の実装方法 滝流効果とは、高さの異なる要素を並べて滝のように見せる視覚効果のことです。 Web 上でウォーターフォール フロー効果を実装する場合、一般的に使用される方法は CSS 列レイアウトを使用することです。

HTML と CSS を使用してウォーターフォール フロー グリッド レイアウトを実装する方法. ウォーターフォール フロー グリッド レイアウトは、Web ページ要素に滝のような効果を与え、ユーザーに優れた視覚エクスペリエンスを提供できる一般的なレイアウト方法です。この記事では、HTML と CSS を使用してウォーターフォール フロー グリッド レイアウトを実装する方法を紹介し、具体的なコード例を示します。まず、HTML 構造と CSS スタイルを準備する必要があります。以下は基本的な HTML 構造であり、表示する必要があるいくつかの要素が含まれています: <!DOCTYPEhtml&
