js高级实例

面向对象tab栏切换

//tab.css
* {
  margin: 0;
  padding: 0;
}

li {
  list-style-type: none;
}

main {
  width: 960px;
  height: 500px;
  border-radius: 10px;
  margin: 50px auto;
}

main h4 {
  height: 100px;
  line-height: 100px;
  text-align: center;
}

.tab_box {
  width: 900px;
  margin: 0 auto;
  height: 400px;
  border: 1px solid lightsalmon;
  position: relative;
}

.tab_nav ul {
  overflow: hidden;
}

.tab_nav ul li {
  float: left;
  width: 100px;
  height: 50px;
  line-height: 50px;
  text-align: center;
  border-right: 1px solid #ccc;
  position: relative;
}

.tab_nav ul li.nav_active {
  border-bottom: 2px solid #fff;
  z-index: 9;
}

.tab_nav ul li span:last-child {
  position: absolute;
  user-select: none;
  font-size: 12px;
  top: -18px;
  right: 0;
  display: inline-block;
  height: 20px;
}

.tab_nav input {
  width: 80%;
  height: 60%;
  outline-width: 0;
  border: 1px solid #ccc;
}

.tab_close {
  display: block;

}

.tab_add {
  position: absolute;
  top: 0;
  right: 0;
}

.tab_add span {
  display: block;
  width: 20px;
  height: 20px;
  line-height: 20px;
  text-align: center;
  border: 1px solid #ccc;
  float: right;
  margin: 10px;
  /* 控制用户能否选中文本 */
  user-select: none;
}

.tab_con {
  width: 100%;
  height: 300px;
  position: absolute;
  padding: 30px;
  top: 50px;
  left: 0px;
  box-sizing: border-box;
  border-top: 1px solid #ccc;
}

.tab_con section,
.tab_con section.con_active {
  display: none;
  width: 100%;
  height: 100%;
}

.tab_con section.con_active {
  display: block;
}

