> 웹 프론트엔드 > JS 튜토리얼 > 워터폴 플로우 절대 레이아웃_자바스크립트 기술을 구현하기 위한 자바스크립트에 대한 자세한 설명

워터폴 플로우 절대 레이아웃_자바스크립트 기술을 구현하기 위한 자바스크립트에 대한 자세한 설명

WBOY
풀어 주다: 2016-05-16 15:16:58
원래의
1562명이 탐색했습니다.

폭포류는 몇 년 전부터 인기가 있었나 봐요. 먼저 핀터레스트를 기점으로 한 파동이었고 그다음에는 국내 디자인이 버섯처럼 솟아올랐고, 모구지에, 마크 등 폭포가 터지는 사례가 많다(그러나 최근에는 음란물에 연루돼 놀림도 ​​받은 것 같다). 타오바오의 '와우''는 모두 훌륭한 예시인데, 오늘은 폭포수 흐름에 대해 이야기해보겠습니다.
1. 절대 레이아웃:

JS 구현 원칙

실제로 폭포 스타일의 가장 큰 어려움은 해당 열에 이미지를 어떻게 깔끔하게 정리하고, 이미지 새로 고침 및 로딩을 언제 시작해야 하는가입니다.
그림을 깔끔하게 정리하는 주요 논리와 알고리즘은 먼저 컨테이너에 몇 개의 열을 배치할 수 있는지 구한 다음 계산을 통해 첫 번째 열의 높이를 저장하고 나머지 높이를 순회하는 것입니다(단, 요소 제외). 첫 번째 열)을 선택하고 각각 높이가 가장 작은 열을 입력하세요. 하나씩 추가하고 마지막으로 순회를 종료합니다.
새로 고침을 시작하기 위한 설정은 매우 간단합니다. 폭포 새로 고침은 하나의 이벤트, 즉 window.onsroll에만 관련됩니다. 주요 알고리즘은 페이지가 가장 낮은 높이로 슬라이드되면 노드를 로드하고 추가하기 시작하는 것입니다. 물론 추가되는 노드 수는 고정되어 있지 않습니다.
먼저 코드부터 설명하겠습니다. 하나는 이미지 배열이고, 다른 하나는 반응형 로딩을 추가하는 것입니다.

1. 사진 정리

var $ = function() {
  return document.querySelectorAll.apply(document, arguments);
 }
 var arrHeight = []; //得到分列的高度
 var columns = function() { //计算页面最多可以放多少列
  var containerW = $("#main")[0].clientWidth,
   pinW = $(".pin")[0].offsetWidth;
  return Math.floor(containerW / pinW);
 }
 var getIndex = function(arr) { //获得最小高度的index
   var minHeight = Math.min.apply(null, arr); //获得最小高度
   for (var i in arr) {
    if (arr[i] === minHeight) {
     return i;
    }
   }
  }
  //根据列数确定第一排img的高度并放入数组当中。
 var setCenter = (function() { //通过列数设置宽度
  var main = $('#main')[0]; //获得罩层
  var getPadding = function() { //设置padding
   var col = columns(); //获得最后一列
   var padding = main.clientWidth - col * $('.pin')[0].offsetWidth;
   return padding / 2;
  }
  var getComputedStyle = function(ele) { //兼容IE的支持情况
   if (window.getComputedStyle) {
    return window.getComputedStyle(ele);
   } else {
    return ele.currentStyle;
   }
  }
  var getPinPad = function() { //获得pin的padding值
   var pin = $(".pin")[0];
   return parseInt(getComputedStyle(pin).paddingLeft);
  }
  return function() { //设置宽度
   main.style.padding = `0 ${getPadding()}px 0 ${getPadding()-getPinPad()}px`;
  }
 })();
 var overLoad = function(ele) {
  var index = getIndex(arrHeight),
   minHeight = Math.min.apply(null, arrHeight), //获取最小高度
   pins = $('.pin'),
   style = ele.style;
  style.position = "absolute";
  style.top = minHeight + "px"; //设置当前元素的高度
  style.left = pins[index].offsetLeft + "px";
  arrHeight[index] += ele.offsetHeight;
 }
 //初始化时执行函数
 var init = function() {
   var pins = $(".pin"),
    col = columns();
   setCenter(); //设置包裹容器的宽度
   for (var i = 0, pin; pin = pins[i]; i++) {
    if (i < col) { //存储第一排的高度
     arrHeight.push(pin.offsetHeight);
    } else {
     overLoad(pin); //将元素的位置重排
    }
   }
  }
