欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

javascript實(shí)現(xiàn)瀑布流加載圖片原理

 更新時(shí)間:2016年02月02日 10:56:27   作者:帶上餅干  
這篇文章主要為大家介紹了javascript實(shí)現(xiàn)瀑布流加載圖片效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

講一下大概的原理吧

 功能描述:

  • 根據(jù)不同菜單的屬性值分別加載不同的數(shù)據(jù)
  • 下拉滾動(dòng)條到一定位置預(yù)加載圖片,滾動(dòng)條拉到最底下的時(shí)候渲染html;
  • 鼠標(biāo)移到菜單,切換各個(gè)圖片列表;
  • 鼠標(biāo)移到圖片列表上,顯示詳細(xì)信息; 

技術(shù)實(shí)現(xiàn)方案:

  先梳理一下從加載到顯示的流程:
  1. 加載數(shù)據(jù)
  2. 拼接HTML寫入到頁面
  3. 檢查剛剛寫入的HTML中的img是否全部加載完成,如果是,進(jìn)入5、否則進(jìn)入4
  4. 等待圖片加載完成
  5. 計(jì)算每個(gè)元素的位置

  一開始的時(shí)候最頭疼的是如何定位的問題,后來經(jīng)過朋友指導(dǎo)終于解決:計(jì)算總共有多少列圖片并且把每一列的高度都放到一個(gè)數(shù)組里面。每當(dāng)一張圖片加載完成的時(shí)候就查找這個(gè)數(shù)組里面最小的值,并且定位當(dāng)前圖片的top設(shè)置為這個(gè)值,完成后把這個(gè)圖片的高度加上數(shù)組里面的最小值并且返回到數(shù)組里面,依次類推。 
 PS:因?yàn)檫@個(gè)功能代碼太多,只能作基本的簡單分解代碼了: 

// 創(chuàng)建用于記錄每列高度的數(shù)組
_getLowestCol: function() {
  t._cols = new Array(5),min = 0;
  // 初始化為0
  for (var i = 0; i < t._cols.length; i++) {
    if (cols[i] < cols[min]) {
      min = i;
    }
    return min;
  }
},
_reposition: function() {
  t._grids.each(function(i, grid) {
    //先顯示出來
    grid = $(grid).show();
    
    var height = grid.outerHeight(), min = t._getLowestCol();

    // 定位
    grid.animate({
      left: (t._colWidth + t._colSpacing) * min,
      top: t._cols[min],
      opacity: 1
    },1000);
    // 記錄高度
    t._cols[min] += height;
  });

}

 其次開發(fā)過程中遇到的難題是:因?yàn)槿缟蠄D所示,鼠標(biāo)移動(dòng)到菜單欄需要切換圖片列表,并且分別需要用瀑布流加載不同類型的數(shù)據(jù)。所以要處理在切換頁面的時(shí)候如何才能做到每個(gè)頁面只執(zhí)行一次代碼請(qǐng)求接口,而不需要每一次切換都重新請(qǐng)求數(shù)據(jù)接口,僅僅執(zhí)行切換顯示圖片列表的操作就可以了。
  考慮到每一個(gè)菜單都有一個(gè)自定義屬性,所以這個(gè)問題輕易地解決了:建立一個(gè)對(duì)象來記錄當(dāng)前菜單是否已經(jīng)執(zhí)行過代碼,如果沒有就執(zhí)行請(qǐng)求數(shù)據(jù) ?!?/p>

var isLoad = {};//是否載入過
labelType.mouseover(function() {
  var i = $(this).index();
  var api = _this.attr('api');//接口標(biāo)識(shí)
  
  if(! isLoad[ api ]){
    isLoad[ api ] = i;
    loadData(wrapper, api);
  }
  
});

