【黑马程序员前端】JavaScript入门到精通(2)--20230801

news2024/12/27 11:17:07

B站链接
【黑马程序员前端】JavaScript入门到精通(1)–20230801
【黑马程序员前端】JavaScript入门到精通(2)–20230801

2.web APIs资料(续前)

web APIs第六天

01-正则表达式的使用

在这里插入图片描述

<!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>
</head>

<body>
  <script>
    const str = '我们在学习前端,希望学习前端能高薪毕业'
    // 正则表达式使用:
    // 1. 定义规则
    const reg = /前端/
    // 2. 是否匹配
    // console.log(reg.test(str))  // true
    // 3. exec()
    console.log(reg.exec(str))  // 返回数组
  </script>
</body>

</html>
02-元字符
<!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>
</head>

<body>
  <script>
    // 元字符

    // console.log(/哈/.test('哈')) // true
    // console.log(/哈/.test('哈哈')) // true
    // console.log(/哈/.test('二哈')) // true
    // console.log('------------------')
    // // 1. 边界符
    // console.log(/^哈/.test('哈')) // true
    // console.log(/^哈/.test('哈哈')) // true
    // console.log(/^哈/.test('二哈')) // flase
    // console.log(/^哈$/.test('哈')) // true  只有这种情况为true 否则全是false
    // console.log(/^哈$/.test('哈哈')) // false
    // console.log(/^哈$/.test('二哈')) // false

    // console.log('------------------')
    // //  量词 * 类似 >=0 次
    // console.log(/^哈$/.test('哈')) // true
    // console.log(/^哈*$/.test('')) // true
    // console.log(/^哈*$/.test('哈')) // true
    // console.log(/^哈*$/.test('哈哈')) // true
    // console.log(/^哈*$/.test('二哈很傻')) //  false
    // console.log(/^哈*$/.test('哈很傻')) //  false
    // console.log(/^哈*$/.test('哈很哈')) // false
    // console.log('------------------')
    // //  量词 + 类似 >=1 次
    // console.log(/^哈$/.test('哈')) // true
    // console.log(/^哈+$/.test('')) // false
    // console.log(/^哈+$/.test('哈')) // true
    // console.log(/^哈+$/.test('哈哈')) // true
    // console.log(/^哈+$/.test('二哈很傻')) //  false
    // console.log(/^哈+$/.test('哈很傻')) //  false
    // console.log(/^哈+$/.test('哈很哈')) // false

    // console.log('------------------')
    // console.log('------------------')
    // //  量词 ? 类似  0 || 1
    // console.log(/^哈?$/.test('')) // true
    // console.log(/^哈?$/.test('哈')) // true
    // console.log(/^哈?$/.test('哈哈')) // true
    // console.log(/^哈?$/.test('二哈很傻')) //  false
    // console.log(/^哈?$/.test('哈很傻')) //  false
    // console.log(/^哈?$/.test('哈很哈')) // false


    // 量词 {n} 写几,就必须出现几次
    console.log(/^哈{4}$/.test('哈'))
    console.log(/^哈{4}$/.test('哈哈'))
    console.log(/^哈{4}$/.test('哈哈哈'))
    console.log(/^哈{4}$/.test('哈哈哈哈'))
    console.log(/^哈{4}$/.test('哈哈哈哈哈'))
    console.log(/^哈{4}$/.test('哈哈哈哈哈哈'))
    console.log('------------------')
    // 量词 {n,}   >=n
    console.log(/^哈{4,}$/.test('哈'))
    console.log(/^哈{4,}$/.test('哈哈'))
    console.log(/^哈{4,}$/.test('哈哈哈'))
    console.log(/^哈{4,}$/.test('哈哈哈哈'))
    console.log(/^哈{4,}$/.test('哈哈哈哈哈'))
    console.log(/^哈{4,}$/.test('哈哈哈哈哈哈'))
    console.log('------------------')
    // 量词 {n,m}  逗号左右两侧千万不能有空格    >=n && <= m
    console.log(/^哈{4,6}$/.test('哈'))
    console.log(/^哈{4,6}$/.test('哈哈'))
    console.log(/^哈{4,6}$/.test('哈哈哈'))
    console.log(/^哈{4,6}$/.test('哈哈哈哈'))
    console.log(/^哈{4,6}$/.test('哈哈哈哈哈'))
    console.log(/^哈{4,6}$/.test('哈哈哈哈哈哈'))
    console.log(/^哈{4,6}$/.test('哈哈哈哈哈哈哈'))
    console.log('------------------')
    // 字符类   [abc]  只选1个
    console.log(/^[abc]$/.test('a'))  // true
    console.log(/^[abc]$/.test('b'))  // true
    console.log(/^[abc]$/.test('c'))  // true
    console.log(/^[abc]$/.test('ab'))  // false
    console.log(/^[abc]{2}$/.test('ab'))  // true
    console.log('------------------')
    // 字符类   [a-z]  只选1个
    console.log(/^[A-Z]$/.test('p'))  // false
    console.log(/^[A-Z]$/.test('P'))  // true
    console.log(/^[0-9]$/.test(2))  // true
    console.log(/^[a-zA-Z0-9]$/.test(2))  // true
    console.log(/^[a-zA-Z0-9]$/.test('p'))  // true
    console.log(/^[a-zA-Z0-9]$/.test('P'))  // true
    console.log('------------------')

  </script>

</body>

</html>
03-验证用户名案例

在这里插入图片描述

<!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>
        span {
            display: inline-block;
            width: 250px;
            height: 30px;
            vertical-align: middle;
            line-height: 30px;
            padding-left: 15px;
        }

        .error {
            color: red;
            background: url(./images/error1.png) no-repeat left center;
        }

        .right {
            color: green;
            background: url(./images/right.png) no-repeat left center;
        }
    </style>
</head>

<body>
    <input type="text">
    <span></span>
    <script>
        // 1. 准备正则
        const reg = /^[a-zA-Z0-9-_]{6,16}$/
        const input = document.querySelector('input')
        const span = input.nextElementSibling
        input.addEventListener('blur', function () {
            // console.log(reg.test(this.value))
            if (reg.test(this.value)) {
                span.innerHTML = '输入正确'
                span.className = 'right'
            } else {
                span.innerHTML = '请输入6~16位的英文数字下划线'
                span.className = 'error'
            }
        })
    </script>
</body>

</html>
04-正则修饰符

在这里插入图片描述

<!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>
</head>

<body>
  <script>
    console.log(/^java$/.test('java'))
    console.log(/^java$/i.test('JAVA'))
    console.log(/^java$/i.test('Java'))
    const str = 'java是一门编程语言, 学完JAVA工资很高'
    // const re = str.replace(/java|JAVA/g, '前端')
    const re = str.replace(/java/ig, '前端')
    console.log(re)  // 前端是一门编程语言, 学完前端工资很高
  </script>
</body>

</html>
05-过滤敏感词

在这里插入图片描述

<!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>
</head>

<body>
  <textarea name="" id="" cols="30" rows="10"></textarea>
  <button>发布</button>
  <div></div>
  <script>
    const tx = document.querySelector('textarea')
    const btn = document.querySelector('button')
    const div = document.querySelector('div')
    btn.addEventListener('click', function () {
      // console.log(tx.value)
      div.innerHTML = tx.value.replace(/激情|基情/g, '**')
      tx.value = ''
    })
  </script>
</body>

</html>
06-change事件
<!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>
</head>

<body>
  <!-- <input type="text"> -->
  <input type="checkbox" name="" id="">
  <script>
    // change 事件 内容发生了变化
    const input = document.querySelector('input')
    input.addEventListener('change', function () {
      console.log(111)
    })
  </script>
</body>

</html>
综合案例素材

login.html
在这里插入图片描述

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

<head>
  <meta charset="UTF-8">
  <title>小兔鲜儿 - 新鲜 惠民 快捷!</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="renderer" content="webkit">
  <link rel="shortcut icon" href="../favicon.ico">
  <link rel="stylesheet" href="./css/common.css">
  <link rel="stylesheet" href="./css/login.css">
  <link rel="stylesheet" href="https://at.alicdn.com/t/font_2143783_iq6z4ey5vu.css">
</head>

<body>
  <!-- 登录头部 -->
  <div class="xtx-login-header">
    <h1 class="logo"></h1>
    <a class="home" href="./index.html">进入网站首页</a>
  </div>
  <!-- 登录内容 -->
  <div class="xtx-login-main">
    <div class="wrapper">
      <form action="" autocomplete="off">
        <div class="box">
          <div class="tab-nav">
            <a href="javascript:;" class="active" data-id="0">账户登录</a>
            <a href="javascript:;" data-id="1">二维码登录</a>
          </div>
          <div class="tab-pane">
            <div class="link">
              <a href="javascript:;">手机验证码登录</a>
            </div>  
            <div class="input">
              <span class="iconfont icon-zhanghao"></span>
              <input required type="text" placeholder="请输入用户名称/手机号码" name="username">
            </div>
            <div class="input">
              <span class="iconfont icon-suo"></span>
              <input required type="password" placeholder="请输入密码" name="password">
            </div>
            <div class="agree">
              <label for="my-checkbox">
                <input type="checkbox" value="1" id="my-checkbox" class="remember" name="agree">
                <span class="iconfont icon-xuanze"></span>
              </label>
              我已同意 <a href="javascript:;">《服务条款》</a href="javascript:;"><a>《服务条款》</a>
            </div>
            <div class="button clearfix">
              <button type="submit" class="dl">登 录</button>
              <!-- <a class="dl" href="./center.html">登 录</a> -->
              <a class="fl" href="./forget.html">忘记密码?</a>
              <a class="fr" href="./register.html">免费注册</a>
            </div>
          </div>
          <div class="tab-pane" style="display: none;">
            <img class="code" src="./images/code.png" alt="">
          </div>
        </div>
      </form>
    </div>
  </div>
  <!-- 登录底部 -->
  <div class="xtx-login-footer">
    <!-- 版权信息 -->
    <div class="copyright">
      <p>
        <a href="javascript:;">关于我们</a>
        <a href="javascript:;">帮助中心</a>
        <a href="javascript:;">售后服务</a>
        <a href="javascript:;">配送与验收</a>
        <a href="javascript:;">商务合作</a>
        <a href="javascript:;">搜索推荐</a>
        <a href="javascript:;">友情链接</a>
      </p>
      <p>CopyRight &copy; 小兔鲜儿</p>
    </div>
  </div>
  <script>
    // 1. tab栏切换  事件委托
    const tab_nav = document.querySelector('.tab-nav')
    const pane = document.querySelectorAll('.tab-pane')
    // 1.1 事件监听
    tab_nav.addEventListener('click', function (e) {
      if (e.target.tagName === 'A') {
        // 取消上一个active
        tab_nav.querySelector('.active').classList.remove('active')
        // 当前元素添加active
        e.target.classList.add('active')

        // 先干掉所有人  for循环
        for (let i = 0; i < pane.length; i++) {
          pane[i].style.display = 'none'
        }
        // 让对应序号的 大pane 显示 
        pane[e.target.dataset.id].style.display = 'block'
      }
    })

    // 点击提交模块
    const form = document.querySelector('form')
    const agree = document.querySelector('[name=agree]')
    const username = document.querySelector('[name=username]')
    form.addEventListener('submit', function (e) {
      e.preventDefault()
      // 判断是否勾选同意协议
      if (!agree.checked) {
        return alert('请勾选同意协议')
      }

      // 记录用户名到本地存储
      localStorage.setItem('xtx-uname', username.value)
      // 跳转到首页
      location.href = './index.html'
    })
  </script>
</body>

</html>

register.html
在这里插入图片描述

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

<head>
  <meta charset="UTF-8">
  <title>小兔鲜儿 - 新鲜 惠民 快捷!</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="renderer" content="webkit">
  <link rel="shortcut icon" href="./favicon.ico">
  <link rel="stylesheet" href="./css/common.css">
  <link rel="stylesheet" href="./css/register.css">
  <link rel="stylesheet" href="https://at.alicdn.com/t/font_2143783_iq6z4ey5vu.css">
</head>

