js:工作中封装好的一些方法(封装,常用功能)

321 阅读10分钟

倒计时

 <script>
    // 时间字符串
    // var targetDate = '2019/11/11 00:00:00'

    // 将字符串格式化为日期对象
    // var d = new Date(targetDate)
    // Mon Nov 11 2019 00:00:00 GMT+0800 (中国标准时间)
    
    // var targetDate = '2019/01/10 00:00:00'

    function countTime(targetStr) {
       // 将时间字符串转换为时间对象
       var targetDate = new Date(targetStr)

       // 当前时间对象
       var currentDate = new Date()
      
       // 毫秒差 = 目标时间 - 当前时间
       var diffTime = targetDate - currentDate
       console.log('diffTime', diffTime)

       // 活动结束时 清除定时器
       if (diffTime <= 0) {
         window.clearInterval(timer)
         return '本次活动已结束 sorry!'
       }

       // 毫秒换算成秒
       diffTime = diffTime / 1000

       var convertDay = 60 * 60 * 24
       var convertHour = 60 * 60
       // 天
       var day = Math.floor(diffTime / convertDay)
      //  console.log(day)

       // 总秒差 / 一天秒数 剩下的余数
       diffTime = diffTime % convertDay
       
       // 小时
       var hour = Math.floor(diffTime / convertHour)
       // 换算成小时后 剩余的秒数
       diffTime = diffTime % convertHour
      //  console.log(hour)

       // 分钟
       var minutes = Math.floor(diffTime / 60)
       // 换算成分钟后 剩余的秒数
       diffTime = diffTime % 60
      //  console.log(minutes)

       // 秒
       var seconds = Math.floor(diffTime)
      //  console.log(seconds)

      // 几天几小时几分几秒
      return `${addZero(day)}${addZero(hour)}小时${addZero(minutes)}${addZero(seconds)}秒`
    }

    var title = document.getElementById('title')
    
    var timer = window.setInterval(function() {
      console.log('定时器')
      title.innerHTML = countTime('2019/01/11 00:00:00')
    }, 1000)

    // 不够10的数 补零
    function addZero(val) {
      return val < 10 ? '0' + val : val
    }
  </script>

任意数求和

    // 任意数求和
    // function sum() {
    //   var total = null;
    //   for (var i = 0; i < arguments.length; i++) {
    //       var num = arguments[i]
    //       if (typeof num === 'number' && !isNaN(num)) {
    //           total += num; // total = total + num
    //     }
    //   }
    // return total;
    // }
    // var a = sum(1, 2, 'abc', NaN, 10)

    // console.log(a);

任意数求和最合理版,最简化版

 function sum() {
      var total = null;
      for (var i = 0; i < arguments.length; i++) {
        // var num = Number(arguments[i]) // '123'
        // var num = parseInt(arguments[i]) // '10px'
        var num = parseFloat(arguments[i]) // '10.123px'
        if (!isNaN(num)) {
          total += num;
        }
      }
      return total;
    }
    var a = sum(1, 2, 10, '123', '10.50px')
    console.log(a)

不重复随机验证码

!<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .code {
      margin: 20px auto 0;
      width: 100px;
      height: 35px;
      line-height: 35px;
      text-align: center;
      border: 1px solid pink;
      border-radius: 5px;
      font-size: 20px;
      cursor: pointer;
      user-select: none;
    }
  </style>
</head>
<body>
  <div class="code" id="codeTitle"></div>
  <script>
    function createCode(n) {
      n = n || 4
      var str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
      var len = str.length
      var codeStr = ''

    while (codeStr.length < n) {
        var ind = Math.round(Math.random() * (len - 1))
        var char = str[ind]

        // 避免验证码中 出现重复的字符
        // 如果在codeStr中还没有这个字符时 我们再拼接
        if (codeStr.indexOf(char) === -1) {
            codeStr += char
        }
      }
            codeTitle.innerHTML = codeStr
    }

    createCode()

    codeTitle.onclick = function () {
            createCode()
    }
  </script>
</body>
</html>

隔行变色封装,用类名(className)动态添加,这样就不会有添加行内样式的问题,如果添加行内背景色的话,鼠标滑过的时候,权重不够,就得在样式后面填上!important.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style> 
            *{
                margin: 0;
                padding: 0;
            }
            ul{
                width: 700px;
                list-style: none;
                margin: 40px auto;
                border:1px solid red;
            }
            li{
                height: 35px;
                line-height: 35px;
                text-align: center;
            }
            .bg0{
                background: purple;
            }
            .bg1{
                background: pink;
            }
            ul li.hover{
                background: yellow;
            }
         </style>
</head>
<body>
    <ul id="list">
        <li>item1</li>
        <li>item2</li>
        <li>item3</li>
        <li>item4</li>
        <li>item5</li>
        <li>item6</li>
        <li>item7</li>
        <li>item8</li>
        <li>item9</li>
        <li>item10</li>
    </ul>
    <script>
    var oUl=document.getElementById('list');
    var oLis=oUl.getElementsByTagName('li');
       function fn(){
            for(var i=0;i<oLis.length;i++){
                oLis[i].className=`bg${i%2}`;
                oLis[i]._ind=i;
                oLis[i].onclick=function(){
                    console.log(this._ind+1);
                }
                oLis[i].onmouseover=function(){
                    this.className='hover';
                }
                oLis[i].onmouseout=function(){
                    this.className=`bg${this._ind%2}`;
                }
            }
       }
       console.log(fn())

       function clear(){
          for(var i=0;i<oLis.length;i++){
            oLis[i].style.backgroundColor='#fff'
        }
    }

    </script>
</body>
</html>

隔行变色封装,由于设置的行内样式,鼠标滑过的时候,需要给鼠标滑过的样式增加权重

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style> 
       *{
           margin: 0;
           padding: 0;
       }
       ul{
           width: 700px;
           list-style: none;
           margin: 40px auto;
           border:1px solid red;
       }
       li{
           height: 35px;
           line-height: 35px;
           text-align: center;
       }
       ul li.hover{
           background: yellow!important;
       }
    </style>
</head>
<body>
    <ul id="list">
        <li>item1</li>
        <li>item2</li>
        <li>item3</li>
        <li>item4</li>
        <li>item5</li>
        <li>item6</li>
        <li>item7</li>
        <li>item8</li>
        <li>item9</li>
        <li>item10</li>
    </ul>
    <script>
    var oUl=document.getElementById('list');
    var oLis=oUl.getElementsByTagName('li');

    //隔行变色 封装起来
    function fn(color1,color2){
       for(var i=0;i<oLis.length;i++){
           oLis[i]._ind=i;
           if(i%2===0){
              oLis[i].style.background=color1;
           }else{
              oLis[i].style.background=color2;
           }
           oLis[i].onclick=function(){
               console.log(this._ind)
           }
           oLis[i].onmouseover=function(){
               this.className='hover';
           }
           oLis[i].onmouseout=function(){
               this.className=`bg${this._ind%2}`;
           }
       }
    }
   console.log(fn('red','green'))//fn里面传颜色值
    //清楚所有的样式背景颜色就清空了
    function clear(){
        for(var i=0;i<oLis.length;i++){
            oLis[i].style.backgroundColor='#fff'
        }
    }
    // clear();

    </script>
</body>
</html>

隔行变色

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    #list {
      width: 600px;
      margin: 10px auto;
      border: 1px solid pink;
      border-radius: 10px;
      overflow: hidden;
    }

    #list li {
      color: #ffffff;
      list-style: none;
      height: 40px;
      line-height: 40px;
      text-align: center;
      font-size: 14px;
      cursor: pointer;
    }

    /* #list li:hover {
      background-color: red;
    } */

    .bg0 {
      background-color: blueviolet;
    }

    .bg1 {
      background-color: blue;
    }

    #list li.hover {
      background-color: red;
      font-size: 20px;
    }
  </style>
