이 글에는 네이티브 JS 워터폴 플러그인에 대한 자세한 분석과 코드 관련 설명이 나와 있으니 관심 있는 독자분들은 참고하시기 바랍니다.
폭포 흐름 레이아웃의 그림에는 동일한 너비와 가변 높이라는 핵심 기능이 있습니다. 폭포 흐름 레이아웃은 Pinterest, Huaban.com 등과 같은 국내 웹사이트에서 특정 규모로 사용됩니다. 그런 다음 이 기능을 기반으로 폭포 흐름 탐색 여정을 시작합니다.
기본 함수 구현
먼저 20개의 그림이 포함된 컨테이너를 정의합니다.
<body> <style> #waterfall { position: relative; } .waterfall-box { float: left; width: 200px; } </style> </body> <p id="waterfall"> <img class="waterfall-box lazy" src="/static/imghwm/default1.png" data-src="images/1.png" alt="JS를 사용하여 Waterfall Flow 플러그인을 구현하는 방법" > <img class="waterfall-box lazy" src="/static/imghwm/default1.png" data-src="images/2.png" alt="JS를 사용하여 Waterfall Flow 플러그인을 구현하는 방법" > <img class="waterfall-box lazy" src="/static/imghwm/default1.png" data-src="images/3.png" alt="JS를 사용하여 Waterfall Flow 플러그인을 구현하는 방법" > <img class="waterfall-box lazy" src="/static/imghwm/default1.png" data-src="images/4.png" alt="JS를 사용하여 Waterfall Flow 플러그인을 구현하는 방법" > <img class="waterfall-box lazy" src="/static/imghwm/default1.png" data-src="images/5.png" alt="JS를 사용하여 Waterfall Flow 플러그인을 구현하는 방법" > <img class="waterfall-box lazy" src="/static/imghwm/default1.png" data-src="images/6.png" alt="JS를 사용하여 Waterfall Flow 플러그인을 구현하는 방법" > ... </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도 이해해야 합니다.
속성의 차이점을 비교해야만 이 프로젝트를 더 잘 이해할 수 있습니다. CSS 코드는 다음과 같이 간단합니다. 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() })Scroll, resize 이벤트 모니터링 구현
초기화 함수 init를 구현한 후 다음 단계는 스크롤 이벤트 모니터링을 구현하는 것입니다. 스크롤이 도달하면 인식합니다. 상위 노드의 맨 아래에는 그림이 꾸준히 로드되는 효과가 있습니다. 이때 고려해야 할 점은 스크롤할 때 로딩 기능이 어느 위치에서 실행되는지입니다. 이는 사람마다 다릅니다. 내 접근 방식은 상위 컨테이너 높이 + 스크롤 거리> 마지막 이미지의 offsetTop
조건, 즉 주황색 선 + 보라색 선 > 파란색이 충족될 때 로드를 트리거하는 것입니다. line 함수의 코드는 다음과 같습니다.
상위 노드가 노드를 맞춤화할 수 있으므로 스크롤 모니터링 기능의 캡슐화를 제공합니다. rrreeeResize 이벤트 모니터링은 스크롤 이벤트 모니터링과 유사합니다. 크기 조정 기능이 실행되면 init를 호출하여 기능을 재설정하면 됩니다.
게시-구독 모델과 상속을 사용하여 리스닝 바인딩 구현플러그인 개발이 목표이기 때문에 기능 구현에만 만족할 수 없고 개발자가 스스로 처리할 수 있도록 해당 운영 공간을 남겨둡니다. . 비즈니스 시나리오에서 워터폴 흐름의 그림 드롭다운 로드를 생각하면 일반적으로 Ajax를 통해 비동기적으로 가져오므로 로드된 데이터를 라이브러리에 하드 코딩하면 안 됩니다(여기에서는). 우리는 폭포수 사용에서 교훈을 얻었습니다),
rrreee호출 방법을 살펴보면 게시/구독 모델을 사용하여 구현하는 것을 생각하는 것은 어렵지 않습니다. .js 비동기 비동기 레코드. 핵심 아이디어는 구독 기능을 통해 캐시에 함수를 추가한 다음 게시 기능을 통해 비동기 호출을 구현하는 것입니다. 코드 구현은 다음과 같습니다. rrreee 다음으로 Waterfall이 게시/구독 모드를 사용하도록 하려면 Waterfall이 eventEmitter 함수를 상속하도록 하기만 하면 코드는 다음과 같이 구현됩니다.
rrreee상속 방법은 생성자 상속과 프로토타입 체인 상속을 기반으로 하는 두 가지 작성 방법의 장점을 흡수하고 Object.create
이제 하위 클래스와 상위 클래스가 있으므로 상속에 대한 자세한 내용을 설명하는 또 다른 기사를 작성할 수 있으므로 여기서 멈추겠습니다. 🎜🎜🎜작은 최적화🎜🎜🎜스크롤 이벤트로 인해 이미지가 여러 번 로드되는 것을 방지하려면 흔들림 방지 및 조절 기능을 사용하는 것을 고려할 수 있습니다. 게시-구독 모델을 기반으로 로드 여부를 나타내는 isLoading 매개변수가 정의되어 있으며, 해당 부울 값에 따라 로드 여부가 결정됩니다. 🎜rrreee
여기서 현재 이미지가 로드되었음을 알리려면 waterfall.done
을 추가하세요. 코드는 다음과 같습니다. 🎜rrreee🎜위는 제가 모두를 위해 컴파일한 것입니다. . 앞으로 모든 사람에게 도움이 되기를 바랍니다. 🎜🎜관련 기사: 🎜🎜🎜Vue 구성 요소 및 Route의 수명 주기(자세한 튜토리얼) 🎜🎜🎜🎜SpringMVC를 사용하여 vue 도메인 간 요청 해결🎜🎜🎜🎜webpack 4.0.0-beta.0 버전의 새로운 기능( 자세한 튜토리얼) 🎜 🎜
위 내용은 JS를 사용하여 Waterfall Flow 플러그인을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