<body>
  <!-- 项部导航 -->
  <div class="xtx_topnav">
    <div class="wrapper">
      <!-- 顶部导航 -->
      <ul class="xtx_navs">
        <li>
          <a href="./login.html">请先登录</a>
        </li>
        <li>
          <a href="./register.html">免费注册</a>
        </li>
        <li>
          <a href="./center-order.html">我的订单</a>
        </li>
        <li>
          <a href="./center.html">会员中心</a>
        </li>
        <li>
          <a href="javascript:;">帮助中心</a>
        </li>
        <li>
          <a href="javascript:;">在线客服</a>
        </li>
        <li>
          <a href="javascript:;">
            <i class="mobile sprites"></i>
            手机版
          </a>
        </li>
      </ul>
    </div>
  </div>
  <!-- 头部 -->
  <div class="xtx_header">
    <div class="wrapper">
      <!-- 网站Logo -->
      <h1 class="xtx_logo"><a href="/">小兔鲜儿</a></h1>
      <!-- 主导航 -->
      <div class="xtx_navs">
        <ul class="clearfix">
          <li>
            <a href="./index.html">首页</a>
          </li>
          <li>
            <a href="./category01.html">生鲜</a>
          </li>
          <li>
            <a href="./category01.html">美食</a>
          </li>
          <li>
            <a href="./category01.html">餐厨</a>
          </li>
          <li>
            <a href="./category01.html">电器</a>
          </li>
          <li>
            <a href="./category01.html">居家</a>
          </li>
          <li>
            <a href="./category01.html">洗护</a>
          </li>
          <li>
            <a href="./category01.html">孕婴</a>
          </li>
          <li>
            <a href="./category01.html">服装</a>
          </li>
        </ul>
      </div>
      <!-- 站内搜索 -->
      <div class="xtx_search clearfix">
        <!-- 购物车 -->
        <a href="./cart-none.html" class="xtx_search_cart sprites">
          <i>2</i>
        </a>
        <!-- 搜索框 -->
        <div class="xtx_search_wrapper">
          <input type="text" placeholder="搜一搜" onclick="location.href='./search.html'">
        </div>
      </div>
    </div>
  </div>
  <div class="xtx-wrapper">
    <div class="container">
      <!-- 卡片 -->
      <div class="xtx-card">
        <h3>新用户注册</h3>
        <form class="xtx-form">
          <div data-prop="username" class="xtx-form-item">
            <span class="iconfont icon-zhanghao"></span>
            <input name="username" type="text" placeholder="设置用户名称">
            <span class="msg"></span>
          </div>
          <div data-prop="phone" class="xtx-form-item">
            <span class="iconfont icon-shouji"></span>
            <input name="phone" type="text" placeholder="输入手机号码  ">
            <span class="msg"></span>
          </div>
          <div data-prop="code" class="xtx-form-item">
            <span class="iconfont icon-zhibiaozhushibiaozhu"></span>
            <input name="code" type="text" placeholder="短信验证码">
            <span class="msg"></span>
            <a class="code" href="javascript:;">发送验证码</a>
          </div>
          <div data-prop="password" class="xtx-form-item">
            <span class="iconfont icon-suo"></span>
            <input name="password" type="password" placeholder="设置6至20位字母、数字和符号组合">
            <span class="msg"></span>
          </div>
          <div data-prop="confirm" class="xtx-form-item">
            <span class="iconfont icon-suo"></span>
            <input name="confirm" type="password" placeholder="请再次输入上面密码">
            <span class="msg"></span>
          </div>
          <div class="xtx-form-item pl50">
            <i class="iconfont icon-queren"></i>
            已阅读并同意<i>《用户服务协议》</i>
          </div>
          <div class="xtx-form-item">
            <button class="submit">下一步</button>
            <!-- <a class="submit" href="javascript:;">下一步</a> -->
          </div>
        </form>
      </div>
    </div>
  </div>
  <!-- 公共底部 -->
  <div class="xtx_footer clearfix">
    <div class="wrapper">
      <!-- 联系我们 -->
      <div class="contact clearfix">
        <dl>
          <dt>客户服务</dt>
          <dd class="chat">在线客服</dd>
          <dd class="feedback">问题反馈</dd>
        </dl>
        <dl>
          <dt>关注我们</dt>
          <dd class="weixin">公众号</dd>
          <dd class="weibo">微博</dd>
        </dl>
        <dl>
          <dt>下载APP</dt>
          <dd class="qrcode">
            <img src="./uploads/qrcode.jpg">
          </dd>
          <dd class="download">
            <span>扫描二维码</span>
            <span>立马下载APP</span>
            <a href="javascript:;">下载页面</a>
          </dd>
        </dl>
        <dl>
          <dt>服务热线</dt>
          <dd class="hotline">
            400-0000-000
            <small>周一至周日 8:00-18:00</small>
          </dd>
        </dl>
      </div>
    </div>
    <!-- 其它 -->
    <div class="extra">
      <div class="wrapper">
        <!-- 口号 -->
        <div class="slogan">
          <a href="javascript:;" class="price">价格亲民</a>
          <a href="javascript:;" class="express">物流快捷</a>
          <a href="javascript:;" class="quality">品质新鲜</a>
        </div>
        <!-- 版权信息 -->
        <div class="copyright">
          <p>
            <a href="javascript:;">关于我们</a>
            <a href="javascript:;">帮助中心</a>
            <a href="javascript:;">售后服务</a>
            <a href="javascript:;">配送与验收</a>
            <a href="javascript:;">商务合作</a>
            <a href="javascript:;">搜索推荐</a>
            <a href="javascript:;">友情链接</a>
          </p>
          <p>CopyRight &copy; 小兔鲜儿</p>
        </div>
      </div>
    </div>
  </div>
  <script>
    (function () {
      // 1. 发送短信验证码模块
      const code = document.querySelector('.code')
      let flag = true  // 通过一个变量来控制   节流阀 
      //  1.1 点击事件
      code.addEventListener('click', function () {
        if (flag) {
          // 取反了,不能马上第二次点击
          flag = false
          let i = 5
          // 点击完毕之后立马触发
          code.innerHTML = `0${i}秒后重新获取`
          // 开启定时器
          let timerId = setInterval(function () {
            i--
            code.innerHTML = `0${i}秒后重新获取`
            if (i === 0) {
              // 清除定时器
              clearInterval(timerId)
              // 从新获取
              code.innerHTML = `重新获取`
              // 到时间了,可以开启 flag了
              flag = true
            }
          }, 1000)
        }
      })
    })();


    // 2. 验证的是用户名
    // 2.1 获取用户名表单
    const username = document.querySelector('[name=username]')
    // 2.2 使用change事件  值发生变化的时候
    username.addEventListener('change', verifyName)
    // 2.3 封装verifyName函数
    function verifyName() {
      // console.log(11)
      const span = username.nextElementSibling
      // 2.4 定规则  用户名
      const reg = /^[a-zA-Z0-9-_]{6,10}$/
      if (!reg.test(username.value)) {
        // console.log(11)
        span.innerText = '输入不合法,请输入6~10位'
        return false
      }
      // 2.5 合法的 就清空span
      span.innerText = ''
      return true
    }



    // 3. 验证的是手机号
    // 2.1 获取手机表单
    const phone = document.querySelector('[name=phone]')
    // 2.2 使用change事件  值发生变化的时候
    phone.addEventListener('change', verifyPhone)
    // 2.3 verifyPhone
    function verifyPhone() {
      // console.log(11)
      const span = phone.nextElementSibling
      // 2.4 定规则  用户名
      const reg = /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/
      if (!reg.test(phone.value)) {
        // console.log(11)
        span.innerText = '输入不合法,请输入正确的11位手机号码'
        return false
      }
      // 2.5 合法的 就清空span
      span.innerText = ''
      return true
    }


    // 4. 验证的是验证码
    // 4.1 获取验证码表单
    const codeInput = document.querySelector('[name=code]')
    //4.2 使用change事件  值发生变化的时候
    codeInput.addEventListener('change', verifyCode)
    // 4.3 verifyPhone
    function verifyCode() {
      // console.log(11)
      const span = codeInput.nextElementSibling
      // 4.4 定规则  验证码
      const reg = /^\d{6}$/
      if (!reg.test(codeInput.value)) {
        // console.log(11)
        span.innerText = '输入不合法,6 位数字'
        return false
      }
      // 4.5 合法的 就清空span
      span.innerText = ''
      return true
    }

    // 5. 验证的是密码框
    // 5.1 获取密码表单
    const password = document.querySelector('[name=password]')
    //5.2 使用change事件  值发生变化的时候
    password.addEventListener('change', verifyPwd)
    // 5.3 verifyPhone
    function verifyPwd() {
      // console.log(11)
      const span = password.nextElementSibling
      // 5.4 定规则  密码
      const reg = /^[a-zA-Z0-9-_]{6,20}$/
      if (!reg.test(password.value)) {
        // console.log(11)
        span.innerText = '输入不合法,6~20位数字字母符号组成'
        return false
      }
      // 5.5 合法的 就清空span
      span.innerText = ''
      return true
    }



    // 6. 密码的再次验证
    // 6.1 获取再次验证表单
    const confirm = document.querySelector('[name=confirm]')
    //6.2 使用change事件  值发生变化的时候
    confirm.addEventListener('change', verifyConfirm)
    // 6.3 verifyPhone
    function verifyConfirm() {
      // console.log(11)
      const span = confirm.nextElementSibling
      // 6.4 当前表单的值不等于 密码框的值就是错误的
      if (confirm.value !== password.value) {
        // console.log(11)
        span.innerText = '两次密码输入不一致'
        return false
      }
      // 6.5 合法的 就清空span
      span.innerText = ''
      return true
    }

    // 7. 我同意
    const queren = document.querySelector('.icon-queren')
    queren.addEventListener('click', function () {
      // 切换类  原来有的就删掉,原来没有就添加
      this.classList.toggle('icon-queren2')
    })

    // 8. 提交模块
    const form = document.querySelector('form')
    form.addEventListener('submit', function (e) {
      // 判断是否勾选我同意模块 ,如果有 icon-queren2说明就勾选了,否则没勾选
      if (!queren.classList.contains('icon-queren2')) {
        alert('请勾选同意协议')
        // 阻止提交
        e.preventDefault()
      }
      // 依次判断上面的每个框框 是否通过,只要有一个没有通过的就阻止
      // console.log(verifyName())
      if (!verifyName()) e.preventDefault()
      if (!verifyPhone()) e.preventDefault()
      if (!verifyCode()) e.preventDefault()
      if (!verifyPwd()) e.preventDefault()
      if (!verifyConfirm()) e.preventDefault()
    })
  </script>
</body>

</html>

web APIs第七天实战

放大镜

在这里插入图片描述

在这里插入图片描述

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

<head>
  <meta charset="UTF-8">
  <title>小兔鲜儿 - 新鲜 惠民 快捷!</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="renderer" content="webkit">
  <!-- <link rel="stylesheet" href="//at.alicdn.com/t/font_1939705_bgtmkonu28.css"> -->
  <link rel="stylesheet" href="./fonts/iconfont.css">
  <link rel="stylesheet" href="./css/index.css">

  <link rel="stylesheet" href="./css/common.css">
  <link rel="stylesheet" href="./css/product.css">

</head>