</head>
<body>
  <ul id="list">
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 1</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 2</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 3</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 4</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 5</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 6</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 7</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 8</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 9</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 10</li>
  </ul>
  <script>
    var oUl = document.getElementById('list')
    var oLis = document.getElementsByTagName('li')
    
    for (var i = 0; i <  oLis.length; i++) {
        var cur = oLis[i]

        cur.className = 'bg' + (i % 2)

        cur._ind = i

      // 当前事件绑定给哪个元素 里面的this就是哪个元素本身
      // 点击事件
    cur.onclick = function () {
        alert(this._ind)
      }

      // 鼠标滑入事件
    cur.onmouseover = function () {
        this.className = 'hover'
      }

      // 鼠标滑出事件
    cur.onmouseout = function () {
        this.className = 'bg' + (this._ind % 2)
      }
    }
  </script>
</body>
</html>

隔多行变色

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    #list {
      width: 600px;
      margin: 10px auto;
      border: 1px solid pink;
      border-radius: 10px;
      overflow: hidden;
    }

    #list li {
      /* color: #ffffff; */
      list-style: none;
      height: 40px;
      line-height: 40px;
      text-align: center;
      font-size: 14px;
      cursor: pointer;
    }

    /* #list li:hover {
      background-color: red;
    } */

    .bg0 {
      background-color: blueviolet;
    }

    .bg1 {
      background-color: blue;
    }

    .bg2 {
      background-color: rgb(0, 238, 255);
    }

    #list li.hover {
      background-color: red;
      font-size: 20px;
    }
  </style>
</head>

<body>
  <ul id="list">
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 1</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 2</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 3</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 4</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 5</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 6</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 7</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 8</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 9</li>
    <li>腾讯视频-中国领先的在线视频媒体平台,海量高清视频 10</li>
  </ul>
  <script>
    var oUl = document.getElementById('list')
    var oLis = document.getElementsByTagName('li')

    for (var i = 0; i < oLis.length; i++) {
      oLis[i].className = 'bg' + (i % 3)
    }

    // for (var i = 0; i < oLis.length; i++) {
    //      var cur = oLis[i]

    //   switch(i % 3) {
    //      case 0:
    //      cur.style.backgroundColor = 'red'
    //      break
    //      case 1:
    //      cur.style.backgroundColor = 'pink'
    //      break
    //      default:
    //      cur.style.backgroundColor = 'green'
    //   }
    // }
    
    // for (var i = 0; i < oLis.length; i++) {
    //      var cur = oLis[i]

    // if (i % 3 === 0) { // 第一种情况
    //     cur.style.backgroundColor = 'red'
    //   } else if (i % 3 === 1) { // 第二种情况
    //     cur.style.backgroundColor = 'pink'
    //   } else { // 第三种情况
    //     cur.style.backgroundColor = 'green'
    //   }
    // }
  </script>
</body>
</html>

选项卡

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .tab-container {
      width: 306px;
      margin: 20px auto 0;
    }

    .tab-container .tab-header {
      list-style: none;
    }

    .tab-container .tab-header li {
      float: left;
      width: 100px;
      height: 40px;
      line-height: 40px;
      text-align: center;
      border: 1px solid pink;
      cursor: pointer;
    }

    .tab-container .tab-header li.select {
      background-color: orange;
      color: #ffffff;
    }

    .tab-container .tab-panel div {
      display: none;
      width: 304px;
      height: 200px;
      text-align: center;
      line-height: 200px;
      border: 1px solid pink;
      border-top: none;
    }

    .tab-container .tab-panel div.select {
      display: block;
    }
  </style>
</head>
<body>
  <div class="tab-container">
    <!-- 页卡部分  -->
    <ul class="tab-header" id="tab-header">
      <li class="select">电影</li>
      <li>电视剧</li>
      <li>综艺</li>
      <!-- <li>综艺</li>
      <li>综艺</li> -->
    </ul>

    <!-- 面板内容 -->
    <div class="tab-panel" id="tab-panel">
      <div class="select">无双</div>
      <div>知否</div>
      <div>吐槽大会</div>
    </div>
  </div>
  <script>
    // 获取页卡父级元素
    var tabHeader = document.getElementById('tab-header')
    // 通过父级获取到里面li元素(页卡)[li, li, li]
    var tabHeaderList = tabHeader.getElementsByTagName('li')
    
    // 获取面板父级元素
    var tabPanel = document.getElementById('tab-panel')
    // 通过面板父级获取里面div元素(面板)[div, div, div]
    var tabPanelList = tabPanel.getElementsByTagName('div')

    // 根据点击的li 得到的索引n  再去面板集合中找到对应索引位置n的 div 添加类名即可
    // [li, li, li]  0 1 2
    // [div, div, div] 0 1 2 


    // 循环3次 每次都会给当前取出来的li 绑定点击事件
    for (var i = 0; i < tabHeaderList.length; i++) {
      // console.log('循环时', i, tabHeaderList[i])
      
      // 将当前i的值作为索引 存储个当前的li元素对象
      // 给元素对象添加自定义属性
      tabHeaderList[i]._index = i

      // tabHeaderList[0]._index = 0
      // tabHeaderList[1]._index = 1
      // tabHeaderList[2]._index = 2
      

      // 给每个li循环绑定事件(click事件)
      tabHeaderList[i].onclick = function () {
        // 拿到当前点击li身上的索引
         var ind = this._index

        // 先把其他li类名 去掉
      for (var l = 0; l < tabHeaderList.length; l++) {
          tabHeaderList[l].className = ''
          tabPanelList[l].className = ''
        }

        // this 代表的 当前绑定事件的元素对象
        this.className = 'select'
        tabPanelList[ind].className = 'select'
      }
      
    }

    
    // 第一次循环
    // li[0].onclick = function() {
    //    console.log(this) // 第一个li这个元素
    // }

    // // 第二次循环
    // li[1].onclick = function () {
    //   console.log(this) // 第二个li这个元素
    // }

    // // 第三次循环
    // li[2].onclick = function () {
    //   console.log(this) // 第三个li这个元素
    // }

    // li有没有被点击的问题

    // console.dir(tabHeaderList[0])

    // onclick 元素点击事件 (事件处理函数)
    
    // // onclick用来监听当前元素有没有被点击
    // tabHeaderList[0].onclick = function () {
    //   // 当鼠标点击这个元素的时候 就会触发这个函数
    //   // console.log('点点点 00000')
    //   console.log(this) // 第一个li元素对象
    // }

    // tabHeaderList[1].onclick = function () {
    //   // 当鼠标点击这个元素的时候 就会触发这个函数
    //   console.log('点点点 11111')
    //   // console.log(this === tabHeaderList[1])
    // }

    // tabHeaderList[2].onclick = function () {
    //   // 当鼠标点击这个元素的时候 就会触发这个函数
    //   console.log('点点点 22222')
    // }
  </script>
</body>
</html>

选项卡 升级版 自执行函数的那种会产生三个不销毁的作用域,let里面的索引可以直接保存下来

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin:0;padding:0;
        }
        .tab{
            width:306px;
            margin:30px auto 0px;
        }
        .tab .olist{
            list-style: none;
        }
        .tab .olist li{
            width:100px;
            height:30px;
            line-height:30px;
            text-align: center;
            float:left;
            border: 1px solid green;
            cursor: pointer;
        }
        .tab .olist li.select{
            background-color:lightyellow;
            color:blue;
        }
        .tab .odiv div{
            width:304px;
            height:100px;
            line-height: 100px;
            border: 1px solid green;
            border-top:none;
            text-align: center;
            display:none;
        }
        .tab .odiv div.select{
            display:block;
        }
    </style>
