瀑布流,很常見了,淘寶,網易雲音樂等等都有,實現原理,咱先放着一遍,先將涉及到的知識點拓展開來css
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()方法直接在對象上定義個新屬性或者修改一個對象的現有屬性,並返回這個對象
接受三個參數
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
早期的瀏覽器中不兼容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 }
普通的訪問簡單,直接,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設置的,普通訪問仍是訪問的到的,不然仍是用封裝函數的方法
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]) //屬性值 }
明天再續寫
好吧,如今正式說一說瀑布流的問題,前面都是我在瀑布流中遇到的重要的知識點
下面總結一下思路
瀑布流,兩步走
第一步,圖片大大小小都對齊,不要溢出,不要塌陷
第二部,滾動鼠標,圖片源源不斷的來,永遠滾不到底
解決第一步:
計算頁面中的列數,利用列數求出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 } }
但凡是有錯,直接指出,相互進步,就立刻也過年了,祝你們新年大吉吧!