js下拉滾動條瀑布流載入資料程式碼例項

antzone發表於2017-04-14

分享一段程式碼例項,並詳細介紹一下它的實現過程。

此程式碼模擬實現了,拖動滾動條實現瀑布流方式載入資料的效果。

當然這裡並沒有真正的載入遠端伺服器的資料,模擬實現的,實際應用中只要做相應的更改即可。

程式碼例項如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style type="text/css">
html, body {
  background: #ccc;
  padding: 0px;
  margin: 0px;
}
.box {
  width: 960px;
  margin: 0 auto;
  overflow: auto;
}
.childDom {
  background: #fff;
  transition: all .5s ease;
}
.childDom:hover {
  transform: scale(1.1);
}
.loadInfo {
  text-align: center;
  font-size: 2em;
}
</style>
<script type="text/javascript">
var Funs = function(newObj) {
  var Obj = {
    width: 240,
    height: 400,
    rowsNum: 4,
    dataNum: 22,
    boxDom: "box",
    num: 10,
    class: "childDom"
  };
  var topNum = 0,
      leftNum = 0;
  Funs.prototype.setEle = function() {
    var boxDom = document.getElementById(Obj.boxDom);
    var boxWidth = Obj.width * Obj.rowsNum + Obj.num * (Obj.rowsNum - 1);
    if (Obj.dataNum / Obj.rowsNum !== parseInt(Obj.dataNum / Obj.rowsNum)) {
      var boxHeight=Obj.height*(parseInt((Obj.dataNum/Obj.rowsNum))+1)+Obj.num*parseInt(Obj.dataNum/Obj.rowsNum);
    } else {
      var boxHeight=Obj.height*(Obj.dataNum/Obj.rowsNum)+Obj.num*((Obj.dataNum/Obj.rowsNum)-1);
    }
    boxDom.style.width = boxWidth + "px";
    boxDom.style.height = boxHeight + "px";
    return boxDom;
  }
  Funs.prototype.creChildEle = function(n) {
    var creEle = document.createElement("div");
    creEle.className = Obj.class;
    creEle.innerHTML = n;
    creEle.style.float = "left";
    creEle.style.position = "absolute";
    creEle.style.width = Obj.width + "px";
    creEle.style.height = Obj.height + "px";
    creEle.style.marginLeft = leftNum + "px";
    creEle.style.marginTop = topNum + "px";
    return creEle;
  }
  Funs.prototype.compute = function(n) {
    if ((n + 1) / Obj.rowsNum == parseInt((n + 1) / Obj.rowsNum)) {
      leftNum = 0;
      topNum += Obj.height + Obj.num;
    } else {
      leftNum += Obj.width + Obj.num;
      topNum = topNum;
    }
  }
  Funs.prototype.init = function() {
    if (newObj !== null) {
      Obj = newObj;
    }
    var dom = this.setEle();
    for (var i = 0; i < Obj.dataNum; i++) {
      var creEle = this.creChildEle(i);
      this.compute(i);
      dom.appendChild(creEle);
    }
  }
}
 
//獲取滾動高度、文件高度、瀏覽器視口高度
var heightFuns = function() {
  //獲取滾動高度
  heightFuns.prototype.getScrollTop = function() {
    var scrollTop = 0,
    bodyScrollTop = 0,
    documentScrollTop = 0;
    if (document.body) {
      bodyScrollTop = document.body.scrollTop;
    }
    if (document.documentElement) {
      documentScrollTop = document.documentElement.scrollTop;
    }
    scrollTop = (bodyScrollTop - documentScrollTop > 0) ? bodyScrollTop : documentScrollTop;
    return scrollTop;
  }
  //獲取文件的總高度
  heightFuns.prototype.getScrollHeight = function() {
    var scrollHeight = 0,
    bodyScrollHeight = 0,
    documentScrollHeight;
    if (document.body) {
      bodyScrollHeight = document.body.scrollHeight;
    }
    if (document.documentElement) {
      documentScrollHeight = document.documentElement.scrollHeight;
    }
    scrollHeight=(bodyScrollHeight-documentScrollHeight>0)?bodyScrollHeight:documentScrollHeight;
    return scrollHeight;
  }
  //獲取瀏覽器視口的高度
  heightFuns.prototype.getWindowHeight = function() {
    var windowHeight = 0;
    if (document.compatMode == 'CSS1Compat') {
      windowHeight = document.documentElement.clientHeight;
    } else {
      windowHeight = document.body.clientHeight;
    }
    return windowHeight;
  }
}
 
var data = {
  width: 250,
  height: 300,
  rowsNum: 3,
  dataNum: 0,
  boxDom: "box",
  num: 20,
  class: "childDom"
};
 
function showData() {
  data.dataNum += 10;
  var creObj = new Funs(data);
  creObj.init();
}
 
window.onload = function () {
  showData();
  var heightObj = new heightFuns();
  window.onscroll = function () {
    var loadDom = document.getElementById("loadInfo");
    if (heightObj.getScrollTop() == heightObj.getScrollHeight() - heightObj.getWindowHeight()) {
      setTimeout(showData, 1000);
      loadDom.innerHTML = "正在載入...";
    }
  }
}
</script>
</head>
<body>
  <div class="box" id="box">
  </div>
  <div class="loadInfo" id="loadInfo"></div>
