폭포수 흐름 플러그인을 구현하는 JS 코드
폭포 흐름 레이아웃의 그림에는 동일한 너비와 가변 높이라는 핵심 기능이 있습니다. 폭포 흐름 레이아웃은 Pinterest, Huaban.com 등과 같은 국내 웹사이트에서 어느 정도 사용됩니다. 본 글은 주로 네이티브 JS 워터폴 플로우 플러그인과 코드 관련 설명을 자세하게 분석한 글이므로 관심 있는 독자분들은 참고하셔서 공부하시는데 도움이 되었으면 좋겠습니다.
기본 함수 구현
먼저 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을 구현한 후 다음 단계는 스크롤 이벤트 모니터링을 구현하는 것입니다. 상위 노드의 맨 아래에 도달합니다. 그림이 꾸준히 로드되는 효과가 있습니다. 이때 고려해야 할 점은 스크롤할 때 로딩 기능이 어느 위치에서 실행되는지입니다. 이는 사람마다 다릅니다. 내 접근 방식은 상위 컨테이너 높이 + 스크롤 거리> 마지막 이미지의 offsetTop
조건, 즉 주황색 선 + 보라색 선 > 파란색이 충족될 때 로드를 트리거하는 것입니다. line 함수의 코드는 다음과 같습니다.
rrreee상위 노드가 노드를 맞춤화할 수 있으므로 스크롤 모니터링 기능의 캡슐화를 제공합니다.
rrreeeResize 이벤트 모니터링은 다음과 같습니다. 스크롤 이벤트 모니터링과 유사합니다. 트리거될 때 크기 조정 기능이 없으면 초기화 기능을 호출하여 재설정하면 됩니다.
🎜게시-구독 모델과 상속을 사용하여 리스닝 바인딩 구현🎜🎜플러그인 개발이 목표이기 때문에 기능 구현에만 만족할 수 없고 개발자가 스스로 처리할 수 있도록 해당 운영 공간을 남겨둡니다. . 비즈니스 시나리오에서 폭포 흐름의 그림 드롭다운 로드를 떠올려 보면 일반적으로 Ajax를 통해 비동기식으로 가져오므로 로드된 데이터를 라이브러리에 하드 코딩해서는 안 됩니다(여기에서는). 우리는 폭포수 사용에서 교훈을 얻습니다), 🎜🎜🎜 🎜rrreee🎜호출 방법을 살펴보면 게시/구독 모델을 사용하여 구현하는 것을 생각하는 것은 어렵지 않습니다. Node.js 비동기 비동기 레코드. 핵심 아이디어는 구독 함수를 통해 캐시에 함수를 추가한 다음 게시 함수를 통해 비동기 호출을 구현하는 것입니다. 코드 구현은 다음과 같습니다. 🎜🎜🎜🎜rrreee🎜다음으로 Waterfall이 게시/구독을 사용하도록 합니다. 모드에서는 Waterfall이 eventEmitter 함수를 상속하도록 하면 코드는 다음과 같이 구현됩니다. 🎜🎜🎜🎜rrreee🎜상속 방법은 생성자 상속과 프로토타입 체인 상속을 기반으로 하는 두 가지 작성 방법의 장점을 흡수하고Object를 사용합니다. .create
를 사용하여 분리 하위 클래스와 상위 클래스에 대해서는 상속에 대한 자세한 내용을 다루는 다른 기사를 작성할 수 있으므로 여기에서 멈추겠습니다. 🎜🎜🎜작은 최적화🎜🎜🎜스크롤 이벤트로 인해 이미지가 여러 번 로드되는 것을 방지하려면 흔들림 방지 및 조절 기능을 사용하는 것을 고려할 수 있습니다. 게시-구독 모델을 기반으로 로딩 여부를 나타내는 isLoading 매개변수가 정의되어 있으며, Boolean 값에 따라 로딩 여부가 결정됩니다. 🎜🎜🎜🎜rrreee🎜 이때 필요한 것은 다음과 같습니다. waterfall.done
을 추가하여 현재 이미지가 로드되었음을 알리는 코드는 다음과 같습니다. 🎜🎜🎜🎜rrreee🎜관련 권장사항: 🎜🎜🎜🎜자세한 설명 순수 네이티브 JS 워터폴 플러그인 Macy.js🎜🎜🎜🎜Jquery 사용 워터폴 플로우 플러그인_jquery🎜🎜🎜🎜jQuery 워터폴 플로우 플러그인 Wookmark 사용법 소개 example_jquery🎜🎜위 내용은 폭포수 흐름 플러그인을 구현하는 JS 코드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 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
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