<body>
  <!-- 项部导航 -->
  <div class="xtx_topnav">
    <div class="wrapper">
      <!-- 顶部导航 -->
      <ul class="xtx_navs">
        <li>
          <a href="javascript:;">请先登录</a>
        </li>
        <li>
          <a href="javascript:;">免费注册</a>
        </li>
        <li>
          <a href=".javascript:;">我的订单</a>
        </li>
        <li>
          <a href="javascript:;">会员中心</a>
        </li>
        <li>
          <a href="javascript:;">帮助中心</a>
        </li>
        <li>
          <a href="javascript:;">在线客服</a>
        </li>
        <li>
          <a href="javascript:;">
            <i class="mobile sprites"></i>
            手机版
          </a>
        </li>
      </ul>
    </div>
  </div>
  <!-- 头部 -->
  <div class="xtx_header">
    <div class="wrapper">
      <!-- 网站Logo -->
      <h1 class="xtx_logo"><a href="/">小兔鲜儿</a></h1>
      <!-- 主导航 -->
      <div class="xtx_navs">
        <ul class="clearfix">
          <li>
            <a href="javascript:;">首页</a>
          </li>
          <li>
            <a href="javascript:;">生鲜</a>
          </li>
          <li>
            <a href="javascript:;">美食</a>
          </li>
          <li>
            <a href="javascript:;">餐厨</a>
          </li>
          <li>
            <a href="javascript:;">电器</a>
          </li>
          <li>
            <a href="javascript:;">居家</a>
          </li>
          <li>
            <a href="javascript:;">洗护</a>
          </li>
          <li>
            <a href="javascript:;">孕婴</a>
          </li>
          <li>
            <a href="javascript:;">服装</a>
          </li>
        </ul>
      </div>
      <!-- 站内搜索 -->
      <div class="xtx_search clearfix">
        <!-- 购物车 -->
        <a href="javascript:;" class="xtx_search_cart sprites">
          <i>2</i>
        </a>
        <!-- 搜索框 -->
        <div class="xtx_search_wrapper">
          <input type="text" placeholder="搜一搜" onclick="location.href='./search.html'">
        </div>
      </div>
    </div>
  </div>

  <!-- 头部sticky定位 添加show类名可以显示 -->
  <div class="sticky">
    <div class="header-sticky container">
      <div class="sticky-logo">
        <h1>
          <a href="#"></a>
        </h1>
      </div>
      <ul class="sticky-nav">
        <li><a href="#">首页</a></li>
        <li><a href="#">居家</a></li>
        <li><a href="#">美食</a></li>
        <li><a href="#">服饰</a></li>
        <li><a href="#">母婴</a></li>
        <li><a href="#">个护</a></li>
        <li><a href="#">严选</a></li>
        <li><a href="#">数码</a></li>
        <li><a href="#">运动</a></li>
        <li><a href="#">杂项</a></li>
      </ul>
      <div class="sticky-right">
        <a href="#">品牌</a>
        <a href="#">专题</a>
      </div>
    </div>
  </div>

  <!-- 返回顶部 -->
  <div class="backTop">
    <i class="backIcon"></i>
    <p>顶部</p>
  </div>

  <div class="xtx-wrapper">
    <div class="container">
      <!-- 面包屑 -->
      <div class="xtx-bread">
        <a href="javascript:;"> 首页 > </a>
        <a href="javascript:;"> 电子产品 > </a>
        <a href="javascript:;"> 电视 > </a>
        <span>小米电视4A 32英寸</span>
      </div>
      <!-- 商品信息 -->
      <div class="xtx-product-info">
        <div class="left">
          <div class="pictrue">
            <div class="middle">
              <img src="./images/1.jpg" alt="">
              <div class="layer"></div>
            </div>
            <div class="small">
              <ul>
                <li class="active"><img src="./images/1.jpg" alt=""></li>
                <li><img src="./images/2.jpg" alt=""></li>
                <li><img src="./images/3.jpg" alt=""></li>
                <li><img src="./images/4.jpg" alt=""></li>
                <li><img src="./images/5.jpg" alt=""></li>
              </ul>
            </div>
            <div class="large"></div>
          </div>
          <div class="other">
            <ul>
              <li>
                <p>销量人气</p>
                <p>1999+</p>
                <p>销量人气</p>
              </li>
              <li>
                <p>商品评价</p>
                <p>999+</p>
                <p>查看评价</p>
              </li>
              <li>
                <p>收藏人气</p>
                <p>299+</p>
                <p><a href="javascript:;">收藏商品</a></p>
              </li>
              <li>
                <p>品牌信息</p>
                <p>小米</p>
                <p><a href="javascript:;">品牌主页</a></p>
              </li>
            </ul>
          </div>
        </div>
        <div class="right">
          <h3 class="name">小米电视4A 32英寸</h3>
          <p class="desc">全面屏设计 / 高清分辨率 / 海量内容 / 1G+4G大内存 / 多核处理器</p>
          <p class="price"><span class="now">¥1899</span><span class="old">¥2999</span></p>
          <div class="address">
            <div class="item">
              <div class="dt">促销</div>
              <div class="dd">12月好物放送,App领券购买直降120元</div>
            </div>
            <div class="item">
              <div class="dt">配送</div>
              <div class="dd"><div class="box">
                  <span>陕西 西安 <i></i></span>
                </div>
              </div>
            </div>
            <div class="item">
              <div class="dt">服务</div>
              <div class="dd">
                <span class="fw">无忧退货</span>
                <span class="fw">快速退款</span>
                <span class="fw">免费包邮</span>
                <a href="#" class="lj">了解详情</a>
              </div>
            </div>
          </div>
          <div class="attrs">
            <div class="item">
              <div class="dt">颜色</div>
              <div class="dd" id="color">
                <img src="./uploads/img/cate-06.png" alt="">
                <img src="./uploads/img/cate-07.png" alt="">
              </div>
            </div>
            <div class="item">
              <div class="dt">颜色</div>
              <div class="dd" id="size">
                <span class="size">22英寸</span>
                <span class="size">42英寸</span>
                <span class="size">52英寸</span>
                <span class="size">62英寸</span>
              </div>
            </div>
            <div class="item">
              <div class="dt">数量</div>
              <div class="dd">
                <div class="num">
                  <a href="javascript:;">-</a>
                  <input type="text" value="1">
                  <a href="javascript:;">+</a>
                </div>
              </div>
            </div>
            <div class="item">
              <a class="buy" href="javascript:;">立即购买</a>
            </div>
          </div>
        </div>
      </div>
      <!-- 同类产品推荐 -->
      <div class="xtx-relevant-product">
        <h3>同类产品推荐</h3>
        <ul>
          <li>
            <a href="#">
              <img src="./uploads/history_goods_1.jpg" alt="">
              <p class="name">USB Type C数据线</p>
              <p class="desc">快速充电,稳定传输</p>
              <p class="price">¥39</p>
            </a>
          </li>
          <li>
            <a href="#">
              <img src="./uploads/history_goods_2.jpg" alt="">
              <p class="name">红米Note 5A 高配版</p>
              <p class="desc">1600万像素柔光自拍</p>
              <p class="price">¥1899</p>
            </a>
          </li>
          <li>
            <a href="#">
              <img src="./uploads/history_goods_3.jpg" alt="">
              <p class="name">VGA网口多功能转接器</p>
              <p class="desc">小巧便携,节省桌面空间</p>
              <p class="price">¥19</p>
            </a>
          </li>
          <li>
            <a href="#">
              <img src="./uploads/history_goods_4.jpg" alt="">
              <p class="name">笔记本Pro 15.6"</p>
              <p class="desc">全金属强化机身搭配独显</p>
              <p class="price">¥4899</p>
            </a>
          </li>
        </ul>
        <a href="javascript:;" class="prev"><span class="iconfont icon-angle-left"></span></a>
        <a href="javascript:;" class="next"><span class="iconfont icon-angle-right"></span></a>
      </div>
      <!-- 商品详情 -->
      <div class="xtx-product-detail">
        <div class="main">
          <div class="cont">
            <div class="tab-head">
              <a href="javascript:;" class="active" data-id="2">商品详情</a>
              <a href="javascript:;" data-id="3">商品评价<span>(998+)</span></a>
            </div>
            <div class="tab-pane" style="display: block;">
              <!-- 静态属性 -->
              <div class="attrs">
                <div class="item"><span>商品名称:</span><span>小米L32M5-AZ </span></div>
                <div class="item"><span>商品编号:</span><span>4620979 </span></div>
                <div class="item"><span>商品毛重:</span><span>8.0kg </span></div>
                <div class="item"><span>商品产地:</span><span>中国大陆 </span></div>
                <div class="item"><span>屏幕尺寸:</span><span>32英寸及以下 </span></div>
                <div class="item"><span>能效等级:</span><span>三级能效 </span></div>
                <div class="item"><span>电视类型:</span><span>人工智能 </span></div>
                <div class="item"><span>选购指数:</span><span>6.9-6.0 </span></div>
                <div class="item"><span>观看距离:</span><span>2m以下(≤32英寸)</span></div>
              </div>
              <!-- 详情内容 -->
              <div class="detail">
                <img src="https://yanxuan-item.nosdn.127.net/39d7f2407c90d0442566a719146ee9c1.jpg" alt=""
                  data-v-2c43c764=""><img src="https://yanxuan-item.nosdn.127.net/7dfee58e7c6b3996badf368610ed62b1.jpg"
                  alt="" data-v-2c43c764=""><img
                  src="https://yanxuan-item.nosdn.127.net/d1acff1a29bddd21c2ad337d892a9f7c.jpg" alt=""
                  data-v-2c43c764=""><img src="https://yanxuan-item.nosdn.127.net/ac722b04b2014ac337d8db695ee46f0c.jpg"
                  alt="" data-v-2c43c764=""><img
                  src="https://yanxuan-item.nosdn.127.net/c63e36faa0848ee37c825897f5cec179.jpg" alt=""
                  data-v-2c43c764=""><img src="https://yanxuan-item.nosdn.127.net/e0f13dbf14c8a2f07e86bf3df3ca002b.jpg"
                  alt="" data-v-2c43c764="">
              </div>
            </div>
            <div class="tab-pane" style="display: none;">
              <div class="goods-tabs">
                <div class="tabs-hd">
                  <span>排序:</span>
                  <!-- tabs切换按钮 -->
                  <ul>
                    <li class="active"><a href="#">默认</a></li>
                    <li><a href="#">最新</a></li>
                    <li><a href="#">最热</a></li>
                  </ul>
                </div>
                <div class="tabs-bd">
                  <!-- 默认tabs隐藏   切换show类名显示 -->
                  <!-- 默认评论模块 -->
                  <div class="tabs tabs-default show">
                    <!-- tabs-item 每一个评论列表 -->
                    <div class="tabs-item">
                      <div class="userInfo">
                        <span class="userpic"><img src="./uploads/avatar_1.png" alt=""></span>
                        <span class="username">兔****y</span>
                      </div>
                      <div class="tbs-body">
                        <div class="score">
                          <!-- 切换xingxing 和 xingxing1 可以改变星星样式 -->
                          <i class="iconfont icon-xingxing"></i>
                          <i class="iconfont icon-xingxing"></i>
                          <i class="iconfont icon-xingxing"></i>
                          <i class="iconfont icon-xingxing1"></i>
                          <i class="iconfont icon-xingxing1"></i>
                          <span class="attr">颜色:白色 尺寸:10cm 产地:美国</span>
                        </div>
                        <div class="text">昨天下单,今天中午开锅就试着烧了五花肉,耗时30分钟,一切都刚刚好,比以前的锅烧出来口感汤汁都好多了,且价格实惠!建议购买!</div>
                        <div class="comment-image">
                          <div class="list">
                            <a class="" href="javascript:;">
                              <img src="./uploads/1.webp" alt="">
                            </a>
                            <a class="" href="javascript:;">
                              <img src="./uploads/2.webp" alt="">
                            </a>
                            <a class="" href="javascript:;">
                              <img src="./uploads/3.webp" alt="">
                            </a>
                            <a class="" href="javascript:;">
                              <img src="./uploads/4.webp" alt="">
                            </a>
                            <a class="" href="javascript:;">
                              <img src="./uploads/5.webp" alt="">
                            </a>

                          </div>
                          <!---->
                        </div>
                        <div class="time">
                          <span>2021-04-03 13:20:32</span>
                          <span class="zan"><i class="iconfont icon-dianzan"></i>74</span>
                        </div>
                      </div>
                    </div>
                    <!-- tabs-item 每一个评论列表 -->
                    <div class="tabs-item">
                      <div class="userInfo">
                        <span class="userpic"><img src="./uploads/avatar_1.png" alt=""></span>
                        <span class="username">兔****y</span>
                      </div>
                      <div class="tbs-body">
                        <div class="score">
                          <!-- 切换xingxing 和 xingxing1 可以改变星星样式 -->
                          <i class="iconfont icon-xingxing"></i>
                          <i class="iconfont icon-xingxing"></i>
                          <i class="iconfont icon-xingxing"></i>
                          <i class="iconfont icon-xingxing1"></i>
                          <i class="iconfont icon-xingxing1"></i>
                          <span class="attr">颜色:白色 尺寸:10cm 产地:美国</span>
                        </div>
                        <div class="text">昨天下单,今天中午开锅就试着烧了五花肉,耗时30分钟,一切都刚刚好,比以前的锅烧出来口感汤汁都好多了,且价格实惠!建议购买!</div>
                        <div class="comment-image">
                          <div class="list">
                            <a class="" href="javascript:;">
                              <img src="./uploads/1.webp" alt="">
                            </a>
                            <a class="" href="javascript:;">
                              <img src="./uploads/2.webp" alt="">
                            </a>
                            <a class="" href="javascript:;">
                              <img src="./uploads/3.webp" alt="">
                            </a>
                            <a class="" href="javascript:;">
                              <img src="./uploads/4.webp" alt="">
                            </a>
                            <a class="" href="javascript:;">
                              <img src="./uploads/5.webp" alt="">
                            </a>

                          </div>
                          <!---->
                        </div>
                        <div class="time">
                          <span>2021-04-03 13:20:32</span>
                          <span class="zan"><i class="iconfont icon-dianzan"></i>74</span>
                        </div>
                      </div>
                    </div>
                    <!-- tabs-item 每一个评论列表 -->
                    <div class="tabs-item">
                      <div class="userInfo">
                        <span class="userpic"><img src="./uploads/avatar_1.png" alt=""></span>
                        <span class="username">兔****y</span>
                      </div>
                      <div class="tbs-body">
                        <div class="score">
                          <!-- 切换xingxing 和 xingxing1 可以改变星星样式 -->
                          <i class="iconfont icon-xingxing"></i>
                          <i class="iconfont icon-xingxing"></i>
                          <i class="iconfont icon-xingxing"></i>
                          <i class="iconfont icon-xingxing1"></i>
                          <i class="iconfont icon-xingxing1"></i>
                          <span class="attr">颜色:白色 尺寸:10cm 产地:美国</span>
                        </div>
                        <div class="text">昨天下单,今天中午开锅就试着烧了五花肉,耗时30分钟,一切都刚刚好,比以前的锅烧出来口感汤汁都好多了,且价格实惠!建议购买!</div>
                        <div class="comment-image">
                          <div class="list">
                            <a class="" href="javascript:;">
                              <img src="./uploads/1.webp" alt="">
                            </a>
                            <a class="" href="javascript:;">
                              <img src="./uploads/2.webp" alt="">
                            </a>
                            <a class="" href="javascript:;">
                              <img src="./uploads/3.webp" alt="">
                            </a>
                            <a class="" href="javascript:;">
                              <img src="./uploads/4.webp" alt="">
                            </a>
                            <a class="" href="javascript:;">
                              <img src="./uploads/5.webp" alt="">
                            </a>

                          </div>
                          <!---->
                        </div>
                        <div class="time">
                          <span>2021-04-03 13:20:32</span>
                          <span class="zan"><i class="iconfont icon-dianzan"></i>74</span>
                        </div>
                      </div>
                    </div>
                  </div>

                  <!-- 最新评论模块 -->
                  <div class="tabs tabs-new"></div>
                  <!-- 最热评论模块 -->
                  <div class="tabs tabs-hot"></div>
                </div>

                <!-- 翻页在这里 -->
                <div class="xtx-pagination">
                  <ul>
                    <li>1</li>
                    <li>2</li>
                    <li>3</li>
                    <li>4</li>
                    <li>5</li>
                    <li>6</li>
                    <li>7</li>
                    <li>8</li>
                  </ul>
                </div>
              </div>
            </div>
          </div>
          <!-- 注意事项 -->
          <div class="warn">
            <h3>注意事项</h3>
            <p class="tit">• 购买运费如何收取? </p>
            <p>单笔订单金额(不含运费)满88元免邮费;不满88元,每单收取10元运费。(港澳台地区需满500元免邮费;不满500元,每单收取30元运费) </p>
            <br>
            <br>
            <p class="tit">• 使用什么快递发货? </p>
            <p>默认使用顺丰快递发货(个别商品使用其他快递) </p>
            <p>配送范围覆盖全国大部分地区(港澳台地区除外)。 </p>
            <br>
            <br>
            <p class="tit">• 如何申请退货? </p>
            <p>1.自收到商品之日起30日内,顾客可申请无忧退货,退款将原路返还,不同的银行处理时间不同,预计1-5个工作日到账; </p>
            <p>2.内裤和食品等特殊商品无质量问题不支持退货; </p>
            <p>3.退货流程: 确认收货-申请退货-客服审核通过-用户寄回商品-仓库签收验货-退款审核-退款完成; </p>
            <p>4.因小兔鲜儿产生的退货,如质量问题,退货邮费由小兔鲜儿承担,退款完成后会以现金券的形式报销。因客户个人原因产生的退货,购买和寄回运费由客户个人承担。</p>
          </div>
        </div>
        <div class="aside">
          <div class="tit">24小时热销榜</div>
          <div class="product">
            <img src="./uploads/fresh_goods_3.jpg" alt="">
            <p class="name">USB Type C数据线</p>
            <p class="desc">快速充电,稳定传输</p>
            <p class="price">¥29</p>
          </div>
          <div class="product">
            <img src="./uploads/fresh_goods_3.jpg" alt="">
            <p class="name">USB Type C数据线</p>
            <p class="desc">快速充电,稳定传输</p>
            <p class="price">¥29</p>
          </div>
          <div class="product">
            <img src="./uploads/fresh_goods_3.jpg" alt="">
            <p class="name">USB Type C数据线</p>
            <p class="desc">快速充电,稳定传输</p>
            <p class="price">¥29</p>
          </div>
          <div class="tit">专题推荐</div>
          <div class="special">
            <img src="./uploads/discuss_goods_1.jpg" alt="">
            <p class="name">一往无前,诞生于崛起</p>
          </div>
          <div class="special">
            <img src="./uploads/discuss_goods_1.jpg" alt="">
            <p class="name">一往无前,诞生于崛起</p>
          </div>
          <div class="special">
            <img src="./uploads/discuss_goods_1.jpg" alt="">
            <p class="name">一往无前,诞生于崛起</p>
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- 公共底部 -->
  <div class="xtx_footer clearfix">
    <div class="wrapper">
      <!-- 联系我们 -->
      <div class="contact clearfix">
        <dl>
          <dt>客户服务</dt>
          <dd class="chat">在线客服</dd>
          <dd class="feedback">问题反馈</dd>
        </dl>
        <dl>
          <dt>关注我们</dt>
          <dd class="weixin">公众号</dd>
          <dd class="weibo">微博</dd>
        </dl>
        <dl>
          <dt>下载APP</dt>
          <dd class="qrcode">
            <img src="./uploads/qrcode.jpg">
          </dd>
          <dd class="download">
            <span>扫描二维码</span>
            <span>立马下载APP</span>
            <a href="javascript:;">下载页面</a>
          </dd>
        </dl>
        <dl>
          <dt>服务热线</dt>
          <dd class="hotline">
            400-0000-000
            <small>周一至周日 8:00-18:00</small>
          </dd>
        </dl>
      </div>
    </div>
    <!-- 其它 -->
    <div class="extra">
      <div class="wrapper">
        <!-- 口号 -->
        <div class="slogan">
          <a href="javascript:;" class="price">价格亲民</a>
          <a href="javascript:;" class="express">物流快捷</a>
          <a href="javascript:;" class="quality">品质新鲜</a>
        </div>
        <!-- 版权信息 -->
        <div class="copyright">
          <p>
            <a href="javascript:;">关于我们</a>
            <a href="javascript:;">帮助中心</a>
            <a href="javascript:;">售后服务</a>
            <a href="javascript:;">配送与验收</a>
            <a href="javascript:;">商务合作</a>
            <a href="javascript:;">搜索推荐</a>
            <a href="javascript:;">友情链接</a>
          </p>
          <p>CopyRight &copy; 小兔鲜儿</p>
        </div>
      </div>
    </div>
  </div>

  <script>

    //顶部导航栏自动滑出
    (function () {
      const sticky = document.querySelector('.sticky');
      const header = document.querySelector('.xtx_header .wrapper');
      const headerTop = header.offsetTop;
      const heaerHeight = header.clientHeight;
      const top = headerTop + heaerHeight;
      window.addEventListener('scroll', function () {
        const n = document.documentElement.scrollTop;
        if (n >= top) {
          sticky.style.top = '0px';
        } else {
          sticky.style.top = '-80px';
        }
      })
    })();


    //三个图的故事
    (function () {
      // 1. 获取三个盒子
      // 2. 小盒子 图片切换效果
      const small = document.querySelector('.small')
      //  中盒子
      const middle = document.querySelector('.middle')
      //  大盒子
      const large = document.querySelector('.large')
      // 2. 事件委托
      small.addEventListener('mouseover', function (e) {
        if (e.target.tagName === 'IMG') {
          // console.log(111)
          // 排他 干掉以前的 active  li 上面
          this.querySelector('.active').classList.remove('active')
          // 当前元素的爸爸添加 active
          e.target.parentNode.classList.add('active')
          // 拿到当前小图片的 src
          // console.log(e.target.src)
          // 让中等盒子里面的图片,src 更换为   小图片src
          middle.querySelector('img').src = e.target.src
          // 大盒子更换背景图片
          large.style.backgroundImage = `url(${e.target.src})`
        }
      })


      // 3. 鼠标经过中等盒子, 显示隐藏 大盒子
      middle.addEventListener('mouseenter', show)
      middle.addEventListener('mouseleave', hide)
      let timeId = null
      // 显示函数 显示大盒子
      function show() {
        // 先清除定时器
        clearTimeout(timeId)
        large.style.display = 'block'
      }
      // 隐藏函数 隐藏大盒子
      function hide() {
        timeId = setTimeout(function () {
          large.style.display = 'none'
        }, 200)
      }


      // 4. 鼠标经过大盒子, 显示隐藏 大盒子
      large.addEventListener('mouseenter', show)
      large.addEventListener('mouseleave', hide)


      // 5. 鼠标经过中等盒子,显示隐藏 黑色遮罩层
      const layer = document.querySelector('.layer')
      middle.addEventListener('mouseenter', function () {
        layer.style.display = 'block'
      })
      middle.addEventListener('mouseleave', function () {
        layer.style.display = 'none'
      })
      // 6.移动黑色遮罩盒子
      middle.addEventListener('mousemove', function (e) {
        // let x = 10, y = 20
        // console.log(11)
        // 鼠标在middle 盒子里面的坐标 = 鼠标在页面中的坐标 - middle 中等盒子的坐标
        // console.log(e.pageX)鼠标在页面中的坐标
        // middle 中等盒子的坐标
        // console.log(middle.getBoundingClientRect().left)
        let x = e.pageX - middle.getBoundingClientRect().left
        let y = e.pageY - middle.getBoundingClientRect().top - document.documentElement.scrollTop
        // console.log(x, y)
        // 黑色遮罩移动 在 middle 盒子内 限定移动的距离
        if (x >= 0 && x <= 400 && y >= 0 && y <= 400) {
          // 黑色盒子不是一直移动的
          // 声明2个变量 黑色盒子移动的 mx my变量 
          let mx = 0, my = 0
          if (x < 100) mx = 0
          if (x >= 100 && x <= 300) mx = x - 100
          if (x > 300) mx = 200

          if (y < 100) my = 0
          if (y >= 100 && y <= 300) my = y - 100
          if (y > 300) my = 200

          layer.style.left = mx + 'px'
          layer.style.top = my + 'px'
          // 大盒子的背景图片要跟随 中等盒子移动  存在的关系是 2倍   
          large.style.backgroundPositionX = -2 * mx + 'px'
          large.style.backgroundPositionY = -2 * my + 'px'
        }
      })
    })();


    //商品详情和商品评价切换
    (function () {
      const tabHead = document.querySelector('.tab-head');
      tabHead.addEventListener('click', function (e) {
        if (e.target.tagName == 'A') {
          const active = document.querySelector('.tab-head .active');
          if (active) active.classList.remove('active');
          e.target.classList.add('active');

          const id = e.target.dataset.id;
          const a = id == 2 ? 3 : 2;
          document.querySelector('.main .cont>div:nth-child(' + id + ')').style.display = 'block';
          document.querySelector('.main .cont>div:nth-child(' + a + ')').style.display = 'none';
        }
      })
    })();


    //点击尺寸
    (function () {
      const dd = document.querySelector('.item #size');
      dd.addEventListener('click', function (e) {
        if (e.target.tagName == 'SPAN') {
          const active = document.querySelector('.item #size .active');
          if (active) active.classList.remove('active');
          e.target.classList.add('active');
        }
      });
    })();


    //点击颜色
    (function () {
      const dd = document.querySelector('.item #color');
      dd.addEventListener('click', function (e) {
        if (e.target.tagName == 'IMG') {
          const active = document.querySelector('.item  #color img.active');
          if (active) active.classList.remove('active');
          e.target.classList.add('active');
        }
      });
    })();

  </script>