</head>
<body>
<div class="tab" id="tabDiv">
    <ul class="olist" id="olis">
        <li class="select">张三</li>
        <li>李四</li>
        <li>王五</li>
    </ul>
    <div class="odiv" id="odi">
        <div class="select">吃瓜</div>
        <div>喝水</div>
        <div>吃火锅</div>
    </div>
</div>
<script>
    var ou = document.getElementById('olis'),
        oli = ou.getElementsByTagName('li');
    var odive = document.getElementById('odi'),
        odiveLi = odive.getElementsByTagName('div');
    // 1.自定义属性,把当前点击的索引存储到每一个li上;
   /* for (i = 0; i<oli.length; i++) {
        oli[i].index = i;
        oli[i].onclick = function(){
            var int = this.index
            for (l = 0;l<oli.length;l++){
                oli[l].className = ''
                odiveLi[l].className = ''
            }
            this.className = 'select'
            odiveLi[int].className = 'select'
        }
    }*/
   //  2.作用域不销毁的特点;
   //  闭包可以存储值;
    for(var i=0;i<oli.length;i++){
        oli[i].onclick = (function (i) {
            // 会形成三个不销毁的作用域,每个作用域存储了一个i值;i 0  1  2;
            return function () {
                for(var j=0;j<oli.length;j++){
                    oli[j].className = ''
                    odiveLi[j].className = ''
                }
                oli[i].className="select";
                odiveLi[i].className="select";
            }
        })(i)
    }

    // 3. let

   /* for(var i=0;i<3;i++){

    }
    console.log(i);// 3
    for(let j=0;j<3;j++){
        // let声明的变量只能在该块级作用域内使用,外界是访问不到的;
        console.log(j);
    }*/

    for(let i=0;i<oli.length;i++){
        oli[i].onclick =  function () {
            // 函数的上一级作用域是for循环形成的每一个块级作用域;在该块级作用域下,保存了每一次循环i的值;
            for (var j = 0; j < oli.length; j++) {
                oli[j].className = ''
                odiveLi[j].className = ''
            }
            oli[i].className = "select";
            odiveLi[i].className = "select";
        }
    }
</script>

</body>
</html>

单例模式封装选项卡

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .container{
            width: 306px;
            margin: 20px auto;
        }
        .tab-header{
            list-style: none;
        }
        .clearfix:after{
            content: '';
            display: block;
            height: 0;
            font-size: 0;
            visibility: hidden;
            clear: both;
        }
        .tab-header li{
            float: left;
            width: 100px;
            height: 40px;
            line-height: 40px;
            text-align: center;
            border: 1px solid red;
        }
        .tab-header li.select{
            background: orange;
        }
        .tab-panel div{
            display: none;
            width: 304px;
            height: 300px;
            line-height: 300px;
            border: 1px solid red;
            text-align: center;
        }
        .tab-panel div.select{
            display: block;
        }
    </style>
</head>
<body>
        <!-- 方式一 -->
       <!-- <div class="container">
           <ul class="tab-header clearfix" id="tab-header">
               <li class="select">电影</li>
               <li>电视剧</li>
               <li>综艺</li>
           </ul>
            <div class="tab-panel" id="tab-panel">
                <div class="select">无间道</div>
                <div>那年花开月正圆</div>
                <div>天天向上</div>
             </div>
        </div> -->

        <!-- 方式二 -->
        <div class="container">
           <ul class="tab-header clearfix" id="tab-header">
               <li class="select">电影</li>
               <li>电视剧</li>
               <li>综艺</li>
           </ul>
            <div class="tab-panel" id="tab-panel">
                <div class="item select">无间道</div>
                <div class="item">那年花开月正圆</div>
                <div class="item">天天向上</div>
             </div>
        </div>
    <script>
  
    var tab={
        oLis:document.getElementsByTagName('li'),
        //oDivs:document.getElementById('tab-panel').getElementsByTagName('div'),   //方式一
        oDivs:document.getElementsByClassName('item'),  //方式二
        fn:function(){
            // 方式一:获取tagName
            // for(var i=0;i<tab.oLis.length;i++){
            //     tab.oLis[i].ind=i;
            //     tab.oLis[i].onclick=function(){
            //         for(var j=0;j<tab.oLis.length;j++){
            //             tab.oLis[j].className='';
            //             tab.oDivs[j].className='';
            //         }
            //         this.className='select';
            //         tab.oDivs[this.ind].className = 'select';
            //     }
            // }
            
            //方式二:通过className获取
            for(var i=0;i<tab.oLis.length;i++){
                tab.oLis[i].ind=i;
                tab.oLis[i].onclick=function(){
                    for(var j=0;j<tab.oLis.length;j++){
                        tab.oLis[j].className='';
                        tab.oDivs[j].classList.remove('select');
                    }
                    this.className='select';
                    tab.oDivs[this.ind].classList.add('select');
                }
            }
        }
    }  
    tab.fn();

    </script>
</body>
<html>

递归求1~100被3整除的和

    // 求 1 ~ 100 能够被3整除的数 的和
    //  function sum(n) {
    //    if (n < 1) {
    //       return 0
    //    }

    //    // 如果当n的值能整除 就用n 累加 下一个值
    //    if (n % 3 === 0) {
    //       return n + sum(n - 1)
    //    }

    //    // 不能够被整除 直接看下一个值
    //       return sum(n - 1)
    //  }
    // console.log(sum(100)) // 1683

递归求1~100既能被3又能被5整除的和

 //递归 求 1 ~ 100 能够被3整除被5整除的数 的和
     function sum(n) {
       if (n < 1) {
         return 0
       }

       // 如果当n的值能整除 就用n 累加 下一个值
       if (n % 15 === 0) {
        return n + sum(n - 1)
       }

       // 不能够被整除 直接看下一个值
       return sum(n - 1)
     }
 //for循环 求 1 ~ 100 能够被3整除被5整除的数 的和
     var total = 0
     for (var i = 1; i <= 100; i++) {
       if (i % 15 === 0) {
         total += i
       }
     }

递归求1~5所有数的和

 // 求1 ~ 5 所有数的和 (从1到5 1 + 2 + 3 + 4 + 5)
    function sum(n) {
      if (n <= 1) {
        return 1
      }
        return n + sum(n - 1)
    }
    
    // sum(3) 1 + 2 + 3
    // R 3 + sum(3 - 1) => 3 + sum(2)
    // R 3 + 2 + sum(2 - 1) => 3 + 2 + sum(1)
    // R 3 + 2 + 1
    // 6

求1~100能够被2整除的数的和

 //递归方式 求 1 ~ 100 能够被2整除的数 的和

    // function sum(n) {
    //   if (n < 1) {
    //       return 0
    //   }

    //   if (n % 2 === 0) {
    //       return n + sum(n - 1)
    //   }

    //       return sum(n - 1)
    // }
    // console.log(sum(100)) // 2550

    // sum(100) n = 100
    // n + sum(n - 1) => 100 + sum(100 - 1)

    // 100 + sum(99) => 100 + sum(99 - 1)
    // 100 + 98 + sum(97) => 100 + 98 + sum(97 - 1)
    // 100 + 98 + 96 + sum(96 - 1)

    // for循环方式 求 1 ~ 100 能够被2整除的数 的和
    // var total = 0
    // for (var i = 1; i <= 100; i++) {
    //   if (i % 2 === 0) {
    //     total += i
    //   }
    // }
    // console.log(total) // 2550

