瀑布流知識的延伸

瀑布流,很常見了,淘寶,網易雲音樂等等都有,實現原理,咱先放着一遍,先將涉及到的知識點拓展開來css

1、Math的方法

Math求最小值、最大值,數據庫

對於通常的數字直接求,Math.min  Math.max 編程

可是求數組呢,一個方法,三種形式,js高程書中利用apply的回調函數,將this指向window,直接將所求的數組做爲參數傳入json

封裝函數的方法數組

封裝一個getMin的函數直接調用得到瀏覽器

          var numbers=[23,435,45,34]
          function getMin(arr){               //封裝一個方法
                return min=Math.min.apply(null,arr)  //利用apply的回調函數,將做用域this指向window,將數組做爲參數傳入
          }
          console.log(getMin(numbers))

原型對象的方法一app

學過原型對象,直接在Array的原型上添加min方法,讓Array擁有min的方法,不推薦,產品化的程序不推薦在基本包裝類型添加多餘的方法編程語言

          Array.prototype.min=function(array){     //直接在原型上添加,傳遞參數
               return Math.min.apply(null,array)
          }
          alert(numbers.min(numbers))

原型對象的方法二ide

利用Object.defineProperty方法,這個具體說說函數

          Object.defineProperty(Array.prototype,'max',{
                   writable:false,
                   enumerable:false,
                   configurable:true,
                   value:function(){
                         return Math.max.apply(null,numbers)  
                   }
          })
          console.log(numbers.max())

拓展之Object.defineProperty方法

object.defineProperty()方法直接在對象上定義個新屬性或者修改一個對象的現有屬性,並返回這個對象

接受三個參數

obj:要在其上定義屬性的對象,能夠是引用類型Math,也能夠是自定義的,或者原型對象

prop:要定義或修改屬性的名稱(方法名)

descriptor:將被定義或修改屬性的描述符

默認狀況下使用此方法添加的屬性是不可改變的,可是能夠設置一些特性使其能夠改變,for in 遍歷的到等等

對屬性添加特性描述有數據描述和存取器描述兩種

數據描述

writable:值是否能夠重寫

enumerable:目標屬性是否能夠被枚舉

value:設置屬性的值,能夠爲任意的數據類型或函數

configurable:目標屬性是否能夠被刪除或修改

          //在String原型對象上添加方法
          var str='hello'
          Object.defineProperty(String.prototype,'newword',{
                 value:'world'
          })
          alert(str.newword)
          //單獨給某個對象添加方法
          var obj={}
          Object.defineProperty(obj,'newword',{
                   value:'world'
          })
          alert(obj.newword)
          
          //完整的特性例子
          var obj={}
          Object.defineProperty(obj,'newword',{
                    value:'world',      
                    writable:false,       //是否重寫
                    enumerable:true,     //for in 遍歷
                  configurable:true     //是否能夠刪除屬性  是否能夠再次修改特性
          })
          alert(obj.newword)      //world
          obj.newword='hello'     //writable爲false 因此無效
          alert(obj.newword)      //word
          for(var i in obj){
               console.log(i)       //newword enumerable是true能夠遍歷 
          }
          delete obj.newword
          alert(obj.newword)      //undefined 由於刪除了

存取器描述

使用

getter方法 得到屬性值

setter方法 設置屬性值

當使用getter或setter就不容許使用writable和value這兩個屬性

          var obj={}
          var initValue='hello'
          Object.defineProperty(obj,'newword',{
                  get:function(){             
                      return initValue     //獲得屬性值
                  },
                  set:function(value){     //設置屬性值
                      initValue=value
                  }
          })
          console.log(obj.newword)

IE8只能在DOM對象上使用的

有趣的東西

Math.min 和 Math.max 方法

          var max=Math.max()
          var min=Math.min()
          console.log(max>min)     //false

這裏min反而是大於max呢?

MDN裏解釋對於

Math.min()若是沒有參數,則返回Infinity

Math.max()若是沒有參數,則返回-Infinity

任意參數不能轉換爲數值,則返回NaN

2、獲取指定class的元素

早期的瀏覽器中不兼容getElementsByClassName 爲了獲取指定的class元素集合,經常封裝一個方法,返回數組

          //得到指定class的元素
          function getByClass(parent,name){
                 var lists=parent.getElementsByTagName('*')
                 var arr=[]
                 for(var i=0;i<lists.length;i++){
                           if(lists[i].className==name){
                                  arr.push(lists[i])
                           }
                 }
                 return arr
          }

3、訪問元素的樣式

普通的訪問簡單,直接,DOM2級爲style設置一些屬性和方法,好比CSSText,能夠直接訪問到css元素屬性,爲元素應用多項變化最快捷的方式,一次性應用全部的

下面的代碼,分別是設置CSSText   移除removeProperty   length屬性幫忙遍歷

          //訪問元素的樣式
          //DOM2級中規定 CSSText訪問style裏的代碼
          var myDiv=document.getElementById('myDiv')
          myDiv.style.cssText='width:200px;height:200px;background:#fee;color:red;'
          //移除某個css屬性
          myDiv.style.removeProperty('color')
          //遍歷css屬性  length和item的結合  getPropertyValue方法返回的是css屬性值的字符串
          for(var i=0;i<myDiv.style.length;i++){
                   console.log(myDiv.style[i])
          }

這裏補充個非行間樣式的獲取方法,直接獲取非行間樣式是不可讀的,返回「」 

          //獲取非行間樣式
          function getStyle(obj,attr){
                 if(obj.currentStyle){
                         return obj.currentStyle[attr]         //IE是屬性
                 }else{
                         return getComputedStyle(obj,false)[attr]  //其餘爲方法
                 }
          }

