zoukankan      html  css  js  c++  java
  • 瀑布流知识的延伸

    瀑布流,很常见了,淘宝,网易云音乐等等都有,实现原理,咱先放着一遍,先将涉及到的知识点拓展开来

    一、Math的方法

    Math求最小值、最大值,

    对于一般的数字直接求,Math.min  Math.max 

    但是求数组呢,一个方法,三种形式,js高程书中利用apply的回调函数,将this指向window,直接将所求的数组作为参数传入

    封装函数的方法

    封装一个getMin的函数直接调用获得

              var numbers=[23,435,45,34]
              function getMin(arr){               //封装一个方法
                    return min=Math.min.apply(null,arr)  //利用apply的回调函数,将作用域this指向window,将数组作为参数传入
              }
              console.log(getMin(numbers))

    原型对象的方法一

    学过原型对象,直接在Array的原型上添加min方法,让Array拥有min的方法,不推荐,产品化的程序不推荐在基本包装类型添加多余的方法

              Array.prototype.min=function(array){     //直接在原型上添加,传递参数
                   return Math.min.apply(null,array)
              }
              alert(numbers.min(numbers))

    原型对象的方法二

    利用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

    二、获取指定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
              }

    三、访问元素的样式

    普通的访问简单,直接,DOM2级为style设置一些属性和方法,比如CSSText,可以直接访问到css元素属性,为元素应用多项变化最快捷的方式,一次性应用所有的

    下面的代码,分别是设置CSSText   移除removeProperty   length属性帮忙遍历

              //访问元素的样式
              //DOM2级中规定 CSSText访问style里的代码
              var myDiv=document.getElementById('myDiv')
              myDiv.style.cssText='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是一种轻量级的文本数据交换格式,是一种数据格式,支持多种编程语言,具有自我描述性,容易理解

    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])  //属性值
              }

    五、关于offsetWidth clientHeight scrollTop相关的总结

    明天再续写

    六、瀑布流的思路

    好吧,现在正式说一说瀑布流的问题,前面都是我在瀑布流中遇到的重要的知识点

    下面总结一下思路

    瀑布流,两步走

    第一步,图片大大小小都对齐,不要溢出,不要塌陷

    第二部,滚动鼠标,图片源源不断的来,永远滚不到底

    解决第一步

    计算页面中的列数,利用列数求出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=''+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  
          }
    }

    但凡有错,直接指出,相互进步,就马上也过年了,祝大家新年大吉吧!

  • 相关阅读:
    poj 3280 Cheapest Palindrome(区间DP)
    POJ 2392 Space Elevator(多重背包)
    HDU 1285 定比赛名次(拓扑排序)
    HDU 2680 Choose the best route(最短路)
    hdu 2899 Strange fuction (三分)
    HDU 4540 威威猫系列故事――打地鼠(DP)
    HDU 3485 Count 101(递推)
    POJ 1315 Don't Get Rooked(dfs)
    脱离eclipse,手动写一个servlet
    解析xml,几种方式
  • 原文地址:https://www.cnblogs.com/iDouble/p/8449072.html
Copyright © 2011-2022 走看看