</body>

</html>

3.JS进阶资料

JavaScript进阶第一天

03-闭包
<!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>
</head>

<body>
  <script>
    // 简单的写法
    // function outer() {
    //   let a = 10
    //   function fn() {
    //     console.log(a)
    //   }
    //   fn()
    // }
    // outer()


    // 常见的闭包的形式   外部可以访问使用 函数内部的变量
    // function outer() {
    //   let a = 100
    //   function fn() {
    //     console.log(a)
    //   }
    //   return fn
    // }


    // outer()   ===  fn   ===  function fn() {}
    // const fun = function fn() { }

    // // 常见的写法2
    // function outer() {
    //   let a = 100
    //   return function () {
    //     console.log(a)
    //   }
    // }
    // const fun = outer()
    // fun() // 调用函数


    // 外面要使用这个 10

    // 闭包的应用 
    // 普通形式 统计函数调用的次数
    // let i = 0
    // function fn() {
    //   i++
    //   console.log(`函数被调用了${i}次`)
    // }
    //  因为 i 是全局变量,容易被修改
    // 闭包形式 统计函数调用的次数
    function count() {
      let i = 0
      function fn() {
        i++
        console.log(`函数被调用了${i}`)
      }
      return fn
    }
    const fun = count()
  </script>
</body>

</html>
04-变量提升

在这里插入图片描述

  <script>
    // 1. 把所有var声明的变量提升到 当前作用域的最前面
    // 2. 只提升声明, 不提升赋值
    // var num
    // console.log(num + '件')
    // num = 10
    // console.log(num)

    function fn() {
      console.log(num)
      var num = 10
    }
    fn()
  </script>
05-函数提升

在这里插入图片描述

  <script>
    var fun
    // 1. 会把所有函数声明提升到当前作用域的最前面
    // 2. 只提升函数声明,不提升函数调用
    fn()
    function fn() {
      console.log('函数提升')
    }
    fun()
    var fun = function () {
      console.log('函数表达式')
    }
      // 函数表达式 必须先声明和赋值, 后调用 否则 报错
  </script>
06-函数动态参数

在这里插入图片描述

  <script>
    function getSum() {
      // arguments 动态参数 只存在于 函数里面
      // 是伪数组 里面存储的是传递过来的实参
      // console.log(arguments)  [2,3,4]
      let sum = 0
      for (let i = 0; i < arguments.length; i++) {
        sum += arguments[i]
      }
      console.log(sum)
    }
    getSum(2, 3, 4)
    getSum(1, 2, 3, 4, 2, 2, 3, 4)
  </script>
07-函数参数剩余参数

在这里插入图片描述

  <script>
    function getSum(a, b, ...arr) {
      console.log(arr)  // 使用的时候不需要写 ...
    }
    getSum(2, 3)
    getSum(1, 2, 3, 4, 5)
  </script>
08-展开运算符

在这里插入图片描述

  <script>
    const arr1 = [1, 2, 3]
    // 展开运算符 可以展开数组
    // console.log(...arr)

    // console.log(Math.max(1, 2, 3))
    // ...arr1  === 1,2,3
    // 1 求数组最大值
    console.log(Math.max(...arr1)) // 3
    console.log(Math.min(...arr1)) // 1
    // 2. 合并数组
    const arr2 = [3, 4, 5]
    const arr = [...arr1, ...arr2]
    console.log(arr)

  </script>
09-箭头函数的基本语法
  <script>
    // const fn = function () {
    //   console.log(123)
    // }
    // 1. 箭头函数 基本语法
    // const fn = () => {
    //   console.log(123)
    // }
    // fn()
    // const fn = (x) => {
    //   console.log(x)
    // }
    // fn(1)
    // 2. 只有一个形参的时候,可以省略小括号
    // const fn = x => {
    //   console.log(x)
    // }
    // fn(1)
    // // 3. 只有一行代码的时候,我们可以省略大括号
    // const fn = x => console.log(x)
    // fn(1)
    // 4. 只有一行代码的时候,可以省略return
    // const fn = x => x + x
    // console.log(fn(1))
    // 5. 箭头函数可以直接返回一个对象
    // const fn = (uname) => ({ uname: uname })
    // console.log(fn('刘德华'))

  </script>
10-箭头函数的参数
  <script>
    // 1. 利用箭头函数来求和
    const getSum = (...arr) => {
      let sum = 0
      for (let i = 0; i < arr.length; i++) {
        sum += arr[i]
      }
      return sum
    }
    const result = getSum(2, 3, 4)
    console.log(result) // 9
  </script>
11-箭头函数的this

在这里插入图片描述

  <script>
    // 以前this的指向:  谁调用的这个函数,this 就指向谁
    // console.log(this)  // window
    // // 普通函数
    // function fn() {
    //   console.log(this)  // window
    // }
    // window.fn()
    // // 对象方法里面的this
    // const obj = {
    //   name: 'andy',
    //   sayHi: function () {
    //     console.log(this)  // obj
    //   }
    // }
    // obj.sayHi()

    // 2. 箭头函数的this  是上一层作用域的this 指向
    // const fn = () => {
    //   console.log(this)  // window
    // }
    // fn()
    // 对象方法箭头函数 this
    // const obj = {
    //   uname: 'pink老师',
    //   sayHi: () => {
    //     console.log(this)  // this 指向谁? window
    //   }
    // }
    // obj.sayHi()

    const obj = {
      uname: 'pink老师',
      sayHi: function () {
        console.log(this)  // obj
        let i = 10
        const count = () => {
          console.log(this)  // obj 
        }
        count()
      }
    }
    obj.sayHi()

  </script>