.tab_con input {
  width: 80%;
  height: 60%;
  outline-width: 0;
  border: 1px solid #ccc;
}
//style.css
@font-face {font-family: "iconfont";
  src: url('./iconfont/iconfont.eot?t=1553960438096'); /* IE9 */
  src: url('./iconfont/iconfont.eot?t=1553960438096#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAK4AAsAAAAABmwAAAJrAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcAp4fwE2AiQDCAsGAAQgBYRtBzAbpQXIrrApw71oi3CCOyzEy8RvE4yIN8TD036/zp03qCYRjaJZNBFFS/gREoRGipQKofjuNrb+9XbTqrmXcqWzfTRDqFqWkhAJzYToaE6LQ7Q30CirRqSKMnj58DdIdrNAdhoTQJa5VGfLrtiAy+lPoAcZdUC57UljTR4TMAo4oL0xiqwYG8YueIHPCdTqYajty/t+bUpmrwvEnUK42lQhLMssVy1UNhzN4kmF6vSQVvMY/T5+HEU1SUXBbti7uBBrx++cgqJULp0GhAgBna5AgSkgE0eN6R1NwTitNt0yAI5VG7wr/8AljmoX7K+zq+tBF1Q8k9JTPWp1AjnJDgCzmM3bU0V31dsvV3M2eC6fHjaGfX/qS7U5Gr58vj6uD0bgxudyrV/OtHHyP+NZnpO1txbktjdY+3FB61+7nxeOzq8niGYnRwT3v3aZxeXf6rrNxl5//49WlEtZUUL1Pj3Bv1EO7MuG2namrCkbvcnApLUJtWpRhv2tzlRLx43kQ7WO2/FW6c5QqDZEZnYKFeosoVK1NdSa5E/XaVM1Ra7BhAEQmk0kjV5QaLbIzG5U6HRRqTkK1DqJtivrjMT1zJaNnIsihAiyQE3JdbszcW0Xiadzdl4d8UO0HSUGNDNXzl2hifYSO5pPjrorgdjUAAavoa5TKDZVUXD3kuuOOzh70fShvUiN2owtNsRxIREIIiATUCYpGO2aqXy/CxEeHcfuaKrLDiGbQ5kcEMsNIK8M5qCmR3mn8RFHOpcECBtlAAwWIZ2OAqV5kQoJXHvShORYBzrDZKhhb3uT8QPlrA3bmsKZV6i89DiTV2o1AAAA') format('woff2'),
  url('./iconfont/iconfont.woff?t=1553960438096') format('woff'),
  url('./iconfont/iconfont.ttf?t=1553960438096') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
  url('./iconfont/iconfont.svg?t=1553960438096#iconfont') format('svg'); /* iOS 4.1- */
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-guanbi:before {
  content: "\e676";
}
//tab.js
// 因为toggleTab中的this指向li,li没有sections功能,需要设置一个别的来指向它
var that
class Tab {
  constructor(id) {
    // 获取元素,将this中的sections放在that里面
    that = this
    // 获取tab盒子
    this.main = document.querySelector(id)
    // 获取tab_add按钮
    this.add = this.main.querySelector('.tab_add')
    // 获取li的父元素
    this.ul = this.main.querySelector('.tab_nav ul:first-child')
    // 获取section的父元素
    this.fsection = this.main.querySelector('.tab_con')
    this.init()
  }
  // 初始化操作让相关元素绑定事件
  init() {
    this.updateNode()
    // 为tab_add按钮添加click事件
    this.add.onclick = this.addTab
    for (var i = 0; i < this.lis.length; i++) {
      this.lis[i].index = i
      // 获取到每个li的index,并为其添加click事件
      this.lis[i].onclick = this.toggleTab
      // 为tab_remove按钮添加click事件
      this.remove[i].onclick = this.removeTab
      // 为span_nav添加双击事件
      this.spans[i].ondblclick = this.editTab
      this.sections[i].ondblclick = this.editTab
    }
  }
  // 清除类的函数
  clearClass() {
    for (var i = 0; i < this.lis.length; i++) {
      // 清除所有小li的class
      this.lis[i].className = ''
      // 清除所有sections的class
      this.sections[i].className = ''
    }
  }
  updateNode() {
    // 获取盒子中的所有li标签
    this.lis = this.main.querySelectorAll('li')
    // 获取盒子中的所有section
    this.sections = this.main.querySelectorAll('section')
    // 获取×号按钮
    this.remove = this.main.querySelectorAll('.icon-guanbi')
    // 获取盒子中所有的span标签
    this.spans = this.main.querySelectorAll('.tab_nav li span:first-child')
  }
  // 1.切换功能
  toggleTab() {
    console.log(this.index)
    that.clearClass()
    // nav_tab的切换
    this.className = 'nav_active'
    // con_tab的切换
    that.sections[this.index].className = 'con_active'
  }
  // 2.添加功能
  addTab() {
    // 先清除掉之前设置的class,在个新添加的元素追加新的class
    that.clearClass()
    // alert('add')
    var random = Math.random()
    // 1.创建li元素和section元素
    var li =
      '<li class="nav_active"><span>测试卡</span><span class="iconfont icon-guanbi"></span></li>'
    var section =
      '<section class="con_active">测试' + random + '相关的内容</section>'
    // 2.把这两个元素追加到对应的父元素里面
    that.ul.insertAdjacentHTML('beforeend', li)
    that.fsection.insertAdjacentHTML('beforeend', section)
    // 调用init()来重新获取加上追加的所有 li 和 section元素
    that.init()
  }
  // 3.删除功能
  removeTab(e) {
    // 阻止事件冒泡
    e.stopPropagation()
    // 获取×的父元素对应的索引号
    var index = this.parentNode.index
    // console.log(index)
    // 根据索引号删除对应的 li 和 section
    that.lis[index].remove()
    that.sections[index].remove()
    // 调用init()来重新获取加上追加的所有 li 和 section元素
    that.init()
    // 当我们删除了不是选中状态的li的时候,原来li的选中状态保持不变
    if (document.querySelector('.nav_active')) return;
    // 当我们删除了选中状态的这个li的时候,让前一个li处于选定状态(最好的方法就是给它添加一个点击事件)
    index--
    that.lis[index] && that.lis[index].click()
  }
  // 4.修改功能
  editTab() {
    // 先获取原来的内容,以便双击没有填入内容的时候返回原来的值
    var str = this.innerHTML
    console.log(str)
    // console.log('edit click')
    // 双击禁止选中文字
    window.getSelection ? window.getSelection().removeAllRanges() : document.getSelection.empty()
    // 双击之后生成一个文本框
    this.innerHTML = '<input type="text"/>'
    // 获取input元素
    var input = this.children[0]
    // 将原先的值赋给input
    input.value = str
    // 双击后让input框中的文字处于选中状态
    input.select()
    // 当鼠标离开文本框时把文本框里面的值给span/section
    input.onblur = function () {
      this.parentNode.innerHTML = this.value
    }
    // 按下回车也可以把文本框中的内容赋值给span/section
    input.onkeyup = function (e) {
      if (e.keyCode === 13) {
        this.blur()
      }
    }
  }
}
new Tab('#tab')
//index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>面向对象tab栏切换</title>
    <!-- 引入设置的tab-css -->
    <link rel="stylesheet" href="css/tab.css" />
    <link rel="stylesheet" href="css/style.css" />
  </head>
  <body>
    <main>
      <!-- title -->
      <h4>Js 面向对象 动态添加标签页</h4>
      <div class="tab_box" id="tab">
        <!-- tab导航栏 -->
        <nav class="tab_nav">
          <!-- 标签切换区域 -->
          <ul>
            <li class="nav_active">
              <span>测试1</span><span class="iconfont icon-guanbi"></span>
            </li>
            <li>
              <span>测试2</span><span class="iconfont icon-guanbi"></span>
            </li>
            <li>
              <span>测试3</span><span class="iconfont icon-guanbi"></span>
            </li>
          </ul>
          <!-- 添加区域 -->
          <div class="tab_add">
            <span>+</span>
          </div>
        </nav>
        <!-- tab内容区域 -->
        <div class="tab_con">
          <section class="con_active">测试1相关的内容</section>
          <section>测试2相关的内容</section>
          <section>测试3相关的内容</section>
        </div>
      </div>
    </main>
    <script src="js/tab.js"></script>
  </body>
</html>

利用数组方法实现简单的查询功能

* {
  margin: 0;
  padding: 0;
}

.main {
  width: 600px;
  text-align: center;
  margin: 100px auto;
}

.main input {
  width: 40px;
  outline: 0;
  border: 1px solid #ccc;
  text-align: center;
}

.main button {
  font-size: 10px;
}

table {
  width: 400px;
  margin: 20px auto;
  text-align: center;
  border-collapse: collapse;
}

th,
td {
  border: 1px solid #333;
}
data = [{
    id: 1,
    name: 'xiaomi',
    price: 1999
  },
  {
    id: 2,
    name: 'sanxing',
    price: 3999
  },
  {
    id: 3,
    name: 'huawei',
    price: 4299
  },
  {
    id: 4,
    name: 'vivo',
    price: 2399
  }
]
// 1.获取tbody元素
var tbody = document.querySelector('tbody')
// 2.将data中的数据渲染到页面中,利用forEach数组遍历
setData(data)

function setData(arr) {
  // 先清空原来tbody里面的数据
  tbody.innerHTML = ''
  arr.forEach(function (value) {
    // console.log(value)
    var tr = document.createElement('tr')
    tr.innerHTML = '<td>' + value.id + '</td><td>' + value.name + '</td><td>' + value.price + '</td>'
    tbody.appendChild(tr)
  });
}
// 通过价格区间搜索商品
// 1.获取价格区间查询相关元素
var price_search = document.querySelector('.price_search')
var start = document.querySelector('.start')
var end = document.querySelector('.end')
// 2.为查询按钮绑定点击事件 
price_search.addEventListener('click', function () {
  // console.log(start.value)
  // 利用filter过滤实现价格的查询功能,filter的结果是返回一个新的数组
  var res = data.filter(function (value) {
    return value.price >= start.value && value.price <= end.value
  })
  setData(res)
})
// 通过商品名称搜索商品
// 1.获取名称查询相关元素
var pname = document.querySelector('.pname')
var name_search = document.querySelector('.name_search')
// 2.为按name属性查询按钮绑定click事件
name_search.addEventListener('click', function () {
  var res = []
  // 如果检索数组中的唯一元素,用some的效率更高,因为其找到这个元素,便不再进行循环
  data.some(function (value) {
    if (value.name == pname.value) {
      res.push(value)
      return true //终止遍历
    }
  })
  setData(res)
})
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>利用数组方法实现查询功能</title>
    <link rel="stylesheet" href="css/search.css" />
  </head>
  <body>
    <div class="main">
      <div class="header">
        <span>按商品价格查询:</span>
        <input type="text" class="start" />
        <span>-</span>
        <input type="text" class="end" />
        <button class="price_search">搜索</button>
        <span>按商品名称查询:</span>
        <input type="text" class="pname" />
        <button class="name_search">查询</button>
      </div>
      <table>
        <thead>
          <tr>
            <th>id</th>
            <th>产品名称</th>
            <th>价格</th>
          </tr>
        </thead>
        <tbody></tbody>
      </table>
    </div>
    <script src="js/index.js"></script>
  </body>
</html>

点击输出li的索引号

 // es6 块级作用域
 var aLis = document.querySelectorAll('li')
 for (let i = 0; i < aLis.length; i++) {
   aLis[i].onclick = function () {
     console.log(i)
   }
 }
 
 //普通函数 先取出i存储
 var aLis = document.querySelectorAll('li')
 for (let i = 0; i < aLis.length; i++) {
   aLis[i].index = i
   aLis[i].onclick = function () {
     console.log(this.index)
   }
 }

 // jQuery
 $(function () {
   $('li').on('click', function () {
     var index = $(this).index()
     console.log(index)
   })
 })

 // 利用闭包
 var aLis = document.querySelectorAll('li')
 for (var i = 0; i < aLis.length; i++) {
   // 立即执行函数为一个小闭包
   (function (i) {
     aLis[i].onclick = function () {
       console.log(i)
     }
   })(i)
 }
 // 利用闭包,打印出每个li的innerHTML
var aLis = document.querySelectorAll('li')
for (var i = 0; i < aLis.length; i++) {
  (function (i) {
    setTimeout(function () {
      aLis[i].onclick = function () {
        console.log(aLis[i].innerHTML)
      }
    }, 2000)
  })(i);
}

offset系列的轮播图

<!DOCTYPE html>
<html lang="en">

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

    ul li,
    ol li {
      list-style: none;
    }

    .banner {
      width: 200px;
      height: 200px;
      padding: 10px;
      border: 1px solid #ccc;
      margin-top: 100px;
      margin-left: 50px;
      position: relative;
    }

    .screen {
      width: 200px;
      height: 200px;
      overflow: hidden;
      position: relative;
    }

    .screen ul {
      position: absolute;
      left: 0;
      top: 0;
      width: 1000px;
    }

    ul li {
      width: 200px;
      height: 200px;
      float: left;
      overflow: hidden;
    }

    .screen ol {
      position: absolute;
      right: 10px;
      bottom: 10px;
    }

    .screen ol li {
      width: 20px;
      height: 20px;
      background-color: #fff;
      float: left;
      margin-left: 5px;
      cursor: pointer;
      opacity: 0.7;
      line-height: 20px;
      text-align: center;
    }

    .screen ol li.current {
      background-color: yellow;
    }

    .screen .nav {
      position: relative;
      top: 50%;
      transform: translateY(-50%);
    }

    .nav span {
      position: absolute;
      display: block;
      width: 20px;
      height: 20px;
      background: #fff;
      opacity: 0.4;
      color: #000;
      vertical-align: middle;
      text-align: center;
      cursor: pointer;
    }

    .nav span:first-of-type {
      position: absolute;
      left: 0;
    }

    .nav span:last-of-type {
      position: absolute;
      right: 0;
    }
  </style>
</head>

<body>
  <div class="banner">
    <div class="screen">
      <ul>
        <li><img src="./imgs/11.jpg" alt="" style="width: 200px;height: 200px;"></li>
        <li><img src="./imgs/22.jpg" alt="" style="width: 200px;height: 200px;"></li>
        <li><img src="./imgs/33.jpg" alt="" style="width: 200px;height: 200px;"></li>
        <li><img src="./imgs/44.jpg" alt="" style="width: 200px;height: 200px;"></li>
      </ul>
      <ol></ol>
      <div class="nav">
        <span class="left">&lt;</span>
        <span class="right">&gt;</span>
      </div>
    </div>
  </div>

  <script>
    window.onload = function () {
      var oBanner = document.querySelector('.banner')
      console.log(oBanner);
      var oScreen = document.querySelector('.screen')
      console.log(oScreen);
      var imgWidth = oScreen.offsetWidth
      console.log(imgWidth);
      var oUl = document.querySelector('ul')
      console.log(oUl);
      var oOl = document.querySelector('ol')
      console.log(oOl);
      var oNav = document.querySelector('.nav')
      var oNavs = oNav.children
      console.log(oNavs);

      console.log(oUl.children[0]);
      // 复制ul第一个li到ul最后
      var newUlLi = oUl.children[0].cloneNode(true)
      oUl.appendChild(newUlLi)


      // 给ol中添加对应的li
      for (var i = 0; i < oUl.children.length - 1; i++) {
        var newOlLi = document.createElement('li')
        newOlLi.innerHTML = i + 1
        oOl.appendChild(newOlLi)
      }

      // 给ol中第一个li添加current元素
      var olArr = oOl.children
      olArr[0].className = 'current'

      // 鼠标hover ol 的 li,切换图片

      for (var i = 0; i < olArr.length; i++) {
        olArr[i].index = i
        olArr[i].onmouseover = function () {
          // 首先将current className置空
          for (var j = 0; j < olArr.length; j++) {
            olArr[j].className = ''
          }
          // 赋值当前元素current
          this.className = 'current'
          key = square = this.index
          console.log(this.index);
          // 展示图片,盒子移动
          animate(oUl, -this.index * imgWidth)
        }
      }

      // 添加定时器
      var timer = setInterval(autoPlay, 1000);

      // 两个定时器,一个图片,一个小方块
      var key = 0
      var square = 0

      function autoPlay() {
        key++
        if (key > olArr.length) {
          oUl.style.left = 0
          key = 1
        }
        animate(oUl, -key * imgWidth)

        square++
        if (square > olArr.length - 1) {
          square = 0
        }
        for (var i = 0; i < olArr.length; i++) {
          olArr[i].className = ''
        }
        olArr[square].className = 'current'
      }

      oBanner.onmouseover = function () {
        oNav.style.display = 'block'
        clearInterval(timer)
      }
      oBanner.onmouseout = function () {
        oNav.style.display = 'none'
        timer = setInterval(autoPlay, 1000);
      }

      // 左右切换图片
      oNavs[0].onclick = function () {
        key--
        if (key < 0) {
          oUl.style.left = -imgWidth * (olArr.length) + 'px'
          key = olArr.length - 1
        }
        animate(oUl, -key * imgWidth)

        square--
        if (square < 0) {
          square = olArr.length - 1
        }

        for (var i = 0; i < olArr.length; i++) {
          olArr[i].className = ''
        }
        olArr[square].className = 'current'
      }

      oNavs[1].onclick = function () {
        autoPlay()
      }

      // 封装animate函数
      function animate(ele, target) {
        clearInterval(ele.timer)
        var speed = target > ele.offsetLeft ? 10 : -10
        ele.timer = setInterval(() => {
          var value = target - ele.offsetLeft
          ele.style.left = ele.offsetLeft + speed + 'px'
          if (Math.abs(value) < Math.abs(speed)) {
            ele.style.left = target + 'px'
            clearInterval(ele.timer)
          }
        }, 10);
      }
    }
  </script>
</body>

</html>

offset系列缓慢动画的封装

<!DOCTYPE html>
<html lang="en">

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

    .box {
      width: 200px;
      height: 200px;
      background: pink;
      position: absolute;
      top: 50px;
    }
  </style>
</head>

<body>
  <button class="btn">left:400</button>
  <div class="box" style="left: 0;"></div>

  <script>
    var oBtn = document.querySelector('.btn')
    var oBox = document.querySelector('.box')

    oBtn.onclick = function () {
      animate(oBox, 400)
    }

    function animate(ele, target) {
      clearInterval(ele.timer)
      ele.timer = setInterval(() => {
        var step = (target - ele.offsetLeft) / 10
        var value = target - ele.offsetLeft
        // Math.ceil() - 向上取整 Math.floor() - 向下取整 Math.round() - 四舍五入
        step = step > 0 ? Math.ceil(step) : Math.floor(step)
        ele.style.left = ele.offsetLeft + step + 'px'
        if (Math.abs(value) < Math.abs(target)) {
          ele.style.left = target + 'px'
          clearInterval(ele.timer)
        }
      }, 30);
    }
  </script>
</body>

</html>

闭包应用计算打车费

 // 闭包应用,计算打车费
 // 打车起步价13(3公里内),之后每多一公里增加5块钱,用户输入公里数就可以计算打车价格
 // 如果有拥堵情况,总价格多收取10块钱拥堵费
 var car = (function () {
   // 起步价
   var start = 13
   // 总价
   var total = 0
   return {
     // 正常的总价
     price: function (n) {
       if (n <= 3) {
         total = start
       } else {
         total = start + (n - 3) * 5
       }
       return total
     },
     // 拥堵之后的费用
     yd: function (flag) {
       return flag ? total + 10 : total
     },
   }
 })()
 console.log(car.price(5))
 console.log(car.yd(true))

递归求斐波那契数列

var n = prompt('please input a number:')
function fn(n) {
  if (n === 1 || n === 2) {
    return 1
  }
  return fn(n - 1) + fn(n - 2)
}
console.log(fn(n))

递归求阶乘

var n = prompt('input')
function f(n) {
  if (n == 1) {
    return 1
  }
  return n * f(n - 1)
}
console.log(f(n))

利用递归,输入ID,返回对应对象

var data = [
 {
    id: 1,
    name: '家电',
    goods: [
      {
        id: 11,
        gname: '冰箱',
        goods: [
          {
            id: 110,
            gname: '海尔',
          },
          {
            id: 120,
            gname: '美的',
          },
        ],
      },
      {
        id: 12,
        gname: '洗衣机',
      },
    ],
  },
  {
    id: 2,
    name: '服饰',
    goods: [
      {
        id: 12,
        gname: 'fish',
      },
      {
        id: 20,
        gname: 'apple',
      },
    ],
  },
]
// 我们想要做输入id号,就可以返回的数据对象
// 1. 利用 forEach 去遍历里面的每一个对象
var o = {}
function getID(json, id) {
  json.forEach(function (item) {
    // console.log(item); // 2个数组元素
    if (item.id == id) {
      // console.log(item);
      o = item
      // 2. 我们想要得里层的数据 11 12 可以利用递归函数
      // 里面应该有goods这个数组并且数组的长度不为 0
    } else if (item.goods && item.goods.length > 0) {
      o = getID(item.goods, id)
    }
  })
  return o
}
var id = prompt()
console.log(getID(data, id))

浅拷贝和深拷贝

var obj = {
  id: 1,
  name: 'falcon',
  msg: {
    age: 18,
    hobby: 'singing',
    sport: 'running',
  },
  color: ['pink', 'red'],
}
var o = {}
// 浅拷贝
// for (var k in obj) {
//   o[k] = obj[k]
// }
// console.log(o)
// console.log(o.msg.sport)
// console.log(obj.msg.sport)

// 浅拷贝
Object.assign(o, obj)
console.log(o)
// 深拷贝
function deepCopy(newobj, oldobj) {
  for (var k in oldobj) {
    // 判断我们的属性值属于哪种数据类型
    // 1.获取属性值 oldobj[k]
    var item = oldobj[k]
    // 2.判断这个值是否是数组 or 对象 or 简单数据类型
    // 注:在这里数组也属于object,如果把数组写在object后面,数组就为对象了,会出错
    if (item instanceof Array) {
      newobj[k] = []
      deepCopy(newobj, item)
    } else if (item instanceof Object) {
      newobj[k] = {}
      deepCopy(newobj, item)
    } else {
      newobj[k] = item
    }
  }
}
deepCopy(o, obj)
console.log(o)
o.msg.age = 20
// 深拷贝修改后不会改变已经拷贝的属性和对象
console.log(o)

利用正则进行简单的表单验证

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>用户名的验证</title>
    <style>
      .red {
        color: red;
      }
      .green {
        color: green;
      }
    </style>
  </head>
  <body>
    <div>
      请输入用户名:
      <input type="text" />
      <span></span>
    </div>
    <script>
      var iput = document.querySelector('input')
      var span = document.querySelector('span')
      iput.addEventListener('blur', function () {
        var reg = /^[a-zA-Z0-9-_]{6,16}$/
        var str = iput.value
        if (reg.test(str)) {
          span.innerHTML = '恭喜,通过'
          span.className = 'green'
        } else {
          span.innerHTML = '对不起,错误'
          span.className = 'red'
        }
      })
    </script>
  </body>
</html>

表单验证

* {
  margin: 0;
  padding: 0;
}

li {
  list-style-type: none;
}

.register_box {
  width: 800px;
  height: 600px;
  border: 0.2px solid #ccc;
  margin: 40px auto;
  border-radius: 10px;
}

ul {
  margin: 50px auto;
}

.register_box li {
  margin-bottom: 15px;
}

.register_box label {
  display: inline-block;
  width: 100px;
  height: 36px;
  text-align: right;
}

.inp {
  width: 240px;
  height: 34px;
  border: 0.5px solid #ccc;
  margin-left: 10px;
  outline: none;
}

.safe {
  padding-left: 190px;
  color: #b2b2b2;
}

.safe em {
  padding: 0 12px;
  color: #fff;
}

.ruo {
  background-color: #de1111;
}

.zhong {
  background-color: #40b83f;
}

.qiang {
  background-color: #f79100;
}

.agree {
  padding-top: 20px;
  padding-left: 100px;
}

.agree input {
  vertical-align: middle;
  margin-right: 5px;
}

.agree a {
  color: #1ba1e6;
}

.over {
  width: 200px;
  height: 34px;
  background-color: #c81623;
  margin: 30px 0 0 130px;
  border: none;
  color: #fff;
  font-size: 14px;
}

.success {
  color: #40b83f;
  margin-left: 10px;
}

.error {
  color: #df3033;
  margin-left: 10px;
}

.msg {
  color: #f79100;
  margin-left: 10px
}

.success-icon,
.error_icon,
.msg_icon {
  display: inline-block;
  width: 20px;
  height: 20px;
  vertical-align: middle;
  margin-top: -2px;
  background: url(/img/register/right.png) no-repeat;
}

.error_icon {
  background: url(/img/register/wrong.png);
}

.msg_icon {
  background: url(/img/register/mess.png);
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>表单验证</title>
    <link rel="stylesheet" href="css/check.css" />
  </head>
  <body>
    <div class="register_box">
      <ul>
        <li>
          <label for="">手机号:</label>
          <input type="text" class="inp" id="tel" />
          <span></span>
        </li>
        <li>
          <label for="">QQ:</label>
          <input type="text" class="inp" id="qq" />
          <span></span>
        </li>
        <li>
          <label for="">昵称:</label>
          <input type="text" class="inp" id="nc" />
          <span></span>
        </li>
        <li>
          <label for="">短信验证码:</label>
          <input type="text" class="inp" id="msg" />
          <span></span>
        </li>
        <li>
          <label for="">登录密码:</label>
          <input type="text" class="inp" id="pwd" />
          <span></span>
        </li>
        <li class="safe">
          安全程度
          <em class="ruo"></em>
          <em class="zhong"></em>
          <em class="qiang"></em>
        </li>
        <li>
          <label for="">确认密码:</label>
          <input type="text" class="inp" id="surepwd" />
          <span></span>
        </li>
        <li class="agree">
          <input type="checkbox" />同意协议并注册
          <a href="#">《知果果用户协议》</a>
        </li>
        <li>
          <input type="submit" value="完成注册" class="over" />
        </li>
      </ul>
    </div>
    <script src="js/check.js"></script>
  </body>
</html>
window.onload = function () {
  // 手机号码的正则表达式
  var regtel = /^1[3|4|5|6|7|8|9]\d{9}$/
  var tel = document.querySelector('#tel')
  regexp(tel, regtel)
  // qq号码的验证
  var regqq = /^[1-9][0-9]{4,}$/
  var qq = document.querySelector('#qq')
  regexp(qq, regqq)
  // 昵称的验证
  var regnc = /^[\u4e00-\u9fa5]{2,8}$/
  var nc = document.querySelector('#nc')
  regexp(nc, regnc)
  // 短信验证码
  var regmsg = /^\d{6}$/
  var msg = document.querySelector('#msg')
  regexp(msg, regmsg)
  // 密码验证
  var regpwd = /^[a-zA-Z0-9_-]{6-16}$/
  var pwd = document.querySelector('#pwd')
  regexp(pwd, regpwd)
  surepwd = document.querySelector('#surepwd')
  surepwd.addEventListener('blur', function () {
    if (this.value == pwd.value) {
      this.nextElementSibling.className = 'success'
      this.nextElementSibling.innerHTML = '<i class="success_icon"></i> 恭喜,验证通过'
    } else {
      this.nextElementSibling.className = 'error'
      this.nextElementSibling.innerHTML = '<i class="error_icon"></i>错误,两次密码输入不一致'
    }
  })
  // 函数封装
  function regexp(ele, reg) {
    ele.addEventListener('blur', function () {
      if (this.value.trim() === '') {
        this.nextElementSibling.className = 'msg'
        this.nextElementSibling.innerHTML = '<i class="msg_icon"></i>输入不能为空'
      } else if (reg.test(this.value)) {
        this.nextElementSibling.className = 'success'
        this.nextElementSibling.innerHTML = '<i class="success_icon"></i>恭喜,输入正确'
      } else {
        this.nextElementSibling.className = 'error'
        this.nextElementSibling.innerHTML = '<i class="error_icon"></i>错误,请重新输入'
      }
    })
  }
}

敏感词过滤

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>敏感词过滤</title>
  </head>
  <body>
    <textarea name="" id="msg" cols="30" rows="10"></textarea
    ><button>提交</button>
    <div></div>
    <script>
      var text = document.querySelector('#msg')
      var btn = document.querySelector('button')
      var div = document.querySelector('div')
      btn.addEventListener('click', function () {
        // g:全局匹配 i:忽略大小写  gi/ig:全局匹配+忽略大小写
        var con = text.value.replace(/激情/g, '**')
        div.innerHTML = con
      })
    </script>
  </body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值