로그인 후 복사

총 7개의 함수(대형 함수)와 1개의 변수가 있습니다. 아이디어에 대해 이야기 해 봅시다. 우선, 페이지가 로드된 후 실행되는 함수는 init입니다. js 프로그램에는 해당 키를 찾는 방법이 있어야 한다는 점을 알아야 합니다. 그런 다음 init 함수 본문으로 깊이 들어가서 관찰합니다. init에서 실행되는 비즈니스 로직은 요소의 첫 번째 행 높이를 저장한 다음 나머지 요소를 재배열하는 것입니다. columns 함수를 사용하여 현재 창에 배치할 수 있는 최대 열 수를 얻은 다음 컨테이너의 중심을 설정합니다(패딩을 통해 설정). 다음으로 핀의 셀 상자를 탐색하고 첫 번째 높이를 저장합니다. arrHeight 배열의 요소 행에 나머지 요소를 추가합니다. 아래 요소는 재정렬됩니다. 다른 기능은 따로 설명할 필요가 없습니다. OverLoad 기능에 집중해 보겠습니다.
2. 과부하

var overLoad = function(ele) {
  var index = getIndex(arrHeight),
   minHeight = Math.min.apply(null, arrHeight), //获取最小高度
   pins = $('.pin'),
   style = ele.style;
  style.position = "absolute";
  style.top = minHeight + "px"; //设置当前元素的高度
  style.left = pins[index].offsetLeft + "px";
  arrHeight[index] += ele.offsetHeight;
 }
로그인 후 복사

overLoad에는 최소 높이의 인덱스를 가져오는 getIndex 함수가 있으며, 그런 다음 들어오는 요소의 위치를 ​​설정할 수 있습니다(절대 위치 지정). top은 배열의 최소 높이에 대한 px 값입니다. left는 첫 번째 행에 대해 설정됩니다. Index 요소의 왼쪽 여백 위치입니다. 드디어 높이 업데이트가 완료되었습니다.
3. 로딩 위치 설정

var dataInt = [{
  'src': '1.jpg'
 }, {
  'src': '2.jpg'
 }, {
  'src': '3.jpg'
 }, {
  'src': '4.jpg'
 }, {
  'src': '1.jpg'
 }, {
  'src': '2.jpg'
 }, {
  'src': '3.jpg'
 }, {
  'src': '4.jpg'
 }];

 function isLoad() { //是否可以进行加载
  var scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
   wholeHeight = document.documentElement.clientHeight || document.body.clientHeight,
   point = scrollTop + wholeHeight; //页面底部距离header的距离
  var arr = $('.pin');
  var lastHei = arr[arr.length - 1].getBoundingClientRect().top;
  return (lastHei < point) &#63; true : false;
 }
 //处理滑动
 var dealScroll = (function() {
  var main = $('#main')[0],
   flag = true;
  return function() {
   if (isLoad() && flag) {
    for (var i = 0, data; data = dataInt[i++];) {
     var div = document.createElement('div');
     div.innerHTML = temp(data.src);
     div.className = "pin";
     main.appendChild(div);
     overLoad(div); //和上面的overload有耦合性质
    }
    flag = false;
    setTimeout(function() { //控制滑行手速,时间越长对速度的滑动时间影响越大。
     flag = true;
    }, 200);
   }
  }
 })();

 function temp(src) {
  return `
  <div class="box">
   <img src="http://cued.xunlei.com/demos/publ/img/P_00${src}"/>
  </div>
 `;
 }

로그인 후 복사