以下為全部代碼:
html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<style type="text/css">
*{margin:0;padding:0;}
ul,li{  list-style-type:none;}
li img{width:100%;list-style:none;}
</style>
</head>
<body>
  <div class="photo_box">
    <ul id="container" style="border:1px solid #000;width:80%;height:600px;overflow:hidden;margin:0 auto;position: relative;">
    </ul>
    <div id="loading" class="loading" style="text-align: center;margin-top: 20px;font-size: 1.2em;">加載中...</div>
    <div id="more" class="more"style="text-align: center;margin-top: 20px;font-size: 1.2em;"><input type="button" value="更 多" id="clear" /></div>
  </div>
<script type="text/javascript" src="../../lib/seajs/sea.js"></script>
<script type="text/javascript" src="../../lib/base/1.0.x/base.js"></script>
<script type="text/javascript">
seajs.use(['lib/jquery/1.11.x/index.js', '_example/waterFall_1.1/waterfall.js'], function($, waterFall) {
  waterFall.init({
    container: $('#container'),
    dataURL: 'http://www.woxiu.com/index.php?action=Index/Main&do=ApiZhuboGrade',
    dataType: 'jsonp',
    template: '<% for (var i = 0; i < data.length; i++) { %>' +
            '<li style="display: none;">' +
              '<img src=" <%-data[i].room_img%> ">' +
            '</li>' + 
          '<% } %>',
    colWidth: 200,
    colSpacing: 10,
    rowSpacing: 15,
    page: 1,
    pageEnd: 8,
  });

  // 限制同時(shí)展示的頁數(shù)
  var loadCounter = 1;
  function pageNum(){
    if (loadCounter >= 3) {
      $('#more').show();
      $('#loading').hide();
      return true;
    } else {
      loadCounter++;
      $('#more').hide();
      $('#loading').show();
    }
    return false;
  }
  $('#clear').click(function() {
    loadCounter = 1;
    waterFall._loadNext();
  });
});

</script>
</body>

js:

/**
 * 瀑布流布局組件類
 * @param {Object} options 組件設(shè)置
 *    @param {NodeList} options.container 瀑布流容器
 *    @param {String} options.dataURL 數(shù)據(jù)地址
 *    @param {String} [options.dataType='jsonp'] 數(shù)據(jù)類型,json或jsonp
 *    @param {String}  options.template 模板編輯
 *    @param {Number} [options.colWidth] 圖片大小。
 *    @param {Number} [options.colSpacing] 列間隔。
 *    @param {Number} [options.rowSpacing] 行間隔。
 *    @param {Number} [options.page=1] 數(shù)據(jù)開始頁碼
 *    @param {Number} [options.pageEnd] 數(shù)據(jù)末尾頁碼

 * @pageNum() 函數(shù),如果不需要現(xiàn)在加載也是,需要把函數(shù)里面的判斷去掉。


 從加載到顯示的流程

1. 加載數(shù)據(jù)
2. 拼接HTML寫入到頁面
3. 檢查剛剛寫入的HTML中的img是否全部加載完成,如果是,進(jìn)入5、否則進(jìn)入4
4. 等待圖片加載完成
5. 計(jì)算每個(gè)元素的位置

 */