算法:数组去重

  • 双for循环去重
 var arr = [3, 1, 1, 4 , 2 , 4 , 2 , 4 , 2, 1, 1, 3, 3, 3];
    var ary=[];
    var obj={};
    for(var i=0;i<arr.length;i++){
        var cur=arr[i];
        if(!obj[cur]){
            obj[cur]=cur;
            ary.push(cur);
        }
    }
    console.log(ary);

  • indexOf去重
    // indexOf方法数组去重
    // var arr = [3, 1, 1, 2, 2, 2, 1, 1, 3, 3, 3];
    // var ary = [];

    // for(var i=0;i<arr.length;i++){
    //     var cur = arr[i];
    //     if(ary.indexOf(cur)===-1){
    //        ary.push(cur);
    //    }
    // }
    // console.log(ary)
  • 对象方式去重
 var arr = [3, 1, 1, 4 , 2 , 4 , 2 , 4 , 2, 1, 1, 3, 3, 3];
    var ary=[];
    var obj={};
    for(var i=0;i<arr.length;i++){
        var cur=arr[i];
        if(!obj[cur]){
            obj[cur]=cur;
            ary.push(cur);
        }
    }
    console.log(ary);

算法:冒泡排序

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script>
    // 冒泡排序 
    // 排序思想 两两比较 当前项和后一项进行比较 如果当前项大于后一项则交换位置

    // 要比较 arr.length - 1轮

    // 第一轮 需要比较 arr.length - 1 次 

    // 第二轮 需要比较 arr.length - 1 - 1 次 

    // 第三轮 需要比较 arr.length - 1 - 2 次 

    // 第四轮 需要比较 arr.length - 1 - 3 次 


    // i = 0 第一轮 比较 arr.length - 1 - i => ary.length - 1 - 0
    // i = 1 第二轮 比较 arr.length - 1 - i => ary.length - 1 - 1
    // i = 2 第三轮 比较 arr.length - 1 - i => ary.length - 1 - 2
    // i = 3 第四轮 比较 arr.length - 1 - i => ary.length - 1 - 3

    function bubbleSort(ary) {

      // 控制总比较轮数
      for (var i = 0; i < ary.length - 1; i++) { 

        // 控制每轮比较次数
        for (var j = 0; j < ary.length - 1 - i; j++) {
          
          // 如果当前项大于后一项 则交换位置
          if (ary[j] > ary[j + 1]) {
            var temp = ary[j]
            ary[j] = ary[j + 1]
            ary[j + 1] = temp
          }
        }
      }
      return ary
    }
    var arr = [29, 10, 34, 40, 18]
    console.log(bubbleSort(arr)) // [10, 18, 29, 34, 40]

    // var a = [10, 5] // [5, 10]
    // var temp = a[0]
    // a[0] = a[1]
    // a[1] = temp
    // console.log(a)


    bubbleSort(arr)

    // 第一轮 29, 10, 34, 40, 18    第一轮比较了arr.length - 1次

    // i = 0 10, 29, 34, 40, 18
    // i = 1 10, 29, 34, 40, 18
    // i = 2 10, 29, 34, 40, 18
    // i = 3 10, 29, 34, 18, 40

    // 第一轮结束后 第一个最大 40

    // 第二轮 10, 29, 34, 18, 40   第二轮比较了arr.length - 1 - 1(轮数)次
    
    // i = 0 10, 29, 34, 18, 40
    // i = 1 10, 29, 34, 18, 40
    // i = 2 10, 29, 18, 34, 40

    // 第二轮结束后 第二个最大34

    // 第三轮 10, 29, 18, 34, 40   第三轮比较了arr.length - 1 - 2(轮数)次
    
    // i = 0 10, 29, 18, 34, 40
    // i = 1 10, 18, 29, 34, 40

    // 第三轮结束 第三个最大29

    // 第四轮 10, 18, 29, 34, 40   第四轮比较了arr.length - 1 - 3(轮数)次

    // i = 0 10, 18, 29, 34, 40

    // 第四轮结束 第四个最大 18

    // 10, 18, 29, 34, 40
    

    // 比较了 arr.length - 1 轮

    //  第一轮比较了4次
    //  第二轮比较了3次
    //  第三轮比较了2次
    //  第四轮比较了1次

    // 总共arr.length - 1 轮  4轮

    // 第一轮 需要比较 arr.length - 1 次  第一个最大 40 (倒数第一个最大的)

    // 第二轮 需要比较 arr.length - 1 - 1 第二个最大 34 (倒数第二个最大的)

    // 第三轮 需要比较 arr.length - 1 - 2 第三个最大 29 (倒数第三个最大的)

    // 第四轮 需要比较 arr.length - 1 - 3 第四个最大 18 (倒数第四个最大的)

    10

    // 10, 18, 29, 34, 40
  </script>
</body>
</html>

算法:快速排序

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script>
   // 快速排序
   // 思路 得到数组中间项m, 用中间项m和其他项进行比较。
   // 比中间项m小的 放到左边的新数组(left)
   // 比中间项m大的 放到右边的新数组(right)

   // left和right 这两个数组 再按照同样的思路进行 内部比较
   
   
   var arr = [32, 22, 30, 15, 9, 12, 24]
  //  [9, 12]   [32, 22, 30, 24]

   function quickSort(ary) {
    // 结束条件
        if (ary.length <= 1) { // 如果传递进来的数组中只有项 就不要再进行划分了
      return ary
    }

    // 中间项索引
    var mind = Math.floor(ary.length / 2)
    // 得到中间项
    var mid = ary.splice(mind, 1)[0]
    
    // 比中间项小的放在left数组中
    var left = []
    // 比中间项大的放在right数组中
    var right = []
    
    for (var i = 0; i < ary.length; i++) {
        if (ary[i] < mid) {
        left.push(ary[i])
      } else {
        right.push(ary[i])
      }
    }
    return quickSort(left).concat(mid, quickSort(right))
   }
   console.log(quickSort(arr)) // [9, 12, 15, 22, 24, 30, 32]

   // 去中间项索引
   // Math.floor(arr.length / 2)
  </script>
</body>
</html>

插入排序

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
    //插入排序原理:创建一个空数组,将数组中的每一项添加到新数组中,添加时需要判断添加的项在新数组中的位置(最小值、最大值、在中间)
    var ary=[12,23,4,5,67,8,9,8,8];
    var arr=[];

    arr[0]=ary[0];
    for(var i=0;i<ary.length;i++){
        var cur=ary[i];
        //最小值
        if(cur<arr[0]){//取出来的当前项比arr数组中的第一项还小的话就把cur当前项放到arr数组第一项的前面
           arr.unshift(cur);
           continue;
        }
        //最大值
        if(cur>arr[arr.length-1]){
           arr.push(cur);
           continue;
        }
        //中间值
        for(var j=0;j<arr.length;j++){
            if(cur<arr[j]){
               arr.splice(j,0,cur);
               break;
            }
        }
    }
    console.log(ary);//原数组没发生改变
    console.log(arr);//排好序的数组
    </script>
</body>
</html>

获取当前元素的弟弟节点元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <ul id="list">
        <li id="item1">item1</li>
        <li id="item2">item2</li>
        <li id="item3">item3</li>
        <li id="item4">item4</li>
        <li id="item5">item5</li>
        <li id="item6">item6</li>
        <li id="item7">item7</li>
        <li id="item8">item8</li>
        <li id="item9">item9</li>
        <li id="item10">item10</li>
    </ul>
    <script>
        var item10=document.getElementById('list');
        var item1=document.getElementById('item1');
        var item2=document.getElementById('item2');
        var item3=document.getElementById('item3');
        var item4=document.getElementById('item4');
        var item5=document.getElementById('item5');
        var item6=document.getElementById('item6');
        var item7=document.getElementById('item7');
        var item8=document.getElementById('item8');
        var item9=document.getElementById('item9');
        var item10=document.getElementById('item10');
        function getLittleBrother(curEle){
            var nB=curEle.nextSibling;
            while(nB){
                if(nB.nodeType===1){
                   return nB
                }else{
                    nB=nB.nextSibling;
                }
            }   
        }
        console.log(getLittleBrother(item3));
    </script>
</body>
</html>