PyCharm은 개발자가 코드를 보다 효율적으로 작성할 수 있도록 다양한 기능과 도구를 제공하는 강력하고 인기 있는 Python 통합 개발 환경(IDE)입니다. PyCharm의 플러그인 메커니즘은 기능을 확장하기 위한 강력한 도구입니다. 다양한 플러그인을 설치하면 PyCharm에 다양한 기능과 사용자 정의 기능을 추가할 수 있습니다. 따라서 PyCharm을 처음 접하는 사람이 플러그인을 이해하고 능숙하게 설치하는 것이 중요합니다. 이 문서에서는 PyCharm 플러그인의 전체 설치에 대해 자세히 소개합니다.
![Illustrator에서 플러그인 로드 중 오류 발생 [수정됨]](https://img.php.cn/upload/article/000/465/014/170831522770626.jpg?x-oss-process=image/resize,m_fill,h_207,w_330)
Adobe Illustrator를 시작할 때 플러그인 로딩 오류에 대한 메시지가 팝업됩니까? 일부 Illustrator 사용자는 응용 프로그램을 열 때 이 오류가 발생했습니다. 메시지 뒤에는 문제가 있는 플러그인 목록이 표시됩니다. 이 오류 메시지는 설치된 플러그인에 문제가 있음을 나타내지만 손상된 Visual C++ DLL 파일이나 손상된 기본 설정 파일과 같은 다른 이유로 인해 발생할 수도 있습니다. 이 오류가 발생하면 이 문서에서 문제 해결 방법을 안내하므로 아래 내용을 계속 읽어보세요. Illustrator에서 플러그인 로드 오류 Adobe Illustrator를 시작하려고 할 때 "플러그인 로드 오류" 오류 메시지가 표시되면 다음을 사용할 수 있습니다. 관리자로

사용자가 Edge 브라우저를 사용할 때 더 많은 요구 사항을 충족하기 위해 일부 플러그인을 추가할 수 있습니다. 그런데 플러그인을 추가하면 해당 플러그인이 지원되지 않는다고 표시됩니다. 이 문제를 해결하는 방법은 무엇입니까? 오늘은 에디터가 세 가지 해결 방법을 알려드리겠습니다. 방법 1: 다른 브라우저를 사용해 보세요. 방법 2: 브라우저의 Flash Player가 오래되었거나 누락되어 플러그인이 지원되지 않을 수 있습니다. 공식 웹사이트에서 최신 버전을 다운로드할 수 있습니다. 방법 3: "Ctrl+Shift+Delete" 키를 동시에 누르세요. "데이터 지우기"를 클릭하고 브라우저를 다시 엽니다.

Chrome 플러그인 확장 프로그램 설치 디렉터리는 무엇인가요? 일반적인 상황에서 Chrome 플러그인 확장의 기본 설치 디렉터리는 다음과 같습니다. 1. windowsxp에서 Chrome 플러그인의 기본 설치 디렉터리 위치: C:\DocumentsandSettings\username\LocalSettings\ApplicationData\Google\Chrome\UserData\ Windows7의 Default\Extensions2.chrome 플러그인의 기본 설치 디렉터리 위치: C:\Users\username\AppData\Local\Google\Chrome\User

WebSocket과 JavaScript: 실시간 모니터링 시스템 구현을 위한 핵심 기술 서론: 인터넷 기술의 급속한 발전과 함께 실시간 모니터링 시스템이 다양한 분야에서 널리 활용되고 있다. 실시간 모니터링을 구현하는 핵심 기술 중 하나는 WebSocket과 JavaScript의 조합입니다. 이 기사에서는 실시간 모니터링 시스템에서 WebSocket 및 JavaScript의 적용을 소개하고 코드 예제를 제공하며 구현 원칙을 자세히 설명합니다. 1. 웹소켓 기술

PyCharm Community Edition은 충분한 플러그인을 지원합니까? 구체적인 코드 예제가 필요 소프트웨어 개발 분야에서 Python 언어가 점점 더 널리 사용됨에 따라 전문적인 Python 통합 개발 환경(IDE)인 PyCharm이 개발자들에게 선호되고 있습니다. PyCharm은 Professional 버전과 Community 버전의 두 가지 버전으로 나누어집니다. Community 버전은 무료로 제공되지만 Professional 버전에 비해 플러그인 지원이 제한됩니다. 그렇다면 문제는 PyCharm Community Edition이 충분한 플러그인을 지원하느냐는 것입니다. 이 기사에서는 특정 코드 예제를 사용하여

EclipseSVN 플러그인 설치 및 설정 방법에 대한 자세한 설명 Eclipse는 기능을 확장하기 위해 다양한 플러그인을 지원하는 널리 사용되는 통합 개발 환경(IDE)입니다. 그 중 하나는 개발자가 Subversion 버전 제어 시스템과 상호 작용할 수 있게 해주는 EclipseSVN 플러그인입니다. 이 기사에서는 EclipseSVN 플러그인을 설치 및 설정하는 방법을 자세히 설명하고 특정 코드 예제를 제공합니다. 1단계: EclipseSVN 플러그인 설치 및 Eclipse 열기

JavaScript 및 WebSocket: 효율적인 실시간 일기 예보 시스템 구축 소개: 오늘날 일기 예보의 정확성은 일상 생활과 의사 결정에 매우 중요합니다. 기술이 발전함에 따라 우리는 날씨 데이터를 실시간으로 획득함으로써 보다 정확하고 신뢰할 수 있는 일기예보를 제공할 수 있습니다. 이 기사에서는 JavaScript 및 WebSocket 기술을 사용하여 효율적인 실시간 일기 예보 시스템을 구축하는 방법을 알아봅니다. 이 문서에서는 특정 코드 예제를 통해 구현 프로세스를 보여줍니다. 우리