실제로 핵심은 이전 부분에 있습니다. 이는 단지 데이터를 로드하는 수단일 뿐입니다. 물론 클릭하여 로드(수동 트리거)하거나 다른 로드 방법을 사용할 수도 있습니다. 물론 설정 방법은 전적으로 귀하에게 달려 있습니다. 따라서 추세를 따르고 계속 아래로 스크롤하여 로드하세요. 계속해서 항목 함수->dealScroll을 찾습니다. 이 함수의 작업은 isload 함수를 통해 로딩을 수행할 수 있는지 여부를 결정하는 것입니다. isload 기능을 살펴보겠습니다. 이것이 롤링 로딩의 핵심입니다.

 function isLoad() { //是否可以进行加载
  var scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
   wholeHeight = document.documentElement.clientHeight || document.body.clientHeight,
   point = scrollTop + wholeHeight; //页面底部距离header的距离
  var arr = $('.pin');
  var lastHei = arr[arr.length - 1].getBoundingClientRect().top;
  return (lastHei < point) &#63; true : false;
 }
로그인 후 복사

계산을 통해 뷰포트(툴바 하단)의 페이지 하단 위치를 마지막 요소의 절대 위치와 비교하여 슬라이딩 거리를 초과하면 로딩이 활성화됩니다.
응~ 끝났어.
dealScroll로 돌아가기
다음 단계는 로딩 부분을 살펴보는 것인데 이 부분에 대해서는 사실 딱히 할 말이 없습니다. div 노드를 생성한 후 컨테이너 끝에 배치하고 overLoad 함수를 사용하여 위치를 처리하는 것입니다. 마디. 또한, 함수 마지막에 슬라이딩 속도를 제어하는 ​​트릭을 설정해 놓았는데, 함수를 제한함으로써 요청이 너무 느려지고 사용자가 반복적으로 요청을 보내 리소스가 낭비되는 것을 방지할 수 있습니다.
그러면 이 부분은 끝날 수 있다.
4. 반응형
마지막 부분은 응답성입니다. 이 부분도 매우 간단합니다. 캡슐화만 잘 하면 실제로 이 부분은 크기 조정 이벤트를 추가하는 것뿐입니다. 계속해서 입력 기능을 찾아보겠습니다.

 var resize = (function() {
   var flag;
   return function(fn) {
    clearTimeout(flag);
    flag = setTimeout(function() { //函数的节流,防止用户过度移动
     fn();
     console.log("ok")
    }, 500);
   }
})();
로그인 후 복사

마찬가지로 여기서는 기능 조절이라는 아이디어가 사용됩니다. 프로그래머로서 절대로 사용자가 할 일이 없을 때 브라우저 창을 끌어다 놓을 수 없다고 생각하십시오. 재생하고, 확대하고, 축소하고, 그리고 확대... 사실 저는 이런거 자주 합니다. 여자친구도 없고 코드 쓰기도 귀찮아서 브라우저만 드래그해서 플레이합니다. 그러므로 우리 독견의 요구를 고려하면 기능 조절을 사용하는 것이 매우 필요합니다. 어린이 신발에 관심이 있으시면 이전 기사를 참조하여 자세히 알아보세요. 설명하자면, 여기서 콜백 함수는 init 함수를 의미하지만 init에 몇 가지 변경이 필요합니다. 세부정보를 확인하세요.

 var update = function(ele) { //当resize的时候,重新设置
  ele.style.position = "initial";
 }
 //初始化时执行函数
 var init = function() {
   var pins = $(".pin"),
    col = columns();
   arrHeight = []; //清空高度
   setCenter(); //设置包裹容器的宽度
   for (var i = 0, pin; pin = pins[i]; i++) {
    if (i < col) { //存储第一排的高度
     arrHeight.push(pin.offsetHeight);
     update(pin);
    } else {
     overLoad(pin); //将元素的位置重排
    }
   }
  }
로그인 후 복사

요소의 새로운 첫 번째 행을 업데이트하려면 위에 업데이트를 추가해야 합니다.
그러면 그냥 옮겨서 사용하시면 됩니다.
이는 확실히 레이아웃 내용의 대부분입니다. JavaScript 워터폴 플로우의 또 다른 레이아웃 방법은 다음 기사 "폭포 플로우 레이아웃의 JavaScript 구현에 대한 자세한 설명" .

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