</body>
</html>

上面的程式碼實現了我們的要求,下面介紹一下它的實現過程。

一.程式碼註釋:

(1).var Funs = function(newObj) {},建構函式的作用後面會介紹到,引數是一個物件,自定義的一些引數。

(2).var Obj = {  

  width: 240,

  height: 400,

  rowsNum: 4,

  dataNum: 22,

  boxDom: "box",

  num: 10,

  class: "childDom"

},此物件規定了一些預設引數。

width規定div的寬度。

height規定div元素的高度。

rowsNum:規定一行有幾個div元素。

dataNum:規定一開始顯示幾個div元素。

boxDom:規定容器div的id屬性值。

num:規定div元素的之間的距離。

class: "childDom",規定一個class樣式類名稱。

(3).var topNum = 0,leftNum = 0,規定上外邊距和左外邊距的初始值。

(4). Funs.prototype.setEle = function() {},此函式用來設定容器div元素的尺寸。

(5).var boxDom = document.getElementById(Obj.boxDom),獲取容器元素物件。

(6).var boxWidth = Obj.width * Obj.rowsNum + Obj.num * (Obj.rowsNum - 1),設定容器div元素的寬度。

這個很好理解,div的寬度乘以每行div的數量再加上div元素之間的距離。

(7).if (Obj.dataNum / Obj.rowsNum !== parseInt(Obj.dataNum / Obj.rowsNum)) {

  var boxHeight=Obj.height*(parseInt((Obj.dataNum/Obj.rowsNum))+1)+Obj.num*(Obj.dataNum/Obj.rowsNum);

} else {

  var boxHeight=Obj.height*(Obj.dataNum/Obj.rowsNum)+Obj.num*((Obj.dataNum/Obj.rowsNum)-1);

},用來設定容器div元素的高度。

if語句後面判斷初始顯示div數目是否整除每行的div數目。如果沒有整除的話,會比整除的情況多出一行。

那麼計算的時候會有一些區別。

(4).boxDom.style.width = boxWidth + "px";

boxDom.style.height = boxHeight + "px";

return boxDom;

設定元素的長度和寬度,並返回此元素物件。

(5).Funs.prototype.creChildEle = function(n) {

  var creEle = document.createElement("div");

  creEle.className = Obj.class;

  creEle.innerHTML = n;

  creEle.style.float = "left";

  creEle.style.position = "absolute";

  creEle.style.width = Obj.width + "px";

  creEle.style.height = Obj.height + "px";

  creEle.style.marginLeft = leftNum + "px";

  creEle.style.marginTop = topNum + "px";

  return creEle;

},建立div元素,並且設定相關的css屬性值。

(6).Funs.prototype.compute = function(n) {

  if ((n + 1) / Obj.rowsNum == parseInt((n + 1) / Obj.rowsNum)) {

    leftNum = 0;

    topNum += Obj.height + Obj.num;

  } else {

    leftNum += Obj.width + Obj.num;

    topNum = topNum;

  }

},計算div元素的左外邊距和右外邊距的值。

(7).Funs.prototype.init = function() {

  if (newObj !== null) {

    Obj = newObj;

  }

  var dom = this.setEle();

  for (var i = 0; i < Obj.dataNum; i++) {

    var creEle = this.creChildEle(i);

    this.compute(i);

    dom.appendChild(creEle);

  }

}進行一些初始化操作。

(8).var heightFuns = function() {},獲取滾動高度、文件高度、瀏覽器視口高度。

內部的相關屬性的應用可以參閱相關閱讀。

(9).var data = {

  width: 250,

  height: 300,

  rowsNum: 3,

  dataNum: 0,

  boxDom: "box",

  num: 20,

  class: "childDom"

},自定義的相關資料引數。

(10).function showData() {

  data.dataNum += 10;

  var creObj = new Funs(data);

  creObj.init();

},此函式可以顯示預設的div,比如本例中預設顯示10個div元素。

(11).window.onload = function () {},當文件內容載入完畢再去執行函式中的程式碼。

(12).showData(),顯示預設div。

(13).var heightObj = new heightFuns(),建立物件例項。

(14).window.onscroll = function () {},註冊onscroll事件處理函式。

(15).var loadDom = document.getElementById("loadInfo"),獲取對應id的元素物件。

(16).if (heightObj.getScrollTop() == heightObj.getScrollHeight() - heightObj.getWindowHeight()) {

  setTimeout(showData, 1000);

  loadDom.innerHTML = "正在載入...";

},首先判斷頁面是否拖動到底部。

使用定時器函式延遲1秒執行,是為了模擬從伺服器載入資料的延遲效果。

在延遲期間顯示"正在載入...".

二.相關閱讀:

(1).scrollTop可以參閱document.documentElement.scrollTop瀏覽器相容一章節。

(2).scrollHeight可以參閱scrollHeight和scrollWidth瀏覽器相容一章節。

(3).clientHeight可以參閱clientHeight一章節。

相關文章