• 瀑布流知识的延伸


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

    一、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  
          }
    }

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

  • 相关阅读:
    小程序自动更新版本
    js深浅拷贝理解
    小程序模仿toast效果
    小程序button默认border
    Java利用POI 读取Excel行列数,坑
    Nginx 极简入门教程
    七、SpringBoot整合持久化层,配置多数据源(SpringBoot系列)
    六、SpringBoot整合aop(SpringBoot系列)
    五、SpringBoot随系统启动任务的方式(SpringBoot系列)
    四、SpringBoot通过CORS解决跨域问题(SpringBoot系列)
  • 原文地址:https://www.cnblogs.com/iDouble/p/8449072.html
Copyright © 2020-2023  润新知