获取当前元素在兄弟元素节点中的索引

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <ul id="ul">
        <li id="item1">item1</li>
        <li id="item2">item2</li>
        <li id="item3">item3</li>
        <li id="item4">item4</li>
        <li id="item5">item5</li>
        <li id="item6">item6</li>
        <li id="item7">item7</li>
        <li id="item8">item8</li>
        <li id="item9">item9</li>
        <li id="item10">item10</li>
    </ul>
    <script>
        var oUl=document.getElementById('ul');
        var lis= oUl.firstElementChild;
        //console.log(lis);
        var item1=document.getElementById('item1');
        var item2=document.getElementById('item2');
        var item3=document.getElementById('item3');
        var item4=document.getElementById('item4');
        var item5=document.getElementById('item5');
        var item6=document.getElementById('item6');
        var item7=document.getElementById('item7');
        var item8=document.getElementById('item8');
        var item9=document.getElementById('item9');
        var item10=document.getElementById('item10');
        
        function getIndex(curEle){
            var ary=[];
            var pre=curEle.previousSibling;
            while(pre){
                if(pre.nodeType===1){
                   ary.push(pre);
                   pre=pre.previousSibling;
                }else{
                   pre=pre.previousSibling; 
                }
            }
            return ary.length;
        }
        console.log(getIndex(item2))
    </script>
</body>
</html>

获取当前元素的所有哥哥元素节点

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <ul id="ul">
        <li id="item1">item1</li>
        <li id="item2">item2</li>
        <li id="item3">item3</li>
        <li id="item4">item4</li>
        <li id="item5">item5</li>
        <li id="item6">item6</li>
        <li id="item7">item7</li>
        <li id="item8">item8</li>
        <li id="item9">item9</li>
        <li id="item10">item10</li>
    </ul>
    <script>
        var oUl=document.getElementById('ul');
        var lis= oUl.firstElementChild;
        console.log(lis);
        var item1=document.getElementById('item1');
        var item2=document.getElementById('item2');
        var item3=document.getElementById('item3');
        var item4=document.getElementById('item4');
        var item5=document.getElementById('item5');
        var item6=document.getElementById('item6');
        var item7=document.getElementById('item7');
        var item8=document.getElementById('item8');
        var item9=document.getElementById('item9');
        var item10=document.getElementById('item10');
        
        function getAllBrother(curEle){
            var ary=[];
            var pre=curEle.previousSibling;
            while(pre){
                  if(pre.nodeType===1){
                     ary.push(pre);
                     pre=pre.previousSibling; 
                  }else{
                     pre=pre.previousSibling; 
               }
            }
            return ary;
        }
        console.log(getAllBrother(item10));
    </script>
</body>
</html>

封装hasPublicProperty(是不是公有属性)

 var obj={
        name:'xy',
        hobby:'English',
        sex:'female',
        age:'18'
    }
    function hasPubProperty(obj,attr){
    // 1.提前是attr一定是obj的一个属性
    //    if(attr in obj&&!obj.hasOwnProperty(attr)){
    //      return true;
    //    }else{
    //      return false;  
    //    }
    // 2.排除私有属性
    // 判断条件?条件成立时执行的代码:条件不成立时执行的代码   
    return attr in obj&&!obj.hasOwnProperty(attr)?true:false;
    }
    // 检测对象的共有属性
    console.log(hasPubProperty(obj,'age'));//返回false,通过obj对象,给对象里面添加的属性,都是obj的私有属性