注意:若是是CSSText設置的,普通訪問仍是訪問的到的,不然仍是用封裝函數的方法

4、json的遍歷問題

json是一種輕量級的文本數據交換格式,是一種數據格式,支持多種編程語言,具備自我描述性,容易理解

JSON: JavaScript Object Notation(JavaScript 對象表示法)

JSON 是存儲和交換文本信息的語法。相似 XML。

JSON 比 XML 更小、更快,更易解析。

下面是簡單的json格式和遍歷

          var json={
                 'name':'double',
                 'age':34,
                 'sex':'man'
          }
          // 對於json格式,通常用for in 遍歷其中的元素
          for(var i in json){
                console.log(i)     //獲得name age sex  得到的是屬性
          }
          for(var j in json){
                  console.log(json[j])  //獲得double 34 man  得到的是屬性值
          }

嵌套的json遍歷,

          //嵌套的json格式  
          var json={
                 'name':'double',
                 'age':34,
                 'sex':{
                           'man':'one',
                           'woman':'two'
                 }
          }

          for(var i in json['sex']){         //遍歷嵌套的json格式
                  console.log(i)               //屬性
                  console.log(json['sex'][i])  //屬性值
          }

5、關於offsetWidth clientHeight scrollTop相關的總結

明天再續寫

6、瀑布流的思路

好吧,如今正式說一說瀑布流的問題,前面都是我在瀑布流中遇到的重要的知識點

下面總結一下思路

瀑布流,兩步走

第一步,圖片大大小小都對齊,不要溢出,不要塌陷

第二部,滾動鼠標,圖片源源不斷的來,永遠滾不到底

解決第一步

計算頁面中的列數,利用列數求出container的寬度

計算最小圖片的高度和索引,讓次行的第一張圖片到達最小圖片的下面,且使得那一行的高度增長

 

解決第二步

計算鼠標滾動的距離,相比較最後一張圖片的scrollHeight

爲新加載的圖片建立節點,添加到頁面上

 

附上源碼,註釋標的挺清楚的

window.onload=function(){
      waterFall('container','wrap')              //這裏獲取的是整個的wrap,box則不對,由於padding

      var dataInt={'data':[{'src':'50.jpg'},{'src':'51.jpg'},{'src':'52.jpg'}]} //數據庫中的圖片,以json的格式傳入
      window.onscroll=function(){
             if(checkScrollSlide()){
                  var oParent=document.getElementById('container')
                     for(var i=0;i<dataInt.data.length;i++){            //遍歷數據庫中的圖片
                             var oWrap=document.createElement('div')    //添加新節點到原來的HTML中
                        oWrap.className='wrap'
                        oParent.appendChild(oWrap)
                        var oBox=document.createElement('div')
                        oBox.className='box'
                        oWrap.appendChild(oBox)
                        var oImg=document.createElement('img')
                        oImg.src='images/'+dataInt.data[i].src
                        oBox.appendChild(oImg)
                     }
                     waterFall('container','wrap')                      //再次的排序
             }
      }
}
//排序,讓圖片大小一致的排序
function waterFall(parent,child){
      var iParent=document.getElementById(parent)
      var aLists=getByClass(iParent,child)       //得到class爲wrap的圖片塊
      //得到列數
      var pageWidth=document.documentElement.clientWidth||document.body.clientWidth
      var boxWidth=aLists[0].offsetWidth
      cols=Math.floor(pageWidth/boxWidth)       //整個頁面/單個寬
      //根據列數計算contianer寬度
      iParent.style.cssText='width:'+cols*boxWidth+'px;margin:0 auto;'
      //存放每一行的高度
      var colHeight=[]
      for(var i=0;i<aLists.length;i++){
             if(i<cols){
                     colHeight.push(aLists[i].offsetHeight)     //將第一行高度歸入
             }else{                                          //其他行  
                var minH=Math.min.apply(null,colHeight)    //利用Math.min查找數組高度最小
                var index=colHeight.indexOf(minH)          //得到最小的索引
                aLists[i].style.position='absolute'        //由於移動,因此設置position/top/left
                aLists[i].style.top=minH+'px'
                aLists[i].style.left=boxWidth*index+'px'
                colHeight[index]+=aLists[i].offsetHeight   //最小的高度+接下來的高度,使第二小成爲最小,而後依次
             }
      }
}

//獲取class爲box的元素 傳遞兩個參數parent className
function getByClass(parent,name){
     var list=parent.getElementsByTagName('*')
     var arr=[]
     for(var i=0;i<list.length;i++){
           if(list[i].className==name){
                  arr.push(list[i])
           }
     }
     return  arr
}

//檢測瀏覽器是否scroll
function checkScrollSlide(){
    var oParent=document.getElementById('container')
    var aWrap=getByClass(oParent,'wrap')
    var lastWrap=aWrap[aWrap.length-1].offsetTop+Math.floor(aWrap[aWrap.length-1].offsetHeight/2)  //得到最後一張圖片的距離的高度
    var scrollTop=document.documentElement.scrollTop||document.body.scrollTop             //scrollTop
    var clientHeight=document.documentElement.clientHeight||document.body.clientHeight    //clientHeight
      if(lastWrap<scrollTop+clientHeight){                //判斷
             return true  
      }
}

但凡是有錯,直接指出,相互進步,就立刻也過年了,祝你們新年大吉吧!

相關文章
相關標籤/搜索