12-数组解构

在这里插入图片描述

  <script>
    // const arr = [100, 60, 80]
    // 数组解构 赋值
    // // const [max, min, avg] = arr
    const [max, min, avg] = [100, 60, 80]
    // // const max = arr[0]
    // // const min = arr[1]
    // // const avg = arr[2]
    console.log(max) // 100
    console.log(avg) // 80
    // 交换2个变量的值
    let a = 1
    let b = 2;
    [b, a] = [a, b]
    console.log(a, b)
  </script>
13-必须加分号的两种情况
  <script>
    // 1. 立即执行函数要加
    // (function () { })();
    // (function () { })();
    // 2. 使用数组的时候
    // const arr = [1, 2, 3]
    const str = 'pink';
    [1, 2, 3].map(function (item) {
      console.log(item)
    })

    let a = 1
    let b = 2
      ;[b, a] = [a, b]

    console.log(a, b)
  </script>
14-数组解构细节
  <script>
    // const pc = ['海尔', '联想', '小米', '方正'];
    // [hr, lx, mi, fz] = pc
    // console.log(hr, lx, mi, fz);


    // function getValue() {
    //   return [100, 60]
    // }
    // [max, min] = getValue()
    // console.log(max, min);



    // const pc = ['海尔', '联想', '小米', '方正']
    // const [hr, lx, mi, fz] = ['海尔', '联想', '小米', '方正']
    // console.log(hr)
    // console.log(lx)
    // console.log(mi)
    // console.log(fz)

    // // 请将最大值和最小值函数返回值解构 max 和min 两个变量
    // function getValue() {
    //   return [100, 60]
    // }
    // const [max, min] = getValue()
    // console.log(max)
    // console.log(min)
    // 1. 变量多, 单元值少 , undefined
    // const [a, b, c, d] = [1, 2, 3]
    // console.log(a) // 1
    // console.log(b) // 2
    // console.log(c) // 3
    // console.log(d) // undefined
    // 2. 变量少, 单元值多
    // const [a, b] = [1, 2, 3]
    // console.log(a) // 1
    // console.log(b) // 2
    // 3.  剩余参数 变量少, 单元值多
    // const [a, b, ...c] = [1, 2, 3, 4]
    // console.log(a) // 1
    // console.log(b) // 2
    // console.log(c) // [3, 4]  真数组
    // 4.  防止 undefined 传递
    // const [a = 0, b = 0] = [1, 2]
    // const [a = 0, b = 0] = []
    // console.log(a) // 1
    // console.log(b) // 2
    // 5.  按需导入赋值
    // const [a, b, , d] = [1, 2, 3, 4]
    // console.log(a) // 1
    // console.log(b) // 2
    // console.log(d) // 4

    // const arr = [1, 2, [3, 4]]
    // console.log(arr[0])  // 1
    // console.log(arr[1])  // 2
    // console.log(arr[2])  // [3,4]
    // console.log(arr[2][0])  // 3

    // 多维数组解构
    // const arr = [1, 2, [3, 4]]
    // const [a, b, c] = [1, 2, [3, 4]]
    // console.log(a) // 1
    // console.log(b) // 2
    // console.log(c) // [3,4]


    const [a, b, [c, d]] = [1, 2, [3, 4]]
    console.log(a) // 1
    console.log(b) // 2
    console.log(c) // 3
    console.log(d) // 4
  </script>
15-对象解构

在这里插入图片描述

  <script>
    // 对象解构
    // const obj = {
    //   uname: 'pink老师',
    //   age: 18
    // }
    // obj.uname
    // obj.age 
    // const uname = 'red老师'
    // 解构的语法
    // const { uname, age } = {age: 18, uname: 'pink老师' }
    // // 等价于 const uname =  obj.uname
    // // 要求属性名和变量名必须一直才可以
    // console.log(uname)
    // console.log(age)
    // 1. 对象解构的变量名 可以重新改名  旧变量名: 新变量名
    // const { uname: username, age } = { uname: 'pink老师', age: 18 }

    // console.log(username)
    // console.log(age)
    // 2. 解构数组对象
    const pig = [
      {
        uname: '佩奇',
        age: 6
      }
    ]
    const [{ uname, age }] = pig
    console.log(uname)
    console.log(age)
  </script>
16-多级对象解构

在这里插入图片描述

  <script>
    // const pig = {
    //   name: '佩奇',
    //   family: {
    //     mother: '猪妈妈',
    //     father: '猪爸爸',
    //     sister: '乔治'
    //   },
    //   age: 6
    // }
    // // 多级对象解构
    // const { name, family: { mother, father, sister } } = pig
    // console.log(name)
    // console.log(mother)
    // console.log(father)
    // console.log(sister)

    const person = [
      {
        name: '佩奇',
        family: {
          mother: '猪妈妈',
          father: '猪爸爸',
          sister: '乔治'
        },
        age: 6
      }
    ]
    const [{ name, family: { mother, father, sister } }] = person
    console.log(name)
    console.log(mother)
    console.log(father)
    console.log(sister)
  </script>
17-多级对象解构案例

在这里插入图片描述

  <script>
    // 1. 这是后台传递过来的数据
    const msg = {
      "code": 200,
      "msg": "获取新闻列表成功",
      "data": [
        {
          "id": 1,
          "title": "5G商用自己,三大运用商收入下降",
          "count": 58
        },
        {
          "id": 2,
          "title": "国际媒体头条速览",
          "count": 56
        },
        {
          "id": 3,
          "title": "乌克兰和俄罗斯持续冲突",
          "count": 1669
        },

      ]
    }

    // 需求1: 请将以上msg对象  采用对象解构的方式 只选出  data 方面后面使用渲染页面
    // const { data } = msg
    // console.log(data)
    // 需求2: 上面msg是后台传递过来的数据,我们需要把data选出当做参数传递给 函数
    // const { data } = msg
    // msg 虽然很多属性,但是我们利用解构只要 data值
    function render({ data }) {
      // const { data } = arr
      // 我们只要 data 数据
      // 内部处理
      console.log(data)

    }
    render(msg)

    // 需求3, 为了防止msg里面的data名字混淆,要求渲染函数里面的数据名改为 myData
    function render({ data: myData }) {
      // 要求将 获取过来的 data数据 更名为 myData
      // 内部处理
      console.log(myData)

    }
    render(msg)

  </script>
18-forEach语法

在这里插入图片描述

  <script>
    // forEach 就是遍历  加强版的for循环  适合于遍历数组对象
    const arr = ['red', 'green', 'pink']
    const result = arr.forEach(function (item, index) {
      console.log(item)  // 数组元素 red  green pink
      console.log(index) // 索引号
    })
    // console.log(result)
  </script>
19-渲染商品案例

在这里插入图片描述

<!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>商品渲染</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .list {
      width: 990px;
      margin: 0 auto;
      display: flex;
      flex-wrap: wrap;
      padding-top: 100px;
    }

    .item {
      width: 240px;
      margin-left: 10px;
      padding: 20px 30px;
      transition: all .5s;
      margin-bottom: 20px;
    }

    .item:nth-child(4n) {
      margin-left: 0;
    }

    .item:hover {
      box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2);
      transform: translate3d(0, -4px, 0);
      cursor: pointer;
    }

    .item img {
      width: 100%;
    }

    .item .name {
      font-size: 18px;
      margin-bottom: 10px;
      color: #666;
    }

    .item .price {
      font-size: 22px;
      color: firebrick;
    }

    .item .price::before {
      content: "¥";
      font-size: 14px;
    }
  </style>
</head>

<body>
  <div class="list">
    <!-- <div class="item">
      <img src="" alt="">
      <p class="name"></p>
      <p class="price"></p>
    </div> -->
  </div>
  <script>
    const goodsList = [
      {
        id: '4001172',
        name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',
        price: '289.00',
        picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',
      },
      {
        id: '4001594',
        name: '日式黑陶功夫茶组双侧把茶具礼盒装',
        price: '288.00',
        picture: 'https://yanxuan-item.nosdn.127.net/3346b7b92f9563c7a7e24c7ead883f18.jpg',
      },
      {
        id: '4001009',
        name: '竹制干泡茶盘正方形沥水茶台品茶盘',
        price: '109.00',
        picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',
      },
      {
        id: '4001874',
        name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',
        price: '488.00',
        picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',
      },
      {
        id: '4001649',
        name: '大师监制龙泉青瓷茶叶罐',
        price: '139.00',
        picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',
      },
      {
        id: '3997185',
        name: '与众不同的口感汝瓷白酒杯套组1壶4杯',
        price: '108.00',
        picture: 'https://yanxuan-item.nosdn.127.net/8e21c794dfd3a4e8573273ddae50bce2.jpg',
      },
      {
        id: '3997403',
        name: '手工吹制更厚实白酒杯壶套装6壶6杯',
        price: '99.00',
        picture: 'https://yanxuan-item.nosdn.127.net/af2371a65f60bce152a61fc22745ff3f.jpg',
      },
      {
        id: '3998274',
        name: '德国百年工艺高端水晶玻璃红酒杯2支装',
        price: '139.00',
        picture: 'https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg',
      },
    ]

    // 1. 声明一个字符串变量
    let str = ''
    // 2. 遍历数据 
    goodsList.forEach(item => {
      // console.log(item)  // 可以得到每一个数组元素  对象 {id: '4001172'}
      // const {id} =  item  对象解构
      const { name, price, picture } = item
      str += `
      <div class="item">
        <img src=${picture} alt="">
        <p class="name">${name}</p>
        <p class="price">${price}</p>
      </div>
      `
    })
    // 3.生成的 字符串 添加给 list 
    document.querySelector('.list').innerHTML = str
  </script>
</body>

</html>
20-综合案例-价格筛选

在这里插入图片描述

<!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>商品渲染</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .list {
      width: 990px;
      margin: 0 auto;
      display: flex;
      flex-wrap: wrap;
    }

    .item {
      width: 240px;
      margin-left: 10px;
      padding: 20px 30px;
      transition: all .5s;
      margin-bottom: 20px;
    }

    .item:nth-child(4n) {
      margin-left: 0;
    }

    .item:hover {
      box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2);
      transform: translate3d(0, -4px, 0);
      cursor: pointer;
    }

    .item img {
      width: 100%;
    }

    .item .name {
      font-size: 18px;
      margin-bottom: 10px;
      color: #666;
    }

    .item .price {
      font-size: 22px;
      color: firebrick;
    }

    .item .price::before {
      content: "¥";
      font-size: 14px;
    }

    .filter {
      display: flex;
      width: 990px;
      margin: 0 auto;
      padding: 50px 30px;
    }

    .filter a {
      padding: 10px 20px;
      background: #f5f5f5;
      color: #666;
      text-decoration: none;
      margin-right: 20px;
    }

    .filter a:active,
    .filter a:focus {
      background: #05943c;
      color: #fff;
    }
  </style>
</head>

<body>
  <div class="filter">
    <a data-index="1" href="javascript:;">0-100元</a>
    <a data-index="2" href="javascript:;">100-300元</a>
    <a data-index="3" href="javascript:;">300元以上</a>
    <a href="javascript:;">全部区间</a>
  </div>
  <div class="list">
    <!-- <div class="item">
      <img src="" alt="">
      <p class="name"></p>
      <p class="price"></p>
    </div> -->
  </div>
  <script>
    // 2. 初始化数据
    const goodsList = [
      {
        id: '4001172',
        name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',
        price: '289.00',
        picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',
      },
      {
        id: '4001594',
        name: '日式黑陶功夫茶组双侧把茶具礼盒装',
        price: '288.00',
        picture: 'https://yanxuan-item.nosdn.127.net/3346b7b92f9563c7a7e24c7ead883f18.jpg',
      },
      {
        id: '4001009',
        name: '竹制干泡茶盘正方形沥水茶台品茶盘',
        price: '109.00',
        picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',
      },
      {
        id: '4001874',
        name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',
        price: '488.00',
        picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',
      },
      {
        id: '4001649',
        name: '大师监制龙泉青瓷茶叶罐',
        price: '139.00',
        picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',
      },
      {
        id: '3997185',
        name: '与众不同的口感汝瓷白酒杯套组1壶4杯',
        price: '108.00',
        picture: 'https://yanxuan-item.nosdn.127.net/8e21c794dfd3a4e8573273ddae50bce2.jpg',
      },
      {
        id: '3997403',
        name: '手工吹制更厚实白酒杯壶套装6壶6杯',
        price: '100.00',
        picture: 'https://yanxuan-item.nosdn.127.net/af2371a65f60bce152a61fc22745ff3f.jpg',
      },
      {
        id: '3998274',
        name: '德国百年工艺高端水晶玻璃红酒杯2支装',
        price: '139.00',
        picture: 'https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg',
      },
    ]

    // 1. 渲染函数  封装
    function render(arr) {
      // 声明空字符串
      let str = ''
      // 遍历数组 
      arr.forEach(item => {
        // 解构
        const { name, picture, price } = item
        str += `
         <div class="item">
          <img src=${picture} alt="">
          <p class="name">${name}</p>
          <p class="price">${price}</p>
        </div> 
        `
      })
      // 追加给list 
      document.querySelector('.list').innerHTML = str
    }
    render(goodsList)  // 页面一打开就需要渲染

    // 2. 过滤筛选  
    document.querySelector('.filter').addEventListener('click', e => {
      // e.target.dataset.index   e.target.tagName
      const { tagName, dataset } = e.target
      // 判断 
      if (tagName === 'A') {
        // console.log(11) 
        // arr 返回的新数组
        let arr = goodsList
        if (dataset.index === '1') {
          arr = goodsList.filter(item => item.price > 0 && item.price <= 100)
        } else if (dataset.index === '2') {
          arr = goodsList.filter(item => item.price >= 100 && item.price <= 300)
        } else if (dataset.index === '3') {
          arr = goodsList.filter(item => item.price >= 300)
        }
        // 渲染函数
        render(arr)
      }
    })
  </script>