js原生购物车封装

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>购物车</title>
    <style>
        .container {
            width: 140px;
            margin: 50px auto;
            border: 1px solid #ccc;
            border-radius: 10px;
            background: #eee;
            padding: 10px;
            font-size: 16px;
            line-height: 28px;
        }

        .tit {
            border-bottom: 1px solid #ccc;
        }

        .container div {
            padding-left: 40px;
            position: relative;
        }

        .container div:before {
            content: "";
            position: absolute;
            width: 14px;
            height: 14px;
            border: 1px solid #999;
            left: 0;
            top: 50%;
            margin-top: -8px;
        }

        .container div.on:before {
            content: "";
            position: absolute;
            width: 14px;
            height: 14px;
            border: 1px solid #999;
            background: red;
            left: 0;
            top: 50%;
            margin-top: -8px;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="tit" id="all">
            <span>全选</span>
        </div>
        <div class="item">选项(一)</div>
        <div class="item">选项(二)</div>
        <div class="item">选项(三)</div>
        <div class="item">选项(四)</div>
        <div class="item">选项(五)</div>
        <div class="item">选项(六)</div>
        <div class="item">选项(七)</div>
        <div class="item">选项(八)</div>
        <div class="item">选项(九)</div>
        <div class="item">选项(十)</div>
        <p id="btn">反选</p>
    </div>

    <script>
        // 获取所有item
        var oItems = document.getElementsByClassName("item");
        // 获取全选按钮
        var oAll = document.getElementById("all");
        // 获取反选按钮
        var oBtn = document.getElementById("btn");

        for (var i = 0; i < oItems.length; i++) {
            oItems[i].flag = -1; // -1 没选中, 1选中
            oItems[i].onclick = function () {
                this.flag *= -1; // this.flag = this.flag * -1
                if (this.flag === -1) {
                    this.classList.remove("on");
                } else {
                    this.classList.add("on");
                }
            }
        }

        // 给全选添加事件
        // 点击全部选中,再次点击全部取消选中
        oAll.flag = -1; // -1 没选中, 1选中
        oAll.onclick = function () {
            this.flag *= -1; // this.flag = this.flag * -1

            if (this.flag === -1) {
                this.classList.remove("on");
            } else {
                this.classList.add("on");
            }

            // 遍历每一项item,让item的flag与全选按钮的flag保持一至;
            for (var i = 0; i < oItems.length; i++) {
                oItems[i].flag = this.flag;
                if (oItems[i].flag === -1) {
                    oItems[i].classList.remove("on");
                } else {
                    oItems[i].classList.add("on");
                }
            }
        }

        // 反选
        oBtn.onclick = function () {
            for (var i = 0; i < oItems.length; i++) {
                oItems[i].flag *= -1;
                if (oItems[i].flag === -1) {
                    oItems[i].classList.remove("on");
                } else {
                    oItems[i].classList.add("on");
                }
            }
        };
</body>
</html>
</body>
</html>

商品排序

### html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>5.index.html</title>
    <link rel="stylesheet" href="css/5.reset.css">
    <link rel="stylesheet" href="css/5.css">
</head>
<body>
<div class="container">
    <div class="tab">
        <div class="label">排序</div>
        <ul id="tab">
            <li>上架时间</li>
            <li>价格</li>
            <li>热度</li>
        </ul>
    </div>

    <ul class="goodsList" id="goodsList">

    </ul>
</div>
<script src="js/5.js"></script>
</body>
</html>

### css

.container{
    width: 1200px;
    margin: auto;
}
.tab{
    background: yellow;
    padding: 12px 30px;
    line-height: 38px;
    overflow: hidden;
    margin-bottom: 30px;
}
.goodsList li{
    width: 200px;
}
.label{
    float: left;
    padding-right: 30px;
}
#tab{
    float: left;
    overflow: hidden;
}
#tab li{
    float: left;
    padding: 0 30px;
    position: relative;
}
#tab li:before{
    display: block;
    content: '';
    width: 0;
    height: 0;
    border: 8px solid transparent;
    border-bottom:8px solid #333333;
    position: absolute;
    right: 0;
    top: 0;
}
#tab li.up:before{
    display: block;
    content: '';
    width: 0;
    height: 0;
    border: 8px solid transparent;
    border-bottom:8px solid red;
    position: absolute;
    right: 0;
    top: 0;
}
#tab li:after{
    display: block;
    content: '';
    width: 0;
    height: 0;
    border: 8px solid transparent;
    border-top:8px solid #333333;
    position: absolute;
    right: 0;
    bottom: 0;
}
#tab li.down:after{
    display: block;
    content: '';
    width: 0;
    height: 0;
    border: 8px solid transparent;
    border-top:8px solid red;
    position: absolute;
    right: 0;
    bottom: 0;
}
.goodsList li{
    float: left;
    width: 200px;
    padding: 0 20px;
}
.goodsList li p{
    line-height: 28px;
    padding-top: 10px;

    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

### rest.css

html,body,div,ul,li,img,p{
    margin: 0;
    padding: 0;
}
body{
    background: #eeeeee;
}
ul{
    list-style: none;
}
img{
    width: 100%;//img是继承li的宽度
    display: block;
}

### json文件

[
  {
    "id": 1,
    "title": "HUAWEI全网通版(亮黑色)",
    "price": 499,
    "time": "2017-03-15",
    "hot": 198,
    "img": "img/1.jpg"
  },
  {
    "id": 2,
    "title": "HUAWEI(曜石黑)",
    "price": 129,
    "time": "2017-02-08",
    "hot": 25,
    "img": "img/2.jpg"
  },
  {
    "id": 3,
    "title": "华为畅享7(香槟金)",
    "price": 895,
    "time": "2017-01-25",
    "hot": 568,
    "img": "img/3.jpg"
  },
  {
    "id": 4,
    "title": "HUAWEI全网通版(曜石黑)",
    "price": 1895,
    "time": "2016-12-30",
    "hot": 20000,
    "img": "img/4.jpg"
  },
  {
    "id": 5,
    "title": "HUAWEI全网通版(玫瑰金)",
    "price": 3587,
    "time": "2016-01-30",
    "hot": 1032654,
    "img": "img/5.jpg"
  },
  {
    "id": 6,
    "title": "华为畅享7(香槟金)",
    "price": 992,
    "time": "2018-01-01",
    "hot": 1,
    "img": "img/6.jpg"
  },
  {
    "id": 7,
    "title": "HUAWEI全网通版(樱语粉)",
    "price": 564,
    "time": "2017-02-19",
    "hot": 400,
    "img": "img/7.jpg"
  },
  {
    "id": 8,
    "title": "HUAWEI全网通版(曜石黑)",
    "price": 420,
    "time": "2017-01-25",
    "hot": 240,
    "img": "img/8.jpg"
  },
  {
    "id": 9,
    "title": "HUAWEI P10(钻雕金)",
    "price": 12,
    "time": "2014-01-01",
    "hot": 12345678,
    "img": "img/9.jpg"
  },
  {
    "id": 10,
    "title": "HUAWEI全网通版(曜石黑)",
    "price": 420,
    "time": "2017-01-25",
    "hot": 240,
    "img": "img/8.jpg"
  }
]

### js

;(function(){
    var data=null;

    //获取选项
    var oTab=document.getElementById('tab');
    var oTabs=oTab.getElementsByTagName('li');

    //获取页面展示数据
    var goodsList=document.getElementById('goodsList');
    var goodsListLi=goodsList.getElementsByTagName('li');

    //ajax请求数据
    //1.创建一个ajax对象
    var xhr=new XMLHttpRequest;
    //2.从json中获取数据
    xhr.open('GET','./json/product.json',false);
    //3.判断是否成功获取数据
    xhr.onreadystatechange=function(){
        if(xhr.readyState===4&&xhr.status===200){
          data=JSON.parse(xhr.responseText);//正常返回的是JSON格式的字符串,但是我们要用JSON格式的字符串,所以JSON.parse()一下
        }
    };
    xhr.send(null);
    console.log(data);//返回JSON格式的对象
    
    //绑定数据,渲染数据
    var str = "";
    for (var i = 0; i < data.length; i++) {
        console.log(data);
        var item = data[i];

        str+=`<li data-time="${item.time}" data-price="${item.price}" data-hot="${item.hot}">
                  <img src="${item.img}" alt="">
                  <p>${item.title}</p>
                  <p>上架时间: ${item.time}</p>
                  <p>价格: ${item.price}</p>
                  <p>热度: ${item.hot}</p>
</li>`
    }
    goodsList.innerHTML = str;

    for(var i=0;i<oTabs.length;i++){
        var tabLi=oTabs[i];

        tabLi.flag=-1;

        tabLi.ind=i;
        //console.log(i);//索引是0 1 2
        //自定义属性flag
        tabLi.onclick=function(){
            //console.log(i);索引已经变成3了,要在onclick外面存个索引
            //console.log(this);点哪个哪个就是oTabs中的哪个li
            this.flag*=-1;//点击的时候,tabLi.flag为正1,就让它按从小到大排序

            //切换选项
            switchTab.call(this);

            // 排序
            sortGoods.call(this);
        }
    }

    // 给商品排序
    function sortGoods(){
        // oGoods.sort();
        oGoods = Array.prototype.slice.call(goodsListLi);

        var that = this;

        oGoods.sort(function(a, b){
            // that.index; // 0,上架时间,1价格; 2、热度
            // a,b是数组的相邻两项
            var aProp = null;
            var bProp = null;

            if(that.ind == 0){
                aProp = a.getAttribute("data-time").replace(/-/g, "");
                bProp = b.getAttribute("data-time").replace(/-/g, "");
            }else if(that.ind == 1){
                aProp = a.getAttribute("data-price");
                bProp = b.getAttribute("data-price");
            }else{
                aProp = a.getAttribute("data-hot");
                bProp = b.getAttribute("data-hot");
            }

            return that.flag*(aProp-bProp);
        });

        // 将排好序的元素渲染到页面上
        var oFragment = document.createDocumentFragment();
        for(var i = 0; i < oGoods.length; i++){
            var item = oGoods[i];
            // dom映射
            oFragment.appendChild(item)
        }
        goodsList.appendChild(oFragment);
    };

    function switchTab() {
        // 先要清除所有的li上的三角的样式
        for (var j = 0; j < oTabs.length; j++) {
            if (oTabs[j] !== this) {
                oTabs[j].classList.remove("up");
                oTabs[j].classList.remove("down");
                oTabs[j].flag = -1;
            }
        }

        // 然后再根据this.flag给this添加三角的样式
        if (this.flag === 1) {//1
            this.classList.add("up");
            this.classList.remove("down");
        } else {//-1
            this.classList.add("down");
            this.classList.remove("up");
        }
    };
})();

封装类数组转数组(toArray)

  function toArray(likeAry){
        var  ary = [];
        for(var i=0;i<likeAry.length;i++){
            ary.push(likeAry[i]);
        }
    }

获取上一个哥哥节点(完整版第一种方法)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>1.封装上一个哥哥元素节点的第一种方法</title>
</head>
<body>
<ul>
    <li id="item1"></li>
    <li id="item2"></li>
    <li id="item3"></li>
    <li id="item4"></li>
    <li id="item5"></li>
    <li id="item6"></li>
    <li id="item7"></li>
    <li id="item8"></li>
</ul>
<script src="jquery-1.11.3.js"></script>
<script>
    var item=$('li');
    console.log(item);
    var item1=$('li')[0];
    console.log(item1);
    var item2=$('li')[1];
    console.log(item2);
    var item3=$('li')[2];
    console.log(item3);
    var item4=$('li')[3];
    console.log(item4);
    var item5=$('li')[4];
    console.log(item5);
    var item6=$('li')[5];
    console.log(item6);
    var item7=$('li')[6];
    console.log(item7);
    var item8=$('li')[7];
    console.log(item8);
    function getBrother(curEle){
             if('previousElementSibling' in curEle){
                 return curEle.previousElementSibling;
             }
             var pre=curEle.previousSibling;
             while(pre){
                 if(pre.nodeType===1){
                    return pre;
                 }else{
                    pre=pre.previousSibling;
                 }
             }
             return null;//如果没找到的想要的元素为空格
    }
    console.log(getBrother(item8));//7
    console.log(getBrother(item7));//6
    console.log(getBrother(item6));//5
    console.log(getBrother(item5));//4
    console.log(getBrother(item4));//3
    console.log(getBrother(item3));//2
    console.log(getBrother(item2));//1
    console.log(getBrother(item1));//第一个li的上一个哥哥元素节点不存在
</script>
</body>
</html>

封装上一个哥哥元素节点(完整版:第二种方法)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2.封装上一个哥哥元素节点的第二种方法</title>
</head>
<body>
<ul>
    <li id="item1"></li>
    <li id="item2"></li>
    <li id="item3"></li>
    <li id="item4"></li>
    <li id="item5"></li>
    <li id="item6"></li>
    <li id="item7"></li>
    <li id="item8"></li>
</ul>
<script src="jquery-1.11.3.js"></script>
<script>
    var item=$('li');
    console.log(item);
    var item1=$('li')[0];
    console.log(item1);
    var item2=$('li')[1];
    console.log(item2);
    var item3=$('li')[2];
    console.log(item3);
    var item4=$('li')[3];
    console.log(item4);
    var item5=$('li')[4];
    console.log(item5);
    var item6=$('li')[5];
    console.log(item6);
    var item7=$('li')[6];
    console.log(item7);
    var item8=$('li')[7];
    console.log(item8);
    function getBrother(curEle){
        if(curEle.previousElementSibling){
           return curEle.previousElementSibling;
        }
        var pre=curEle.previousElementSibling;
        while(pre){
              if(pre.nodeType===1){
                 return pre;
              }else{
                 pre=pre.previousSibling;
              }
        }
        return null;//如果获取不到上一个哥哥元素节点元素的话,结果为空
    }
    console.log(getBrother(item8));
    console.log(getBrother(item7));
    console.log(getBrother(item6));
    console.log(getBrother(item5));
    console.log(getBrother(item4));
    console.log(getBrother(item3));
    console.log(getBrother(item2));
    console.log(getBrother(item1));
</script>
</body>
</html>

封装当前元素在兄弟元素中的索引(第一种方法)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>1.封装当前元素在兄弟元素中的索引的多种办法</title>
</head>
<body>
<ul>
    <li id="item1"></li>
    <li id="item2"></li>
    <li id="item3"></li>
    <li id="item4"></li>
    <li id="item5"></li>
    <li id="item6"></li>
    <li id="item7"></li><li id="item8"></li>
</ul>
<script src="jquery-1.11.3.js"></script>
<script>
//    var ul=$('ul')[0];
//    console.log(ul);
    var item=$('li');
//    console.log(item);
    var item1=$('li')[0];
//    console.log(item1);
    var item2=$('li')[1];
//    console.log(item2);
    var item3=$('li')[2];
//    console.log(item3);
    var item4=$('li')[3];
//    console.log(item4);
    var item5=$('li')[4];
//    console.log(item5);
    var item6=$('li')[5];
//    console.log(item6);
    var item7=$('li')[6];
//    console.log(item7);
    var item8=$('li')[7];
//    console.log(item8);

    function index(curEle){
          var allEle=curEle.parentNode.children;
          //console.log(allEle);//类数组
          allEle=[...allEle];//类数组转换成数组了
          //console.log(allEle);//数组
          for(var i=0;i<allEle.length;i++){
              var val=allEle.indexOf(curEle);
              return val;
          }
    }
    console.log(index(item8));//7
    console.log(index(item7));//6
    console.log(index(item6));//5
    console.log(index(item5));//4
    console.log(index(item4));//3
    console.log(index(item3));//2
    console.log(index(item2));//1
    console.log(index(item1));//0
</script>
</body>
</html>

封装当前元素在兄弟元素中的索引(第二种方法):查找上一个哥哥元素节点,用i累加封装当前在兄弟元素中的索引

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
    <li id="item1"></li>
    <li id="item2"></li>
    <li id="item3"></li>
    <li id="item4"></li>
    <li id="item5"></li>
    <li id="item6"></li>
    <li id="item7"></li>
    <li id="item8"></li>
</ul>
<script src="./jquery-1.11.3.js"></script>
<script>
    //    var ul=$('ul')[0];
    //    console.log(ul);
    var item=$('li');
    //    console.log(item);
    var item1=$('li')[0];
    //    console.log(item1);
    var item2=$('li')[1];
    //    console.log(item2);
    var item3=$('li')[2];
    //    console.log(item3);
    var item4=$('li')[3];
    //    console.log(item4);
    var item5=$('li')[4];
    //    console.log(item5);
    var item6=$('li')[5];
    //    console.log(item6);
    var item7=$('li')[6];
    //    console.log(item7);
    var item8=$('li')[7];
    //    console.log(item8);

    function index(curEle) {
        var pre = curEle.previousSibling;//是元素节点
        var i=0;//
        while(pre){//是元素
            if(pre.nodeType===1){
                i++;// 1
            }
            pre=pre.previousSibling;
        }
        return i;
    }
    console.log(index(item8));//7
    console.log(index(item7));//6,传第7项的话,就相当于找它前面所有的li元素,要循环6(索引是0-5,到5的时候i++变为6)次,所以索引是6
    console.log(index(item6));//5
</script>
</body>
</html>

animate封装

### linear(匀速运动的公式)

function linear(t,b,c,d){ return t/d*c+b;//t是走过的时间、d是总时间、c是总路程(灵活的有可能是opacity的变化的值)、b是元素的初始位置 }

3.animate动画的封装
``` ### utils.js ``` var utils = (function () { function offset(curEle) { var l = curEle.offsetLeft; var t = curEle.offsetTop; var p = curEle.offsetParent; while(p.nodeName !=="BODY"){ l+=p.offsetLeft +p.clientLeft; t+=p.offsetTop+p.clientTop; p = p.offsetParent; } return { left:l,top:t } }; function getCss(curEle,attr) { var val; if("getComputedStyle" in window){ // 先判断是否支持getComputedStyle; val = getComputedStyle(curEle)[attr]; }else{ val = curEle.currentStyle[attr]; } // 去单位 var reg = /^(width|height|margin|padding|left|top|right|bottom|fontZise|opacity)$/; // 校验当前属性是否带有单位 if(reg.test(attr)){ // 判断是否为空; if(!isNaN(parseFloat(val))){ val = parseFloat(val); } } return val; } // setCss : 每执行一次,都会设置元素一个属性样式; function setCss(curEle,attr,val) { var reg = /^(width|height|top|left|right|bottom|padding|margin)$/; if(reg.test(attr)){ if(typeof val==="number"){ val = val + "px"; } } curEle.style[attr]=val;// 设置行内样式; } function setGroupCss(curEle,obj) { // 遍历obj;调用封装的setCss,设置元素的单个样式; for(var key in obj){ setCss(curEle,key,obj[key]) } } function css(...arg) {// 在函数定义的括号中,... 是剩余运算符;将所有的实参放入到一个数组中; // if(arg.length===3){ // [oBox,"height",300] setCss(...arg); }else if(arg.length===2){ if(toString.call(arg[1])==="[object Object]"){ setGroupCss(...arg) }else{ return getCss(...arg) } } } function win(attr,val) { // 如果是两个实参,那么一定是设置;如果是一个实参,是获取; if(val===undefined){ return document.documentElement[attr] || document.body[attr]; } document.documentElement[attr] = val; document.body[attr] = val;
}
return {
    offset:offset,
    getCss:getCss,
    setCss:setCss,
    setGroupCss:setGroupCss,
    css:css,
    win:win
}

})(); // 单例模式 /* var utils= { offset:function offset(curEle) { var l = curEle.offsetLeft; var t = curEle.offsetTop; var p = curEle.offsetParent; while(p.nodeName !=="BODY"){ l+=p.offsetLeft +p.clientLeft; t+=p.offsetTop+p.clientTop; p = p.offsetParent; } return { left:l,top:t } } }*/

### animate.js

(function () { // 运动方式 var zhufengEffect = { // 匀速运动公式 Linear: function (t, b, c, d) { return t/d * c + b; }, //指数衰减的反弹缓动 Bounce: { easeIn: function(t, b, c, d) { return c - zhufengEffect.Bounce.easeOut(d - t, 0, c, d) + b; }, easeOut: function(t, b, c, d) { if ((t /= d) < (1 / 2.75)) { return c * (7.5625 * t * t) + b; } else if (t < (2 / 2.75)) { return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b; } else if (t < (2.5 / 2.75)) { return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b; } else { return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b; } }, easeInOut: function(t, b, c, d) { if (t < d / 2) { return zhufengEffect.Bounce.easeIn(t * 2, 0, c, d) * .5 + b; } return zhufengEffect.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b; } }, //二次方的缓动 Quad: { easeIn: function(t, b, c, d) { return c * (t /= d) * t + b; }, easeOut: function(t, b, c, d) { return -c * (t /= d) * (t - 2) + b; }, easeInOut: function(t, b, c, d) { if ((t /= d / 2) < 1) { return c / 2 * t * t + b; } return -c / 2 * ((--t) * (t - 2) - 1) + b; } }, //三次方的缓动 Cubic: { easeIn: function(t, b, c, d) { return c * (t /= d) * t * t + b; }, easeOut: function(t, b, c, d) { return c * ((t = t / d - 1) * t * t + 1) + b; }, easeInOut: function(t, b, c, d) { if ((t /= d / 2) < 1) { return c / 2 * t * t * t + b; } return c / 2 * ((t -= 2) * t * t + 2) + b; } }, //四次方的缓动 Quart: { easeIn: function(t, b, c, d) { return c * (t /= d) * t * t * t + b; }, easeOut: function(t, b, c, d) { return -c * ((t = t / d - 1) * t * t * t - 1) + b; }, easeInOut: function(t, b, c, d) { if ((t /= d / 2) < 1) { return c / 2 * t * t * t * t + b; } return -c / 2 * ((t -= 2) * t * t * t - 2) + b; } }, //五次方的缓动 Quint: { easeIn: function(t, b, c, d) { return c * (t /= d) * t * t * t * t + b; }, easeOut: function(t, b, c, d) { return c * ((t = t / d - 1) * t * t * t * t + 1) + b; }, easeInOut: function(t, b, c, d) { if ((t /= d / 2) < 1) { return c / 2 * t * t * t * t * t + b; } return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; } }, //正弦曲线的缓动 Sine: { easeIn: function(t, b, c, d) { return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; }, easeOut: function(t, b, c, d) { return c * Math.sin(t / d * (Math.PI / 2)) + b; }, easeInOut: function(t, b, c, d) { return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; } }, //指数曲线的缓动 Expo: { easeIn: function(t, b, c, d) { return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b; }, easeOut: function(t, b, c, d) { return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; }, easeInOut: function(t, b, c, d) { if (t == 0) return b; if (t == d) return b + c; if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b; return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b; } }, //圆形曲线的缓动 Circ: { easeIn: function(t, b, c, d) { return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; }, easeOut: function(t, b, c, d) { return c * Math.sqrt(1 - (t = t / d - 1) * t) + b; }, easeInOut: function(t, b, c, d) { if ((t /= d / 2) < 1) { return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b; } return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; } }, //超过范围的三次方缓动 Back: { easeIn: function(t, b, c, d, s) { if (s == undefined) s = 1.70158; return c * (t /= d) * t * ((s + 1) * t - s) + b; }, easeOut: function(t, b, c, d, s) { if (s == undefined) s = 1.70158; return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; }, easeInOut: function(t, b, c, d, s) { if (s == undefined) s = 1.70158; if ((t /= d / 2) < 1) { return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b; } return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; } }, //指数衰减的正弦曲线缓动 Elastic: { easeIn: function(t, b, c, d, a, p) { if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3; var s; !a || a < Math.abs(c) ? (a = c, s = p / 4) : s = p / (2 * Math.PI) * Math.asin(c / a); return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; }, easeOut: function(t, b, c, d, a, p) { if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3; var s; !a || a < Math.abs(c) ? (a = c, s = p / 4) : s = p / (2 * Math.PI) * Math.asin(c / a); return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b); }, easeInOut: function(t, b, c, d, a, p) { if (t == 0) return b; if ((t /= d / 2) == 2) return b + c; if (!p) p = d * (.3 * 1.5); var s; !a || a < Math.abs(c) ? (a = c, s = p / 4) : s = p / (2 * Math.PI) * Math.asin(c / a); if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b; } }

};

/**
 *
 * @param curEle 当前执行动画的元素
 * @param target 目标值对象 {left:500,top:300}
 * @param duration 总过渡时间 2000ms
 */
// effect 指定运动方式 传参
// 传一个数字
// 传一个数组 ['Quad','easeInOut']
function move(curEle, target, duration,effect, callBack) {
    // 默认运动方式
    var tempEffect = zhufengEffect.Linear;

    // 判断effect 如果是个数字
    if(typeof effect === "number") {
        switch (effect) {
            case 0:
                tempEffect = zhufengEffect.Linear;
                break;
            case 1:
                tempEffect = zhufengEffect.Quad.easeInOut;
                break;
            case 2:
                tempEffect = zhufengEffect.Bounce.easeIn;
                break;
            case 3:
                tempEffect = zhufengEffect.Cubic.easeInOut;
                break;
        }
    } else if(effect instanceof Array) {
        //如果以数组方式指定远动方式 ['Quad','easeInOut']
        tempEffect = effect.length === 2? zhufengEffect[effect[0]][effect[1]]:zhufengEffect[effect[0]];
    } else if(typeof effect === "function") {
        callBack = effect;
    }
    // 执行本次动画之前 清除上次动画
    curEle.zfTimer? clearInterval(curEle.zfTimer) : null;

    var begin = {}; // 存储元素执行动画前 相应属性初始状态
    var change = {}; // 存储元素执行动画 相应属性状态变化值
    for(var key in target) {
        // target  对象 目标位置
        if(target.hasOwnProperty(key)) {
            // begin {'left': 'left初始值'}
            begin[key] =Number(utils.css(curEle, key));// 获取属性初始值,在obj新增key属性,初始值赋值给begin的key的属性值
            // change {'left': 'left变化值'}
            console.log(begin[key]);//获取的透明度的
            change[key] =target[key] - begin[key]// key属性要变化的值,并且放在change对象中
            console.log(change[key]);
        }
    }
    // console.log(begin);
    // console.log(change);

    var time = null; // 记录当前时间
    curEle.zfTimer = setInterval(function () {
        time += 10;
        if(time >= duration) { // 结束条件
            // target:{left: 500, top: 300}
            utils.css(curEle,target); // 确保是目标状态
            clearInterval(curEle.zfTimer); //结束动画
            typeof callBack ==="function"? callBack.call(curEle) : null;
            return;
        }
        // 计算出当前时间 元素相应属性 的状态
        // target 有多少个属性 zfEffect.Linear 执行多少次 并且把相应属性的参数传递进去 计算出 当前状态
        // 第一次的时候 key 是left  第二次的时候key 是 top
        for(var key in target) {
           if(target.hasOwnProperty(key)) {
               // 计算出 当前时间time 元素相应属性 所处状态
               var curPos = tempEffect(time,begin[key],change[key], duration);
               // 将当前元素 相应属性 设置为 当前计算出来的状态curPos
               utils.css(curEle, key, curPos);
           }
        }
    }, 10);
}

// 把函数放进全局下的zfAnimate window.zfAnimate = move; })();