JavaScript는 브라우저 및 Node.js 환경에서 실행되며 JavaScript 엔진을 사용하여 코드를 구문 분석하고 실행합니다. 1) 구문 분석 단계에서 초록 구문 트리 (AST)를 생성합니다. 2) 컴파일 단계에서 AST를 바이트 코드 또는 기계 코드로 변환합니다. 3) 실행 단계에서 컴파일 된 코드를 실행하십시오.

Python 및 JavaScript의 미래 추세에는 다음이 포함됩니다. 1. Python은 과학 컴퓨팅 분야에서의 위치를 통합하고 AI, 2. JavaScript는 웹 기술의 개발을 촉진하고, 3. 교차 플랫폼 개발이 핫한 주제가되고 4. 성능 최적화가 중점을 둘 것입니다. 둘 다 해당 분야에서 응용 프로그램 시나리오를 계속 확장하고 성능이 더 많은 혁신을 일으킬 것입니다.

개발 환경에서 Python과 JavaScript의 선택이 모두 중요합니다. 1) Python의 개발 환경에는 Pycharm, Jupyternotebook 및 Anaconda가 포함되어 있으며 데이터 과학 및 빠른 프로토 타이핑에 적합합니다. 2) JavaScript의 개발 환경에는 Node.js, VScode 및 Webpack이 포함되어 있으며 프론트 엔드 및 백엔드 개발에 적합합니다. 프로젝트 요구에 따라 올바른 도구를 선택하면 개발 효율성과 프로젝트 성공률이 향상 될 수 있습니다.

예, JavaScript의 엔진 코어는 C로 작성되었습니다. 1) C 언어는 효율적인 성능과 기본 제어를 제공하며, 이는 JavaScript 엔진 개발에 적합합니다. 2) V8 엔진을 예를 들어, 핵심은 C로 작성되며 C의 효율성 및 객체 지향적 특성을 결합하여 C로 작성됩니다.

JavaScript는 웹 페이지의 상호 작용과 역학을 향상시키기 때문에 현대 웹 사이트의 핵심입니다. 1) 페이지를 새로 고치지 않고 콘텐츠를 변경할 수 있습니다. 2) Domapi를 통해 웹 페이지 조작, 3) 애니메이션 및 드래그 앤 드롭과 같은 복잡한 대화식 효과를 지원합니다. 4) 성능 및 모범 사례를 최적화하여 사용자 경험을 향상시킵니다.

C 및 JavaScript는 WebAssembly를 통한 상호 운용성을 달성합니다. 1) C 코드는 WebAssembly 모듈로 컴파일되어 컴퓨팅 전력을 향상시키기 위해 JavaScript 환경에 도입됩니다. 2) 게임 개발에서 C는 물리 엔진 및 그래픽 렌더링을 처리하며 JavaScript는 게임 로직 및 사용자 인터페이스를 담당합니다.

JavaScript는 웹 사이트, 모바일 응용 프로그램, 데스크탑 응용 프로그램 및 서버 측 프로그래밍에서 널리 사용됩니다. 1) 웹 사이트 개발에서 JavaScript는 HTML 및 CSS와 함께 DOM을 운영하여 동적 효과를 달성하고 jQuery 및 React와 같은 프레임 워크를 지원합니다. 2) 반응 및 이온 성을 통해 JavaScript는 크로스 플랫폼 모바일 애플리케이션을 개발하는 데 사용됩니다. 3) 전자 프레임 워크를 사용하면 JavaScript가 데스크탑 애플리케이션을 구축 할 수 있습니다. 4) node.js는 JavaScript가 서버 측에서 실행되도록하고 동시 요청이 높은 높은 요청을 지원합니다.

Python은 데이터 과학 및 자동화에 더 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 더 적합합니다. 1. Python은 데이터 처리 및 모델링을 위해 Numpy 및 Pandas와 같은 라이브러리를 사용하여 데이터 과학 및 기계 학습에서 잘 수행됩니다. 2. 파이썬은 간결하고 자동화 및 스크립팅이 효율적입니다. 3. JavaScript는 프론트 엔드 개발에 없어서는 안될 것이며 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축하는 데 사용됩니다. 4. JavaScript는 Node.js를 통해 백엔드 개발에 역할을하며 전체 스택 개발을 지원합니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

맨티스BT
Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기