</body>

</html>
21-filter筛选数组

在这里插入图片描述

  <script>
    const arr = [10, 20, 30]
    // const newArr = arr.filter(function (item, index) {
    //   // console.log(item)
    //   // console.log(index)
    //   return item >= 20
    // })
    // 返回的符合条件的新数组

    const newArr = arr.filter(item => item >= 20)
    console.log(newArr)
  </script>

JavaScript进阶第二天

02-创建对象
  <script>
    // const obj = new Object()
    // obj.uname = 'pink老师'
    // console.log(obj)
    const obj = new Object({ uname: 'pink' })
    console.log(obj)
  </script>
03-自己定义构造函数创建对象
<!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>
</head>

<body>
  <script>
    // 创建一个猪 构造函数 
    function Pig(uname, age) {
      this.uname = uname
      this.age = age
    }

    // console.log(new Pig('佩奇', 6))
    // console.log(new Pig('乔治', 3))
    const p = new Pig('佩奇', 6)
    console.log(p)

    //  const pepa = { uname: '佩奇', age: 6 }

    // const obj = new Object()

    function Goods(name, price, count) {
      this.name = name
      this.price = price
      this.count = count
      this.sayhi = function () { }
    }
    const mi = new Goods('小米', 1999, 20)
    console.log(mi)
    const hw = new Goods('华为', 3999, 59)
    console.log(hw)
    console.log(mi === hw)
    mi.name = 'vivo'
    console.log(mi)
    console.log(hw)
    // const date = new Date('2022-4-8')
    // console.log(date)

    // 静态成员 
    Goods.num = 10
    console.log(Goods.num)
    Goods.sayhi = function () { }
  </script>
</body>

</html>
04-基本包装类型

str.length

  <script>
    // const str = 'pink'
    // console.log(str.length)
    // const num = 12
    // console.log(num.toFixed(2))
    // const str = 'pink'
    // js 底层完成, 把简单数据类型包装为了引用数据类型
    // const str = new String('pink')
  </script>
05-Object静态方法

在这里插入图片描述

  <script>
    const o = { uname: 'pink', age: 18 }
    // 1.获得所有的属性名
    console.log(Object.keys(o))  //返回数组['uname', 'age']
    // 2. 获得所有的属性值
    console.log(Object.values(o))  //  ['pink', 18]
    // 3. 对象的拷贝
    // const oo = {}
    // Object.assign(oo, o)
    // console.log(oo)
    Object.assign(o, { gender: '女' })
    console.log(o)
  </script>
06-数组reduce方法

在这里插入图片描述

  <script>
    // arr.reduce(function(累计值, 当前元素){}, 起始值)
    // arr.reduce(function (prev, item) {
    //   // console.log(11)
    //   // console.log(prev)
    //   return prev + item
    // }, 0)
    // arr.reduce(function (prev, item) {
    //   console.log(11)
    //   // console.log(prev)
    //   return prev + item
    // })

    const arr = [1, 2, 3]
    const re = arr.reduce((prev, item) => prev + item)
    console.log(re)
  </script>
07-课堂案例-涨薪

在这里插入图片描述

  <script>
    const arr = [{
      name: '张三',
      salary: 10000
    }, {
      name: '李四',
      salary: 10000
    }, {
      name: '王五',
      salary: 20000
    },
    ]
    // 涨薪的钱数  10000 * 0.3 
    // const money = arr.reduce(function (prev, item) {
    //   return prev + item.salary * 0.3
    // }, 0)
    const money = arr.reduce((prev, item) => prev + item.salary * 1.3, 0)
    console.log(money)
  </script>
08-Array常用方法

find只找一个,every是每一个
在这里插入图片描述

  <script>
    // const arr = ['red', 'blue', 'green']
    // const re = arr.find(function (item) {
    //   return item === 'blue'
    // })
    // console.log(re)

    const arr = [
      {
        name: '小米',
        price: 1999
      },
      {
        name: '华为',
        price: 3999
      },
    ]
    // 找小米 这个对象,并且返回这个对象
    // const mi = arr.find(function (item) {
    //   // console.log(item)  //
    //   // console.log(item.name)  //
    //   console.log(111)
    //   return item.name === '华为'
    // })
    // 1. find 查找
    // const mi = arr.find(item => item.name === '小米')
    // console.log(mi)
    // 2. every 每一个是否都符合条件,如果都符合返回 true ,否则返回false
    const arr1 = [10, 20, 30]
    const flag = arr1.every(item => item >= 20)
    console.log(flag)
  </script>
09-课堂小案例1

在这里插入图片描述

<body>
  <div></div>
  <script>
    const spec = { size: '40cm*40cm', color: '黑色' }
    //1. 所有的属性值回去过来  数组
    // console.log(Object.values(spec))
    // 2. 转换为字符串   数组join('/') 把数组根据分隔符转换为字符串
    // console.log(Object.values(spec).join('/'))
    document.querySelector('div').innerHTML = Object.values(spec).join('/')
  </script>
</body>
10-伪数组转换为真数组

在这里插入图片描述

<body>
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
  </ul>
  <script>
    //  Array.from(lis) 把伪数组转换为真数组
    const lis = document.querySelectorAll('ul li')
    // console.log(lis)
    // lis.pop() 报错
    const liss = Array.from(lis)
    liss.pop()
    console.log(liss)
  </script>
</body>
11-String常见方法
  <script>
    //1. split 把字符串 转换为 数组  和 join() 相反
    // const str = 'pink,red'
    // const arr = str.split(',')
    // console.log(arr)
    // const str1 = '2022-4-8'
    // const arr1 = str1.split('-')
    // console.log(arr1)
    // 2. 字符串的截取   substring(开始的索引号[, 结束的索引号])
    // 2.1 如果省略 结束的索引号,默认取到最后
    // 2.2 结束的索引号不包含想要截取的部分
    // const str = '今天又要做核酸了'
    // console.log(str.substring(5, 7))
    // 3. startsWith 判断是不是以某个字符开头
    // const str = 'pink老师上课中'
    // console.log(str.startsWith('pink'))
    // 4. includes 判断某个字符是不是包含在一个字符串里面
    const str = '我是pink老师'
    console.log(str.includes('pink')) // true
  </script>
12-课堂小案例2

在这里插入图片描述

<body>
  <div></div>
  <script>
    const gift = '50g的茶叶,清洗球'
    // 1. 把字符串拆分为数组
    // console.log(gift.split(',')) [,]
    // 2. 根据数组元素的个数,生成 对应 span标签
    // const str = gift.split(',').map(function (item) {
    //   return `<span>【赠品】 ${item}</span> <br>`
    // }).join('')

    // // console.log(str)
    // document.querySelector('div').innerHTML = str
    document.querySelector('div').innerHTML = gift.split(',').map(item => `<span>【赠品】 ${item}</span> <br>`).join('')
  </script>
</body>
13-toFixed方法

在这里插入图片描述

<body>
  <script>
    // toFixed 方法可以让数字指定保留的小数位数
    const num = 10.923
    // console.log(num.toFixed())
    console.log(num.toFixed(1))
    const num1 = 10
    console.log(num1.toFixed(2))
  </script>
</body>
14-综合案例

NG: const total = goodsList.reduce((pre,item)=>{ pre + (item.price 100 item.count)/100},0)
OK: const total = goodsList.reduce((prev, item) => prev + (item.price * 100 * item.count) / 100, 0)
在这里插入图片描述

<!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-sizing: border-box;
    }

    .list {
      width: 990px;
      margin: 100px auto 0;
    }

    .item {
      padding: 15px;
      transition: all .5s;
      display: flex;
      border-top: 1px solid #e4e4e4;
    }

    .item:nth-child(4n) {
      margin-left: 0;
    }

    .item:hover {
      cursor: pointer;
      background-color: #f5f5f5;
    }

    .item img {
      width: 80px;
      height: 80px;
      margin-right: 10px;
    }

    .item .name {
      font-size: 18px;
      margin-right: 10px;
      color: #333;
      flex: 2;
    }

    .item .name .tag {
      display: block;
      padding: 2px;
      font-size: 12px;
      color: #999;
    }

    .item .price,
    .item .sub-total {
      font-size: 18px;
      color: firebrick;
      flex: 1;
    }

    .item .price::before,
    .item .sub-total::before,
    .amount::before {
      content: "¥";
      font-size: 12px;
    }

    .item .spec {
      flex: 2;
      color: #888;
      font-size: 14px;
    }

    .item .count {
      flex: 1;
      color: #aaa;
    }

    .total {
      width: 990px;
      margin: 0 auto;
      display: flex;
      justify-content: flex-end;
      border-top: 1px solid #e4e4e4;
      padding: 20px;
    }

    .total .amount {
      font-size: 18px;
      color: firebrick;
      font-weight: bold;
      margin-right: 50px;
    }
  </style>
</head>

<body>
  <div class="list">
    <!-- <div class="item">
      <img src="https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg" alt="">
      <p class="name">称心如意手摇咖啡磨豆机咖啡豆研磨机 <span class="tag">【赠品】10优惠券</span></p>
      <p class="spec">白色/10寸</p>
      <p class="price">289.90</p>
      <p class="count">x2</p>
      <p class="sub-total">579.80</p>
    </div> -->
  </div>
  <div class="total">
    <div>合计:<span class="amount">1000.00</span></div>
  </div>
  <script>
    const goodsList = [
      {
        id: '4001172',
        name: '称心如意手摇咖啡磨豆机咖啡豆研磨机',
        price: 289.9,
        picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg',
        count: 2,
        spec: { color: '白色' }
      },
      {
        id: '4001009',
        name: '竹制干泡茶盘正方形沥水茶台品茶盘',
        price: 109.8,
        picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png',
        count: 3,
        spec: { size: '40cm*40cm', color: '黑色' }
      },
      {
        id: '4001874',
        name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器',
        price: 488,
        picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png',
        count: 1,
        spec: { color: '青色', sum: '一大四小' }
      },
      {
        id: '4001649',
        name: '大师监制龙泉青瓷茶叶罐',
        price: 139,
        picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png',
        count: 1,
        spec: { size: '小号', color: '紫色' },
        gift: '50g茶叶,清洗球,宝马, 奔驰'
      }
    ]

    // 1. 根据数据渲染页面
    document.querySelector('.list').innerHTML = goodsList.map(item => {
      // console.log(item)  // 每一条对象
      // 对象解构  item.price item.count
      const { picture, name, count, price, spec, gift } = item
      // 规格文字模块处理
      const text = Object.values(spec).join('/')
      // 计算小计模块 单价 * 数量  保留两位小数 
      // 注意精度问题,因为保留两位小数,所以乘以 100  最后除以100
      const subTotal = ((price * 100 * count) / 100).toFixed(2)
      // 处理赠品模块 '50g茶叶,清洗球'
      const str = gift ? gift.split(',').map(item => `<span class="tag">【赠品】${item}</span> `).join('') : ''
      return `
        <div class="item">
          <img src=${picture} alt="">
          <p class="name">${name} ${str} </p>
          <p class="spec">${text} </p>
          <p class="price">${price.toFixed(2)}</p>
          <p class="count">x${count}</p>
          <p class="sub-total">${subTotal}</p>
        </div>
      `
    }).join('')

    // 3. 合计模块
    const total = goodsList.reduce((prev, item) => prev + (item.price * 100 * item.count) / 100, 0)
    // console.log(total)
    document.querySelector('.amount').innerHTML = total.toFixed(2)
  </script>
</body>

</html>
15-转换为字符串
  <script>
    const num = 10
    console.log(String(num))
    console.log(num.toString())
  </script>

JavaScript进阶第三天

01-构造函数

在这里插入图片描述

  <script>
    // 构造函数  公共的属性和方法 封装到 Star 构造函数里面了
    // 1.公共的属性写到 构造函数里面
    function Star(uname, age) {
      this.uname = uname
      this.age = age
      // this.sing = function () {
      //   console.log('唱歌')
      // }
    }
    // 2. 公共的方法写到原型对象身上   节约了内存
    Star.prototype.sing = function () {
      console.log('唱歌')
    }
    const ldh = new Star('刘德华', 55)
    const zxy = new Star('张学友', 58)
    ldh.sing() //调用
    zxy.sing() //调用
    // console.log(ldh === zxy)  // false
    console.log(ldh.sing === zxy.sing)

    // console.dir(Star.prototype)
  </script>
02-构造函数和原型的this指向

在这里插入图片描述
原型对象里面的函数this指向的还是 实例对象 ldh

  <script>
    let that
    function Star(uname) {
      // that = this
      // console.log(this)
      this.uname = uname
    }
    // 原型对象里面的函数this指向的还是 实例对象 ldh
    Star.prototype.sing = function () {
      that = this
      console.log('唱歌')
    }
    // 实例对象 ldh   
    // 构造函数里面的 this 就是  实例对象  ldh
    const ldh = new Star('刘德华')
    ldh.sing()
    console.log(that === ldh)
  </script>