define(function(require, exports, module) {
  'use strict';
  
  var Tmpl = require('lib/tmpl/2.1.x/index.js'),
    $ = require('lib/jquery/1.11.x/index.js');

  var waterFall = {
    init: function(options) {
      var t = this;
      t._container = options.container;
      t._template = options.template;
      t._colWidth = options.colWidth;
      t._colSpacing = options.colSpacing;
      t._rowSpacing = options.rowSpacing;
      t.dataURL = options.dataURL;
      t.dataType = options.dataType;
      t.page = options.page;
      t.pageEnd = options.pageEnd;
      t._switch = false;

      //計(jì)算有幾列 總寬度 / (列寬 + 列間隔)
      t._totalCols = parseInt(t._container.width() / (t._colWidth + t._colSpacing));

      // 創(chuàng)建用于記錄每列高度的數(shù)組
      t._cols = new Array(t._totalCols);
      // 初始化為0
      for (var i = 0; i < t._cols.length; i++) {
        t._cols[i] = 0;
      }

      t._loadingPage = options.page || 0;
      t._loadNext(options);

      //下拉滾動(dòng)條加載
      var lastTime = new Date().getTime();

      $(window).scroll(function() {

        if ( !t._switch ) {
          //判斷是否滾動(dòng)過快,在ie下
          var thisTime = new Date().getTime();

          if (thisTime - lastTime < 50) {
            console.log(thisTime - lastTime);
            lastTime = thisTime;
            return;
          }

          if ($(window).scrollTop() + $(window).height() >= document.documentElement.scrollHeight) {
            lastTime = thisTime;
            t._loadNext();
          }
        }
      });
    },
    //加載器
    _loadNext: function(t) {
      var t = this;

      t._switch = true;
      //請(qǐng)求數(shù)據(jù)
      if (!t.trigger) {
        $.ajax({
          url: t.dataURL,
          data: { page: ++t._loadingPage },
          dataType:t.dataType,
          success: function(response){
            
            t.trigger = t._completeLoading(response);

          },
          error:function(){console.log('Error! 請(qǐng)求有誤');}
        });  
      }
      return false;
    },
    //加載完數(shù)據(jù)調(diào)用此函數(shù)
    _completeLoading: function(result) {
      var t = this;
      if (t._loadingPage >= t.pageEnd) {
        $('#more').hide();
        $('#loading').html('<p>已是最后一頁了喔 ^_^ ^_^</p>');
        return true;
      }
      else {
        //if (!pageNum()) {
          t._add(result);
        //};
      }
      
      return false;
    },
    //添加格子
    _add: function(result) {
      var t = this, grids = '';
      //調(diào)用模板
      var content = Tmpl.render(t._template, {data:result.data});
      //原始定位
        t._grids = $(content).css({
          position: 'absolute',
          left: t._container.width(),
          top: t._container.height(), 
          width: t._colWidth,
          opacity: 0
        });

      //把Html添加到容器
      t._container.append(t._grids);

      // 執(zhí)行一次_reposition,如果所有圖片都加載完成,該方法返回true,否則返回false
      if ( !t._reposition() ) {
        // 有圖片未加載完,監(jiān)聽onload和onerror
        t._grids.find('img').bind('load error', function() {
          this.loaded = true;
          // 有圖片加載完成,再次執(zhí)行_reposition
          if (t._grids) {
            t._reposition();
          }
        });
      }
    },
    // 此方法用于獲取高度最低的列
    _getLowestCol: function() {
      var cols = this._cols, min = 0;
      for (var i = 1; i < cols.length; i++) {
        if (cols[i] < cols[min]) {
          min = i;
        }
      }
      return min;
    },
    //定位
    _reposition: function() {

      var t = this, allImgsLoaded = true;

      // 檢測圖片是否全部加載完成
      t._grids.find('img').each(function(i, img) {
        if (!img.loaded && !img.complete) {

          allImgsLoaded = false;
        }
        return allImgsLoaded;
      });

      if (allImgsLoaded) {
        t._grids.each(function(i, grid) {
          //先顯示出來
          grid = $(grid).show();
          
          var height = grid.outerHeight(), min = t._getLowestCol();

          // 非第一行的時(shí)候,要加上行間隔
          if (t._cols[min]) { t._cols[min] += t._rowSpacing; }
          // 定位
          grid.animate({
            left: (t._colWidth + t._colSpacing) * min,
            top: t._cols[min],
            opacity: 1
          },1000);
          // 記錄高度
          t._cols[min] += height;
        });
        // 重設(shè)外層容器高度為最高列高度
        t._container.css( 'height', Math.max.apply(Math, t._cols) );
        t._switch = false;
        delete t._grids;
      }

      return allImgsLoaded;
    },
  }

  return waterFall;
});