03-数组扩展最大值和求和方法

原型函数里面的this 指向谁? 实例对象 arr

  <script>
    // 自己定义 数组扩展方法  求和 和 最大值 
    // 1. 我们定义的这个方法,任何一个数组实例对象都可以使用
    // 2. 自定义的方法写到  数组.prototype 身上
    // 1. 最大值
    const arr = [1, 2, 3]
    Array.prototype.max = function () {
      // 展开运算符
      return Math.max(...this)
      // 原型函数里面的this 指向谁? 实例对象 arr
    }
    // 2. 最小值
    Array.prototype.min = function () {
      // 展开运算符
      return Math.min(...this)
      // 原型函数里面的this 指向谁? 实例对象 arr
    }
    console.log(arr.max())
    console.log([2, 5, 9].max())
    console.log(arr.min())
    // const arr = new Array(1, 2)
    // console.log(arr)
    // 3. 求和 方法 
    Array.prototype.sum = function () {
      return this.reduce((prev, item) => prev + item, 0)
    }
    console.log([1, 2, 3].sum())
    console.log([11, 21, 31].sum())
  </script>
04-constructor属性

在这里插入图片描述

  <script>
    // constructor  单词 构造函数

    // Star.prototype.sing = function () {
    //   console.log('唱歌')
    // }
    // Star.prototype.dance = function () {
    //   console.log('跳舞')
    // }
    function Star() {
    }
    // console.log(Star.prototype)
    Star.prototype = {
      // 从新指回创造这个原型对象的 构造函数
      constructor: Star,
      sing: function () {
        console.log('唱歌')
      },
      dance: function () {
        console.log('跳舞')
      },
    }
    console.log(Star.prototype)
    // console.log(Star.prototype.constructor)

    // const ldh = new Star()
    // console.log(Star.prototype.constructor === Star)
  </script>
05-对象原型

在这里插入图片描述

  <script>
    function Star() {

    }
    const ldh = new Star()
    // 对象原型__proto__ 指向 改构造函数的原型对象
    console.log(ldh.__proto__)
    // console.log(ldh.__proto__ === Star.prototype)
    // 对象原型里面有constructor 指向 构造函数 Star
    console.log(ldh.__proto__.constructor === Star)

  </script>
06-原型继承(难)
  <script>
    // 继续抽取   公共的部分放到原型上
    // const Person1 = {
    //   eyes: 2,
    //   head: 1
    // }
    // const Person2 = {
    //   eyes: 2,
    //   head: 1
    // }
    // 构造函数  new 出来的对象 结构一样,但是对象不一样
    function Person() {
      this.eyes = 2
      this.head = 1
    }
    // console.log(new Person)
    // 女人  构造函数   继承  想要 继承 Person
    function Woman() {

    }
    // Woman 通过原型来继承 Person
    // 父构造函数(父类)   子构造函数(子类)
    // 子类的原型 =  new 父类  
    Woman.prototype = new Person()   // {eyes: 2, head: 1} 
    // 指回原来的构造函数
    Woman.prototype.constructor = Woman

    // 给女人添加一个方法  生孩子
    Woman.prototype.baby = function () {
      console.log('宝贝')
    }
    const red = new Woman()
    console.log(red)
    // console.log(Woman.prototype)
    // 男人 构造函数  继承  想要 继承 Person
    function Man() {

    }
    // 通过 原型继承 Person
    Man.prototype = new Person()
    Man.prototype.constructor = Man
    const pink = new Man()
    console.log(pink)
  </script>
07-原型链

在这里插入图片描述

  <script>
    // function Objetc() {}
    console.log(Object.prototype)
    console.log(Object.prototype.__proto__)

    function Person() {

    }
    const ldh = new Person()
    // console.log(ldh.__proto__ === Person.prototype)
    // console.log(Person.prototype.__proto__ === Object.prototype)
    console.log(ldh instanceof Person)
    console.log(ldh instanceof Object)
    console.log(ldh instanceof Array)
    console.log([1, 2, 3] instanceof Array)
    console.log(Array instanceof Object)
  </script>
08-综合案例(TBD)

在这里插入图片描述

<!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>面向对象封装消息提示</title>
  <style>
    .modal {
      width: 300px;
      min-height: 100px;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
      border-radius: 4px;
      position: fixed;
      z-index: 999;
      left: 50%;
      top: 50%;
      transform: translate3d(-50%, -50%, 0);
      background-color: #fff;
    }

    .modal .header {
      line-height: 40px;
      padding: 0 10px;
      position: relative;
      font-size: 20px;
    }

    .modal .header i {
      font-style: normal;
      color: #999;
      position: absolute;
      right: 15px;
      top: -2px;
      cursor: pointer;
    }

    .modal .body {
      text-align: center;
      padding: 10px;
    }

    .modal .footer {
      display: flex;
      justify-content: flex-end;
      padding: 10px;
    }

    .modal .footer a {
      padding: 3px 8px;
      background: #ccc;
      text-decoration: none;
      color: #fff;
      border-radius: 2px;
      margin-right: 10px;
      font-size: 14px;
    }

    .modal .footer a.submit {
      background-color: #369;
    }
  </style>
</head>

<body>
  <button id="delete">删除</button>
  <button id="login">登录</button>

  <!-- <div class="modal">
    <div class="header">温馨提示 <i>x</i></div>
    <div class="body">您没有删除权限操作</div>
  </div> -->


  <script>
    // 1.  模态框的构造函数
    function Modal(title = '', message = '') {
      // 公共的属性部分
      this.title = title
      this.message = message
      // 因为盒子是公共的
      // 1. 创建 一定不要忘了加 this 
      this.modalBox = document.createElement('div')
      // 2. 添加类名
      this.modalBox.className = 'modal'
      // 3. 填充内容 更换数据
      this.modalBox.innerHTML = `
        <div class="header">${this.title} <i>x</i></div>
        <div class="body">${this.message}</div>
      `
      // console.log(this.modalBox)
    }
    // 2. 打开方法 挂载 到 模态框的构造函数原型身上
    Modal.prototype.open = function () {
      if (!document.querySelector('.modal')) {
        // 把刚才创建的盒子 modalBox  渲染到 页面中  父元素.appendChild(子元素)
        document.body.appendChild(this.modalBox)
        // 获取 x  调用关闭方法
        this.modalBox.querySelector('i').addEventListener('click', () => {
          // 箭头函数没有this 上一级作用域的this
          // 这个this 指向 m 
          this.close()
        })
      }
    }
    // 3. 关闭方法 挂载 到 模态框的构造函数原型身上
    Modal.prototype.close = function () {
      document.body.removeChild(this.modalBox)
    }

    // 4. 按钮点击
    document.querySelector('#delete').addEventListener('click', () => {
      const m = new Modal('温馨提示', '您没有权限删除')
      // 调用 打开方法
      m.open()
    })

    // 5. 按钮点击
    document.querySelector('#login').addEventListener('click', () => {
      const m = new Modal('友情提示', '您还么有注册账号')
      // 调用 打开方法
      m.open()
    })

  </script>
</body>

</html>

JavaScript进阶第四天

02-直接复制对象的问题

在这里插入图片描述

  <script>
    const obj = {
      uname: 'pink',
      age: 18
    }
    const o = obj
    console.log(o)
    o.age = 20
    console.log(o)
    console.log(obj)
  </script>
03-浅拷贝

在这里插入图片描述

  <script>
    const obj = {
      uname: 'pink',
      age: 18,
      family: {
        baby: '小pink'
      }
    }
    // 浅拷贝
    // const o = { ...obj }
    // console.log(o)
    // o.age = 20
    // console.log(o)
    // console.log(obj)
    const o = {}
    Object.assign(o, obj)
    o.age = 20
    o.family.baby = '老pink'
    console.log(o)
    console.log(obj)
  </script>
04-递归函数

在这里插入图片描述

  <script>
    let i = 1
    function fn() {
      console.log(`这是第${i}`)
      if (i >= 6) {
        return
      }
      i++
      fn()
    }
    fn()
  </script>
05-模拟setInterval效果

递归
在这里插入图片描述

<body>
  <div></div>
  <script>
    function getTime() {
      document.querySelector('div').innerHTML = new Date().toLocaleString()
      setTimeout(getTime, 1000)
    }
    getTime()
  </script>
</body>
06-深拷贝

在这里插入图片描述

 <script>
    const obj = {
      uname: 'pink',
      age: 18,
      hobby: ['乒乓球', '足球'],
      family: {
        baby: '小pink'
      }
    }
    const o = {}
    // 拷贝函数
    function deepCopy(newObj, oldObj) {
      debugger
      for (let k in oldObj) {
        // 处理数组的问题  一定先写数组 在写 对象 不能颠倒
        if (oldObj[k] instanceof Array) {
          newObj[k] = []
          //  newObj[k] 接收 []  hobby
          //  oldObj[k]   ['乒乓球', '足球']
          deepCopy(newObj[k], oldObj[k])
        } else if (oldObj[k] instanceof Object) {
          newObj[k] = {}
          deepCopy(newObj[k], oldObj[k])
        }
        else {
          //  k  属性名 uname age    oldObj[k]  属性值  18
          // newObj[k]  === o.uname  给新对象添加属性
          newObj[k] = oldObj[k]
        }
      }
    }
    deepCopy(o, obj) // 函数调用  两个参数 o 新对象  obj 旧对象
    console.log(o)
    o.age = 20
    o.hobby[0] = '篮球'
    o.family.baby = '老pink'
    console.log(obj)
    console.log([1, 23] instanceof Object)
    // 复习
    // const obj = {
    //   uname: 'pink',
    //   age: 18,
    //   hobby: ['乒乓球', '足球']
    // }
    // function deepCopy({ }, oldObj) {
    //   // k 属性名  oldObj[k] 属性值
    //   for (let k in oldObj) {
    //     // 处理数组的问题   k 变量
    //     newObj[k] = oldObj[k]
    //     // o.uname = 'pink'
    //     // newObj.k  = 'pink'
    //   }
    // }
  </script>
07-lodash实现深拷贝

在这里插入图片描述

  <!-- 先引用 -->
  <script src="./lodash.min.js"></script>
  <script>
    const obj = {
      uname: 'pink',
      age: 18,
      hobby: ['乒乓球', '足球'],
      family: {
        baby: '小pink'
      }
    }
    const o = _.cloneDeep(obj)
    console.log(o)
    o.family.baby = '老pink'
    console.log(obj)
  </script>
08-利用JSON实现深拷贝

在这里插入图片描述

转化为字符串

  <script>
    const obj = {
      uname: 'pink',
      age: 18,
      hobby: ['乒乓球', '足球'],
      family: {
        baby: '小pink'
      }
    }
    // 把对象转换为 JSON 字符串
    // console.log(JSON.stringify(obj))
    const o = JSON.parse(JSON.stringify(obj))
    console.log(o)
    o.family.baby = '123'
    console.log(obj)
  </script>
09-throw抛出异常

在这里插入图片描述

  <script>
    function fn(x, y) {
      if (!x || !y) {
        // throw '没有参数传递进来'
        throw new Error('没有参数传递过来')
      }

      return x + y
    }
    console.log(fn())
  </script>
10-try-catch捕获异常
<body>
  <p>123</p>
  <script>
    function fn() {
      try {
        // 可能发送错误的代码 要写到 try
        const p = document.querySelector('.p')
        p.style.color = 'red'
      } catch (err) {
        // 拦截错误,提示浏览器提供的错误信息,但是不中断程序的执行
        console.log(err.message)
        throw new Error('你看看,选择器错误了吧')
        // 需要加return 中断程序
        // return
      }
      finally {
        // 不管你程序对不对,一定会执行的代码
        alert('弹出对话框')
      }
      console.log(11)
    }
    fn()
  </script>
</body>
11-普通函数的this指向
<body>
  <button>点击</button>
  <script>
    // 普通函数:  谁调用我,this就指向谁
    console.log(this)  // window
    function fn() {
      console.log(this)  // window    
    }
    window.fn()
    window.setTimeout(function () {
      console.log(this) // window 
    }, 1000)
    document.querySelector('button').addEventListener('click', function () {
      console.log(this)  // 指向 button
    })
    const obj = {
      sayHi: function () {
        console.log(this)  // 指向 obj
      }
    }
    obj.sayHi()
  </script>
</body>
12-call

非数组用apply

  <script>
    const obj = {
      uname: 'pink'
    }
    function fn(x, y) {
      console.log(this) // window
      console.log(x + y)
    }
    // 1. 调用函数  
    // 2. 改变 this 指向
    fn.call(obj, 1, 2)
  </script>
13-apply

数组用apply

  <script>
    const obj = {
      age: 18
    }
    function fn(x, y) {
      console.log(this) // {age: 18}
      console.log(x + y)
    }
    // 1. 调用函数
    // 2. 改变this指向 
    //  fn.apply(this指向谁, 数组参数)
    fn.apply(obj, [1, 2])
    // 3. 返回值   本身就是在调用函数,所以返回值就是函数的返回值

    // 使用场景: 求数组最大值
    // const max = Math.max(1, 2, 3)
    // console.log(max)
    const arr = [100, 44, 77]
    const max = Math.max.apply(Math, arr)
    const min = Math.min.apply(null, arr)
    console.log(max, min)
    // 使用场景: 求数组最大值
    console.log(Math.max(...arr))
  </script>
14-bind

不立即执行用bind
在这里插入图片描述

<body>
  <button>发送短信</button>
  <script>
    const obj = {
      age: 18
    }
    function fn() {
      console.log(this)
    }

    // 1. bind 不会调用函数 
    // 2. 能改变this指向
    // 3. 返回值是个函数,  但是这个函数里面的this是更改过的obj
    const fun = fn.bind(obj)
    // console.log(fun) 
    fun()

    // 需求,有一个按钮,点击里面就禁用,2秒钟之后开启
    document.querySelector('button').addEventListener('click', function () {
      // 禁用按钮
      this.disabled = true
      window.setTimeout(function () {
        // 在这个普通函数里面,我们要this由原来的window 改为 btn
        this.disabled = false
      }.bind(this), 2000)   // 这里的this 和 btn 一样
    })
  </script>
</body>

15-节流防抖素材(TBD)

在这里插入图片描述

<body>
  <div class="box"></div>
  <script>
    const box = document.querySelector('.box')
    let i = 1  // 让这个变量++
    // 鼠标移动函数
    function mouseMove() {
      box.innerHTML = ++i
      // 如果里面存在大量操作 dom 的情况,可能会卡顿
    }
    // console.log(mouseMove)
    // 节流函数 throttle 
    function throttle(fn, t) {
      // 起始时间
      let startTime = 0
      return function () {
        // 得到当前的时间
        let now = Date.now()
        // 判断如果大于等于 500 采取调用函数
        if (now - startTime >= t) {
          // 调用函数
          fn()
          // 起始的时间 = 现在的时间   写在调用函数的下面 
          startTime = now
        }
      }
    }
    box.addEventListener('mousemove', throttle(mouseMove, 500))

    // throttle(mouseMove, 500) === function () { console.log(1) }


    // box.addEventListener('mousemove', function () {
    //   // 得到当前的时间
    //   let now = Date.now()
    //   // 判断如果大于等于 500 采取调用函数
    //   if (now - startTime >= t) {
    //     // 调用函数
    //     fn()
    //     // 起始的时间 = 现在的时间   写在调用函数的下面
    //     startTime = now
    //   }
    // })

  </script>
</body>
16-防抖小案例(TBD)

在这里插入图片描述


<body>
  <div class="box"></div>
  <script>
    const box = document.querySelector('.box')
    let i = 1  // 让这个变量++
    // 鼠标移动函数
    function mouseMove() {
      box.innerHTML = ++i
      // 如果里面存在大量操作 dom 的情况,可能会卡顿
    }
    // 防抖函数
    function debounce(fn, t) {
      let timeId
      return function () {
        // 如果有定时器就清除
        if (timeId) clearTimeout(timeId)
        // 开启定时器 200
        timeId = setTimeout(function () {
          fn()
        }, t)
      }
    }
    // box.addEventListener('mousemove', mouseMove)
    box.addEventListener('mousemove', debounce(mouseMove, 200))

  </script>
</body>
17-lodash节流和防抖

在这里插入图片描述

<!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>
    .box {
      width: 500px;
      height: 500px;
      background-color: #ccc;
      color: #fff;
      text-align: center;
      font-size: 100px;
    }
  </style>
</head>

<body>
  <div class="box"></div>
  <script src="./lodash.min.js"></script>
  <script>
    const box = document.querySelector('.box')
    let i = 1  // 让这个变量++
    // 鼠标移动函数
    function mouseMove() {
      box.innerHTML = ++i
      // 如果里面存在大量操作 dom 的情况,可能会卡顿
    }

    // box.addEventListener('mousemove', mouseMove)
    // lodash 节流写法
    // box.addEventListener('mousemove', _.throttle(mouseMove, 500))
    // lodash 防抖的写法
    box.addEventListener('mousemove', _.debounce(mouseMove, 500))

  </script>
</body>

</html>
18-节流综合案例

在这里插入图片描述

<!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" />
  <meta name="referrer" content="never" />
  <title>综合案例</title>
  <style>
    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }

    .container {
      width: 1200px;
      margin: 0 auto;
    }

    .video video {
      width: 100%;
      padding: 20px 0;
    }

    .elevator {
      position: fixed;
      top: 280px;
      right: 20px;
      z-index: 999;
      background: #fff;
      border: 1px solid #e4e4e4;
      width: 60px;
    }

    .elevator a {
      display: block;
      padding: 10px;
      text-decoration: none;
      text-align: center;
      color: #999;
    }

    .elevator a.active {
      color: #1286ff;
    }

    .outline {
      padding-bottom: 300px;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="header">
      <a href="http://pip.itcast.cn">
        <img src="https://pip.itcast.cn/img/logo_v3.29b9ba72.png" alt="" />
      </a>
    </div>
    <div class="video">
      <video src="https://v.itheima.net/LapADhV6.mp4" controls></video>
    </div>
    <div class="elevator">
      <a href="javascript:;" data-ref="video">视频介绍</a>
      <a href="javascript:;" data-ref="intro">课程简介</a>
      <a href="javascript:;" data-ref="outline">评论列表</a>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
  <script>
    // 1. 获取元素  要对视频进行操作
    const video = document.querySelector('video')
    video.ontimeupdate = _.throttle(() => {
      // console.log(video.currentTime) 获得当前的视频时间
      // 把当前的时间存储到本地存储
      localStorage.setItem('currentTime', video.currentTime)
    }, 1000)

    // 打开页面触发事件,就从本地存储里面取出记录的时间, 赋值给  video.currentTime
    video.onloadeddata = () => {
      // console.log(111)
      video.currentTime = localStorage.getItem('currentTime') || 0
    }

  </script>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/832850.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

谷歌创始人布林重返职场,投入研发AI杀手锏!预计下半年推出下一代通用模型『Gemini』,和OpenAI的终局之战!

夕小瑶科技说 原创 作者 | 王思若 大家好&#xff0c;我是王思若。在大模型混战的当下&#xff0c;去繁就简&#xff0c;最核心的目标或者使命始终是通用人工智能AGI&#xff0c;但目前而言&#xff0c;也只有OpenAI和Google可能会在这个需要海量算力支撑和资金支持的方向上构…

【Spring】AOP切点表达式

文章目录 1、语法2、通配符3、execution4、within5、annotation6、args7、args8、bean9、this10、target11、target12、within13、表达式组合14、补充 1、语法 动作关键词(访问修饰符 返回值 包名.类/接口名 .方法名(参数)异常名) 举例&#xff1a; execution(public User c…

frida学习及使用

文章目录 安装frida安装python3.7设置环境变量安装pycharm和nodejs 使用frida将frida-server push到手机设备中端口转发安装apk使用jadx查看java代码运行frida-server frida源码阅读frida hook方法Frida Java层hoookJavaHook.javaJavaHook.js Frida native层hook 一NativeHook.…

【Leetcode】(自食用)找到消失的数字

step by step. 题目&#xff1a; 给你一个含 n 个整数的数组 nums &#xff0c;其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字&#xff0c;并以数组的形式返回结果。 示例 1&#xff1a; 输入&#xff1a;nums [4,3,2,7,8,2,3,1] 输…

模板方法模式——定义算法的框架

1、简介 1.1、概述 模板方法模式是结构最简单的行为型设计模式&#xff0c;在其结构中只存在父类与子类之间的继承关系。通过使用模板方法模式&#xff0c;可以将一些复杂流程的实现步骤封装在一系列基本方法中。在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法…

js沙箱逃逸

目录 一、什么是沙箱(sandbox) 二、沙箱技术的实现 & node.js 2.1简单沙箱程序示例 2.2this.tostring S1&#xff1a; S2&#xff1a; 三、arguments.callee.caller 一、什么是沙箱(sandbox) 在计算机安全性方面&#xff0c;沙箱&#xff08;沙盒、sanbox&#xff…

【【萌新的STM32学习-4】】

萌新的STM32学习-4 STM32系统框架 1.1 Cortex M 内核& 芯片 F1有四个驱动单元 四个被动单元 AHB 高级高性能总线 APB 高级外围总线 部分系统结构 最上面的ICode 总线直接连接到了内部Flash 不需要通过总线矩阵 . D Code 总线&#xff08;D - Bus&#xff09; 这是Cort…

Kubernetes高可用集群二进制部署(五)kubelet、kube-proxy、Calico、CoreDNS

Kubernetes概述 使用kubeadm快速部署一个k8s集群 Kubernetes高可用集群二进制部署&#xff08;一&#xff09;主机准备和负载均衡器安装 Kubernetes高可用集群二进制部署&#xff08;二&#xff09;ETCD集群部署 Kubernetes高可用集群二进制部署&#xff08;三&#xff09;部署…

Delphi Enterprise Crack

Delphi Enterprise Crack Delphi帮助您使用Object Pascal为Windows、Mac、Mobile、IoT和Linux构建和更新数据丰富、超连接、可视化的应用程序。Delphi Enterprise适合开发团队构建客户端/服务器或多层应用程序、REST服务等。 Delphi功能 单一代码库-用更少的编码工作为所有主要…

MySQL 详细学习教程【万字长文, 建议收藏】

目录 1. Mysql入门1.1 Mysql5.7 安装配置1.2 命令行连接到Mysql1.3 图形化软件1.3.1 Navicat1.3.2 SQLyog 1.4 数据库三层结构 2. Java操作数据库、表2.1 创建数据库2.2 查询数据库2.3 备份恢复数据库2.4 创建表2.5 修改表 3 CRUD3.1 insert插入3.2 update修改3.3 delete修改3.…

一篇文章搞定《LeakCanary源码详解(全)》

一篇文章搞定《LeakCanary源码解析》 前言LeakCanary和LeakCanary2区别LeakCanary的快速使用第一步&#xff1a;添加依赖第二步&#xff1a;初始化LeakCanary第三步&#xff1a;运行应用程序并监测内存泄漏 LeakCanary基础铺垫四大引用WeakReference和ReferenceQueueRefercence…

【Spring】(二)从零开始的 Spring 项目搭建与使用

文章目录 前言一、Spring 项目的创建1.1 创建 Maven 项目1.2 添加 Spring 框架支持1.3 添加启动类 二、储存 Bean 对象2.1 创建 Bean2.1 将 Bean 注册到 Spring 容器 三、获取并使用 Bean 对象3.1 获取Spring 上下文3.2 ApplicationContext 和 BeanFactory 的区别3.3 获取指定的…

2023-02-03——2023-08-03,半年以来与客服交流的记录【CSND 文章撰写 网站使用求解】客服咨询交流记录(长期更新ing)

这世界上久处不厌,都是因为用心。 🎯作者主页: 追光者♂🔥 🌸个人简介: 💖[1] 计算机专业硕士研究生💖 🌿[2] 2023年城市之星领跑者TOP1(哈尔滨)🌿 🌟[3] 2022年度博客之星人工智能领域TOP4🌟 🏅[4] 阿里云社区特邀专家博主🏅 🏆

Cesium 实战教程 - 调整 3dtiles 倾斜摄影大小

Cesium 实战教程 - 调整 3dtiles 倾斜摄影大小 核心代码完整代码在线示例 之前由于误解遇到一个特殊的需求&#xff1a;想要把三维球上叠加倾斜摄影进行自由放大缩小&#xff0c;跟随地图的缩放进行缩放。 后来经过搜索、尝试&#xff0c;终于实现了需求。 但是&#xff0c;后…

什么是强化学习?

&#x1f4dd;什么是强化学习&#xff1f; 1. &#x1f4dd;监督&#xff0c;非监督&#xff0c;强化2. &#x1f4dd;非 i.i.d3. &#x1f4dd;强化学习基本形式4. &#x1f4dd;马尔可夫过程 &#x1f31f; 强化学习&#xff08;Reinforcement Learning&#xff0c;RL&#x…

windows安装kafka配置SASL-PLAIN安全认证

目录 1.Windows安装zookeeper&#xff1a; 1.1下载zookeeper 1.2 解压之后如图二 1.3创建日志文件 1.4复制 “zoo_sample.cfg” 文件 1.5更改 “zoo.cfg” 配置 1.6新建zk_server_jaas.conf 1.7修改zkEnv.cmd 1.8导入相关jar 1.9以上配置就配好啦&#xff0c;接下来启…

小红书博主排名丨狂揽近百万粉丝,女性议题成“爆款制造机”?

从上野千鹤子和北大女生的对谈&#xff0c;到电影《消失的她》&#xff0c;再到引爆“粉色狂潮”的电影《芭比》&#xff0c;近年来&#xff0c;女性话题、两性情感话题成为社会热门议题。“踩过恋爱所有坑&#xff0c;想给姑娘撑把伞”&#xff0c;近期&#xff0c;小红书博主…

2023年华数杯数学建模B题思路代码分析 - 不透明制品最优配色方案设计

# 1 赛题 B 题 不透明制品最优配色方案设计 日常生活中五彩缤纷的不透明有色制品是由着色剂染色而成。因此&#xff0c;不透明 制品的配色对其外观美观度和市场竞争力起着重要作用。然而&#xff0c;传统的人工配色 存在一定的局限性&#xff0c;如主观性强、效率低下等。因此…

docker容器学习笔记1

docker容器是干什么用的 docker就是一个轻量级的虚拟机&#xff0c;是一个容器&#xff0c;隔离性好&#xff0c;能够确保环境的统一&#xff0c;有效利用系统资源&#xff0c;轻松迁移和拓展。简单的可以理解为容器就是一个小型功能齐全的虚拟机。 实际上是如何使用的呢&…

RocketMQ发送消息超时异常

说明&#xff1a;在使用RocketMQ发送消息时&#xff0c;出现下面这个异常&#xff08;org.springframework.messging.MessgingException&#xff1a;sendDefaultImpl call timeout……&#xff09;&#xff1b; 解决&#xff1a;修改RocketMQ中broke.conf配置&#xff0c;添加下…