以上就是本文的全部內(nèi)容,希望對(duì)大家學(xué)習(xí)javascript程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • 一文詳解JavaScript中的URL和URLSearchParams

    一文詳解JavaScript中的URL和URLSearchParams

    URL,稱為統(tǒng)一資源定位器,指互聯(lián)網(wǎng)上能找到資源定位的字符串,而URLSearchParams對(duì)象是專門用于處理url網(wǎng)址信息中的查詢字符串,本文就來帶大家深入了解一下二者的使用
    2023-05-05
  • JavaScript算法題之如何將一個(gè)數(shù)組旋轉(zhuǎn)k步

    JavaScript算法題之如何將一個(gè)數(shù)組旋轉(zhuǎn)k步

    這篇文章主要給大家介紹了關(guān)于JavaScript算法題之如何將一個(gè)數(shù)組旋轉(zhuǎn)k步的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03
  • JS關(guān)鍵字變色實(shí)現(xiàn)思路及代碼

    JS關(guān)鍵字變色實(shí)現(xiàn)思路及代碼

    JS關(guān)鍵字變色詳細(xì)很多朋友都很想實(shí)現(xiàn)吧接下來將執(zhí)行以下幾個(gè)步驟:1.替換關(guān)鍵字,對(duì)字體變色2.用正則,CSS背景變色;該方法可結(jié)合前臺(tái)JS調(diào)用,感興趣的朋友可以參考下,希望可以幫助到你
    2013-02-02
  • 原生javascript實(shí)現(xiàn)分享到朋友圈功能 支持ios和android

    原生javascript實(shí)現(xiàn)分享到朋友圈功能 支持ios和android

    本文主要介紹網(wǎng)上一個(gè)牛人寫的js可以實(shí)現(xiàn)在UC瀏覽器和QQ瀏覽器中調(diào)用瀏覽器內(nèi)置的分享組件進(jìn)行分享。
    2016-05-05
  • javascript高級(jí)的文件目錄排序代碼

    javascript高級(jí)的文件目錄排序代碼

    這幾天在做一個(gè)文件管理的模塊,里面有排序的功能,產(chǎn)品經(jīng)理看了說希望能做出更加智能的文件排序功能,就像是win7的名稱排序一樣,主要就是文件名中的數(shù)字會(huì)按大小排序,而不是直接按ascii碼 ,這兩天晚上沒事,就先寫了這個(gè)排序方法,下個(gè)版本中就可以用上了
    2010-08-08
  • 深入探究JS中的異步編程和事件循環(huán)機(jī)制

    深入探究JS中的異步編程和事件循環(huán)機(jī)制

    js是單線程事件循環(huán)模型,同步操作與異步操作時(shí)代碼所依賴的核心機(jī)制,異步行為是為了優(yōu)化因計(jì)算量大而時(shí)間長的操作,本文詳細(xì)給大家介紹了JS中的異步編程和事件循環(huán)機(jī)制,文中有詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-05-05
  • js關(guān)閉當(dāng)前頁面(窗口)的幾種方式總結(jié)

    js關(guān)閉當(dāng)前頁面(窗口)的幾種方式總結(jié)

    js關(guān)閉當(dāng)前頁面(窗口)的幾種方式總結(jié),需要的朋友可以參考一下
    2013-03-03
  • JavaScript實(shí)現(xiàn)移動(dòng)端橫豎屏檢測

    JavaScript實(shí)現(xiàn)移動(dòng)端橫豎屏檢測

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)移動(dòng)端橫豎屏檢測,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 微信小程序事件點(diǎn)擊跳轉(zhuǎn)頁面的五種方法小結(jié)

    微信小程序事件點(diǎn)擊跳轉(zhuǎn)頁面的五種方法小結(jié)

    本文主要介紹了微信小程序事件點(diǎn)擊跳轉(zhuǎn)頁面的五種方法小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 微信小程序?qū)崿F(xiàn)笑臉評(píng)分功能

    微信小程序?qū)崿F(xiàn)笑臉評(píng)分功能

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)笑臉評(píng)分功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11

最新評(píng)論