js pink老师

JS 基础

输入和输出语法

向body输出内容

document.write("<h1>眼泪为你唱歌</h1>")

窗口弹出内容

alert("将军")

控制台打印内容

console.log("勇敢的面对");

输入语句

prompt("蓝色的雨")

image-20230721101759697

输入语句输出到页面

const name = prompt()
document.write(name)

变量和常量的命名

变量 用 let

常量 用 const

null 和 underfined 的区别

  • underfined 没有赋值
  • null 赋值了, 但是内容为空

null 作为未创建的对象

显式转换

String(false) // "false" 布尔值转换为字符串
Number("123") // 123 字符串转换为数值 
Boolean([])   // true 对象类型转换为布尔值
Object(123)   // new Number(123) 原始值通过Number()构造函数转换为基本包装类型

案例 输入手机价格输出到页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        h5 {
            text-align: center;
        }
        table {
            margin: 0 auto;
        }
        table {
            border-collapse: collapse;
        }
        th , tr {
            border: 1px pink solid;
        }
    </style>

    <script>
        let phone = prompt("请输入手机名")
        let price1 = +prompt("请输入单价")
        let num = +prompt("请输入数量")
        let con = prompt("请输入地址")
        let price2 = price1 * num
        document.write(`<h5>订单确认</h5>
    <table>
        <tr>
            <th>商品名称</th>
            <th>商品价格</th>
            <th>商品数量</th>
            <th>总价</th>
            <th>收货地址</th>
        </tr>

        <tr>
            <td>${phone}</td>
            <td>${price1}元</td>
            <td>${num}</td>
            <td>${price2}元</td>
            <td>${con}</td>
        </tr>
    </table>`)
    </script>
</head>
<body>



</body>
</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gCf5mnXY-1690198311345)(https://imgfff-1313020458.cos.ap-shanghai.myqcloud.com/images/%E6%88%B3%E7%9C%8B%E5%91%BD%E8%BD%A6%E6%A0%87%E5%8F%B7.gif)]

+++

分支循环存钱案例

    <script>
        // 最开始存了 100 元
        let money = 100
        while (true) {
            let input = +prompt("请选择操作:" +
                "1. 存钱" +
                "2. 取钱" +
                "3. 查看金额" +
                "4. 退出")
            if (input === 4) {
                break
            }
            switch (input) {
                case 1:
                    let mon1 = +prompt("请输入存的金额:")
                    money+=mon1
                    break
                case 2:
                    let mon2 = +prompt("请输入取的金额:")
                    money -= mon2;
                    break
                case 3:
                    alert(money)
                    break
            }
        }
    </script>

函数使用

定义两个重名的函数, 后面的会覆盖前面的

function f() {
    alert(1)
}
function f() {
    alert(2)
}
f()

此时打开页面, 弹窗数字 : 2

作用域

js中作用域分成全局作用域和局部作用域, 变量根据作用域来分, 分成全局变量和局部变量

函数的形参和函数内部的变量为局部变量

外部的就是全局变量

匿名函数

匿名函数直接调用有两种方法, 注意第一种后面加分号;

(function (x, y){alert(x+y)})(1,2);
// 或
(function (x, y){alert(x+y)}(1,2))

转换为 Boolean 型

’ ’ 0 undefined null false NaN 转换成布尔值是 false , 其余为 true

测试一下:

// ' '    0    undefined     null     false      NaN
console.log(Boolean(''));
console.log(Boolean(0));
console.log(Boolean(undefined));
console.log(Boolean(null));
console.log(Boolean(false));
console.log(Boolean(NaN));

Web APIs

前言

变量声明关键字

能用const 就用const , 如果报错了,再用 let

作用和分类

使用JS操作html和浏览器

分类: DOM 文档对象模型

BOM 浏览器对象模型

DOM 作用: 开发网页内容特效和实现用户交互, js 操作网页内容

DOM 树

文档树, 描述标签之间关系

html页面的结构不够清晰, 我们把页面变成DOM 模型

Dom 对象: 浏览器根据html标签生成的对象

document : DOM提供的一个对象, 网页所有内容都在document中

获取 DOM 元素

通过CSS 选择器, 获取DOM元素

<div class="head">
    <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
</div>
<script>
    console.log(document.querySelector('.head'));
    console.log(document.querySelectorAll('ul li'));
</script>

image-20230721160613873

+++

直接加点来操作元素

const head = document.querySelector('.head')
head.style.color = 'red'

而querySelectAll获取的是伪数组, 里面只有一个元素, 可以遍历, 不能调用数组的方法

    const head = document.querySelector('.head')
    head.style.color = 'red'
    const lis = document.querySelectorAll('ul li')
    lis[1].style.color = 'blue'

操作元素内容

innerText 方法改变字体文本内容

innerHtml 方法可以加html标签样式

    <div class="box">
        我是盒子内容
    </div>
    <script>
        const box = document.querySelector('.box');
        box.innerText = '我是你大爷'
    </script>

image-20230721163012410

+++

innerText 不识别里面的标签

box.innerText = '<strong>我是你大爷</strong>'

image-20230721163204409

+++

box.innerHTML = '<strong>我是你大爷</strong>'

image-20230721163252425

+++

操作元素属性

直接加点操作

测试一个更换路径, 实现图片替换

<div class="box">
  <img src="gou.jpg" alt="">
</div>
<script>
  const element = document.querySelector('.box img')
  element.src = 'lianlian.jpg'
</script>

通过style 操作 css

遇到 - 转小驼峰

	<div class="box">
    </div>
    <script>
        const box = document.querySelector('.box');
        box.style.width = '200px'
        box.style.height = '200px'
        box.style.backgroundColor = 'pink'
    </script>

image-20230721205105030

+++

这样通过style样式修改代码繁琐, 另一种方案:

在css代码中写好, 然后使用 document 修改类名即可, 这是我们所熟悉的

	<div class="box">
    </div>
    <script>
        const htmlDivElement = 		document.querySelector('div');
        htmlDivElement.className = 'box2'
    </script>

可以写多个

htmlDivElement.className = 'box box2';

这样有一个覆盖问题, 引出下一个方法

<script>
        const htmlDivElement = 	document.querySelector('div');
        // 追加
        htmlDivElement.classList.add('.box2')
        // 删除
        htmlDivElement.classList.remove('.box2')
        // 切换
        htmlDivElement.classList.toggle('.box2')
</script>

className 和 classList 的区别就是初王和第二代王

操作表单元素属性

表单元素操作方式一样的

选中input的value可以获取值

自定义属性

以 data- 开头的属性

    <div>
        <ul>
            <li data-id="1" data-spm="sm"></li>
            <li data-id="2"></li>
            <li data-id="3"></li>
            <li data-id="4"></li>
            <li data-id="5"></li>
        </ul>
    </div>
    <script>
        const htmlDivElement = document.querySelector('li');
        console.log(htmlDivElement.dataset.id);  // 1
        console.log(htmlDivElement.dataset.spm); // sm
    </script>

image-20230721221554923

+++

定时器 间歇函数

setTimeout 延时时间到了, 调用回调函数

	<button>点击停止定时器</button>
    <script>
        const htmlButtonElement = document.querySelector('button');
        let f = setTimeout(function () {
            alert('我是神皮')
        }, 5000)
        htmlButtonElement.addEventListener("click",
            function () {
                clearTimeout(f)
            }
        )
    </script>

这个函数, 5s调用仅一次, 提前点击按钮可以阻止调用函数

+++

setInterval 每隔这个延时时间会调用回调函数, 重复调用

		function show() {
            console.log("找到工作");
        }
        setInterval(show, 1000);

+++

配合变量和回调函数使用

<button>点击停止定时器</button>
    <script>
        let a = 1
        let setInter = setInterval(function () {
            a++
            console.log(a);
        }, 200)
        const htmlButtonElement = document.querySelector('button');
        htmlButtonElement.addEventListener("click", function () {
            clearInterval(setInter)
        })
    </script>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WeGzTFfs-1690198311349)(https://imgfff-1313020458.cos.ap-shanghai.myqcloud.com/images/%E5%B7%A5%E9%9E%A5%E6%90%AC%E7%A0%96.gif)]

+++

倒计时效果

<body>
    <textarea cols="30" id="" name="" rows="10">
        用户注册协议
        欢迎注册成为京东用户!在您注册过程中,您需要完成我们的注册流程并通过点击同意的形式在线签署以下协议,请您务必仔细阅读、充分理解协议中的条款内容后再点击同意(尤其是以粗体或下划线标识的条款,因为这些条款可能会明确您应履行的义务或对您的权利有所限制)。
        【请您注意】如果您不同意以下协议全部或任何条款约定,请您停止注册。您停止注册后将仅可以浏览我们的商品信息但无法享受我们的产品或服务。如您按照注册流程提示填写信息,阅读并点击同意上述协议且完成全部注册流程后,即表示您已充分阅读、理解并接受协议的全部内容,并表明您同意我们可以依据协议内容来处理您的个人信息,并同意我们将您的订单信息共享给为完成此订单所必须的第三方合作方(详情查看
    </textarea>
    <br>
    <button class="btn" disabled>我已经阅读用户协议(6)</button>

    <script>
        let element = document.querySelector('.btn');
        let i = 6
        let inter = setInterval(
            function () {
                i--
                element.innerHTML = `我已经阅读用户协议(${i})`
                if (i === 0) {
                    clearInterval(inter)
                    element.disabled =  false
                    element.innerText = `注册成功`
                }
            }, 1000
        )
    </script>
</body>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bpS4Gt0n-1690198311349)(https://imgfff-1313020458.cos.ap-shanghai.myqcloud.com/images/%E5%A4%8D%E6%B5%8B%E8%A7%84%E8%8C%83.gif)]

+++

事件监听

概念: 让程序检测是否有事件产生, 一旦有事件触发, 立即调用一个函数做出

响应, 也叫绑定事件或注册事件, 比如鼠标经过显示下拉菜单, 点击可以播放轮播图等等

对象.addEventListener(‘事件类型’, 要执行的函数 )

事件监听三要素:

  • 事件源: 哪个dom元素被事件触发, 获取这个dom元素
  • 事件类型: 用什么方式触发, 比如鼠标单击, 鼠标经过
  • 事件调用的函数, 要做什么事

随机点名案例

<h3>随机点名</h3>
<div>
    名字是:
    <span class="name">这里显示名字</span>
</div>
<button class="btn1">开始</button>
<button class="btn2">结束</button>

<script>
    const array = ['张飞', '关羽', '赵云', '马超', '黄忠'];
    const name = document.querySelector(".name");
    const btn1 = document.querySelector(".btn1");
    const btn2 = document.querySelector(".btn2");


    function getRandom(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min
    }
    let demo;

    btn1.addEventListener('click',
        function () {
        demo = setInterval(function () {
            let random = getRandom(0, 4);
            name.innerText = array[random]
        }, 100)
    })

    btn2.addEventListener('click', function () {
        clearInterval(demo)
    })

</script>

58415415413

+++

事件类型

鼠标事件

鼠标触发 click mouseenter mouseleave

焦点事件

表单获得光标 focus blur

键盘事件

键盘触发 keydown keyup

文本事件

表单输入触发 input

image-20230722113133809

+++

<!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;
        }

        ul {

            list-style: none;
        }

        .mi {
            position: relative;
            width: 223px;
            margin: 100px auto;
        }

        .mi input {
            width: 223px;
            height: 48px;
            padding: 0 10px;
            font-size: 14px;
            line-height: 48px;
            border: 1px solid #e0e0e0;
            outline: none;
        }

        .mi .search {
            border: 1px solid #ff6700;
        }

        .result-list {
            display: none;
            position: absolute;
            left: 0;
            top: 48px;
            width: 223px;
            border: 1px solid #ff6700;
            border-top: 0;
            background: #fff;
        }

        .result-list a {
            display: block;
            padding: 6px 15px;
            font-size: 12px;
            color: #424242;
            text-decoration: none;
        }

        .result-list a:hover {
            background-color: #eee;
        }
    </style>

</head>

<body>
    <div class="mi">
        <input type="search" placeholder="小米笔记本">
        <ul class="result-list">
            <li><a href="#">全部商品</a></li>
            <li><a href="#">小米11</a></li>
            <li><a href="#">小米10S</a></li>
            <li><a href="#">小米笔记本</a></li>
            <li><a href="#">小米手机</a></li>
            <li><a href="#">黑鲨4</a></li>
            <li><a href="#">空调</a></li>
        </ul>
    </div>
    <script>
        const element = document.querySelector('[type=search]');
        const element1 = document.querySelector('.result-list');
        element.addEventListener('focus', function () {
            element1.style.display = 'block'
        })
        element.addEventListener('blur', function () {
            element1.style.display = 'none'
        })
    </script>
</body>

</html>

ccc

+++

事件对象

事件绑定的回调函数的第一个参数是事件对象, 取名为e

元素.addEventListener('click', function(e) {
})

回车键打印内容

<input type="text">
<script>
    const htmlInputElement = document.querySelector('input');
    htmlInputElement.addEventListener('keyup', function (e) {
        if (e.key === 'Enter')
            console.log("你按下了回车键");
    })
</script>

案例 bilibili发布评论

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

<head>
    <meta charset="UTF-8">
    <meta content="IE=edge" http-equiv="X-UA-Compatible">
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
    <title>评论回车发布</title>
    <style>
        .wrapper {
            min-width: 400px;
            max-width: 800px;
            display: flex;
            justify-content: flex-end;
        }

        .avatar {
            width: 48px;
            height: 48px;
            border-radius: 50%;
            overflow: hidden;
            margin-right: 20px;
        }

        .wrapper textarea {
            outline: none;
            border-color: transparent;
            resize: none;
            background: #f5f5f5;
            border-radius: 4px;
            flex: 1;
            padding: 10px;
            transition: all 0.5s;
            height: 30px;
        }

        .wrapper textarea:focus {
            border-color: #e4e4e4;
            background: #fff;
            height: 50px;
        }

        .wrapper button {
            background: #00aeec;
            color: #fff;
            border: none;
            border-radius: 4px;
            margin-left: 10px;
            width: 70px;
            cursor: pointer;
        }

        .wrapper .total {
            margin-right: 80px;
            color: #999;
            margin-top: 5px;
            opacity: 0;
            transition: all 0.5s;
        }

        .list {
            min-width: 400px;
            max-width: 800px;
            display: flex;
        }

        .list .item {
            width: 100%;
            display: flex;
        }

        .list .item .info {
            flex: 1;
            border-bottom: 1px dashed #e4e4e4;
            padding-bottom: 10px;
        }

        .list .item p {
            margin: 0;
        }

        .list .item .name {
            color: #FB7299;
            font-size: 14px;
            font-weight: bold;
        }

        .list .item .text {
            color: #333;
            padding: 10px 0;
        }

        .list .item .time {
            color: #999;
            font-size: 12px;
        }
    </style>
</head>

<body>
<div class="wrapper">
    <i class="avatar"></i>
    <textarea id="tx" maxlength="200" placeholder="发一条友善的评论" rows="2"></textarea>
    <button>发布</button>
</div>
<div class="wrapper">
    <span class="total">0/200字</span>
</div>
<div class="list">
    <div class="item" style="display: none;">
        <i class="avatar"></i>
        <div class="info">
            <p class="name">清风徐来</p>
            <p class="text">大家都辛苦啦,感谢各位大大的努力,能圆满完成真是太好了[笑哭][支持]</p>
            <p class="time">2022-10-10 20:29:21</p>
        </div>
    </div>
</div>

<script>
    const element = document.querySelector('#tx');
    const element1 = document.querySelector('.item');
    const element2 = document.querySelector('.text');
    element.addEventListener('keyup', function (e) {
        if (e.key === 'Enter') {
          element1.style.display = 'block'
          element2.innerText = element.innerText
        }
    })
</script>

</body>
</html>

环境对象

函数内部特殊的变量 this , 代表当前函数运行时所处的环境

this指向规则: 谁调用这个函数, this 就指向谁

element.addEventListener('keyup', function (e) {
        if (e.key === 'Enter') {
          element1.style.display = 'block'
          element2.innerText = element.innerText
        }
    })
此时  element 可以替换为   this 
因为  element 调用了函数

回调函数

把函数A 作为函数B的 参数, 函数A为回调函数

<script>
    function fn() {
      console.log("我是回调");
    }
    setInterval(fn, 1000)
</script>

案例 tab栏切换

<!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>tab栏切换</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .tab {
      width: 590px;
      height: 340px;
      margin: 20px;
      border: 1px solid #e4e4e4;
    }

    .tab-nav {
      width: 100%;
      height: 60px;
      line-height: 60px;
      display: flex;
      justify-content: space-between;
    }

    .tab-nav h3 {
      font-size: 24px;
      font-weight: normal;
      margin-left: 20px;
    }

    .tab-nav ul {
      list-style: none;
      display: flex;
      justify-content: flex-end;
    }

    .tab-nav ul li {
      margin: 0 20px;
      font-size: 14px;
    }

    .tab-nav ul li a {
      text-decoration: none;
      border-bottom: 2px solid transparent;
      color: #333;
    }

    .tab-nav ul li a.active {
      border-color: #e1251b;
      color: #e1251b;
    }

    .tab-content {
      padding: 0 16px;
    }

    .tab-content .item {
      display: none;
    }

    .tab-content .item.active {
      display: block;
    }
  </style>
</head>

<body>
  <div class="tab">
    <div class="tab-nav">
      <h3>每日特价</h3>
      <ul>
        <li><a class="active" 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="tab-content">
      <div class="item active"><img src="./images/tab00.png" alt="" /></div>
      <div class="item"><img src="./images/tab01.png" alt="" /></div>
      <div class="item"><img src="./images/tab02.png" alt="" /></div>
      <div class="item"><img src="./images/tab03.png" alt="" /></div>
      <div class="item"><img src="./images/tab04.png" alt="" /></div>
    </div>
  </div>
  <script>
    // 1. a 模块制作 要给 5个链接绑定鼠标经过事件
    // 1.1 获取 a 元素 
    const as = document.querySelectorAll('.tab-nav a')

    // console.log(as) 
    for (let i = 0; i < as.length; i++) {
      // console.log(as[i])
      // 要给 5个链接绑定鼠标经过事件
      as[i].addEventListener('mouseenter', function () {
        // console.log('鼠标经过')
        // 排他思想  
        // 干掉别人 移除类active
        document.querySelector('.tab-nav .active').classList.remove('active')
        // 我登基 我添加类 active  this 当前的那个 a 
        this.classList.add('active')

        // 下面5个大盒子 一一对应  .item 
        // 干掉别人
        document.querySelector('.tab-content .active').classList.remove('active')
        // 对应序号的那个 item 显示 添加 active 类
        document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')

      })
    }
  </script>
</body>
</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zirEsczn-1690198311351)(https://imgfff-1313020458.cos.ap-shanghai.myqcloud.com/images/%E6%94%BE%E7%9D%80%E8%B5%9B%E7%9B%B4%E6%92%AD.gif)]

+++

案例: 单选和全选

<!DOCTYPE html>

<html>

<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    table {
      border-collapse: collapse;
      border-spacing: 0;
      border: 1px solid #c0c0c0;
      width: 500px;
      margin: 100px auto;
      text-align: center;
    }

    th {
      background-color: #09c;
      font: bold 16px "微软雅黑";
      color: #fff;
      height: 24px;
    }

    td {
      border: 1px solid #d0d0d0;
      color: #404060;
      padding: 10px;
    }

    .allCheck {
      width: 80px;
    }
  </style>
</head>

<body>
  <table>
    <tr>
      <th class="allCheck">
        <input type="checkbox" name="" id="checkAll"> <span class="all">全选</span>
      </th>
      <th>商品</th>
      <th>商家</th>
      <th>价格</th>
    </tr>
    <tr>
      <td>
        <input type="checkbox" name="check" class="ck">
      </td>
      <td>小米手机</td>
      <td>小米</td>
      <td>¥1999</td>
    </tr>
    <tr>
      <td>
        <input type="checkbox" name="check" class="ck">
      </td>
      <td>小米净水器</td>
      <td>小米</td>
      <td>¥4999</td>
    </tr>
    <tr>
      <td>
        <input type="checkbox" name="check" class="ck">
      </td>
      <td>小米电视</td>
      <td>小米</td>
      <td>¥5999</td>
    </tr>
  </table>
  <script>
    // 1. 获取大复选框
    const checkAll = document.querySelector('#checkAll')
    // 2. 获取所有的小复选框
    const cks = document.querySelectorAll('.ck')
    // 3. 点击大复选框  注册事件
    checkAll.addEventListener('click', function () {
      // 得到当前大复选框的选中状态
      // console.log(checkAll.checked)  // 得到 是 true 或者是 false
      // 4. 遍历所有的小复选框 让小复选框的checked  =  大复选框的 checked
      for (let i = 0; i < cks.length; i++) {
        cks[i].checked = this.checked
      }
    })
    // 5. 小复选框控制大复选框

    for (let i = 0; i < cks.length; i++) {
      // 5.1 给所有的小复选框添加点击事件
      cks[i].addEventListener('click', function () {
        // 判断选中的小复选框个数 是不是等于  总的小复选框个数
        // 一定要写到点击里面,因为每次要获得最新的个数
        // console.log(document.querySelectorAll('.ck:checked').length)
        // console.log(document.querySelectorAll('.ck:checked').length === cks.length)
        checkAll.checked = document.querySelectorAll('.ck:checked').length === cks.length
      })
    }
  </script>
</body>

</html>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-64I7GUQ3-1690198311352)(https://imgfff-1313020458.cos.ap-shanghai.myqcloud.com/images/%E5%8F%91%E4%B8%ADe%E5%AF%B9%E4%B8%AA.gif)]

+++

事件流

事件完整执行过程流动路径

image-20230722162733456

有捕获阶段和冒泡阶段

	const man = document.querySelector('.man');
    const son = document.querySelector('.son');
    man.addEventListener('click', function () {
      alert("我是父亲")
    })
    son.addEventListener('click', function () {
      alert("我是儿子")
    })
    document.addEventListener('click', function () {
      alert("i need help")
    })


	<div class="man">
    <div class="son">
    </div>
  	</div>

此时是冒泡流, 从小到大

demo1

+++

给 Listener 加一个参数 true, 此时是捕获流(不常用), 效果和冒泡流相反

	man.addEventListener('click', function () {
      alert("我是父亲")
    }, true)
    son.addEventListener('click', function () {
      alert("我是儿子")
    }, true)
    document.addEventListener('click', function () {
      alert("i need help")
    }, true)

+++

阻止冒泡(流动)

e.stopPropagation()

son.addEventListener('click', function (e) {
      alert("我是儿子")
        e.stopPropagation()
})

这样就只会显示自身

+++

事件解绑

匿名函数无法解绑, 因此我们必须给函数一个名字

改造上面的儿子函数

son.addEventListener('click', function (e) {
      alert("我是儿子")
        e.stopPropagation()
})

改造后 =>

	let isSon;
    son.addEventListener('click', isSon = function (e) {
      alert("我是儿子")
        e.stopPropagation()
    })
    son.removeEventListener('click', isSon)

两种鼠标经过事件的区别

image-20230722172946517

事件委托

九子夺嫡, 你要办事情, 找阿哥, 儿子再找康熙, 康熙直接给所有儿子传旨

原理: 给父元素(康熙)注册事件, 触发子元素, 冒泡到父元素身上, 触发父元素事件

示例:

<body>
    <ul>
        <li>大阿哥</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
        <li>9</li>
    </ul>

  <script>
      document.querySelector('ul').addEventListener('click', function () {
          alert('123')
      })
  </script>

案例 tab栏切换 plus

<!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>tab栏切换</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .tab {
            width: 590px;
            height: 340px;
            margin: 20px;
            border: 1px solid #e4e4e4;
        }

        .tab-nav {
            width: 100%;
            height: 60px;
            line-height: 60px;
            display: flex;
            justify-content: space-between;
        }

        .tab-nav h3 {
            font-size: 24px;
            font-weight: normal;
            margin-left: 20px;
        }

        .tab-nav ul {
            list-style: none;
            display: flex;
            justify-content: flex-end;
        }

        .tab-nav ul li {
            margin: 0 20px;
            font-size: 14px;
        }

        .tab-nav ul li a {
            text-decoration: none;
            border-bottom: 2px solid transparent;
            color: #333;
        }

        .tab-nav ul li a.active {
            border-color: #e1251b;
            color: #e1251b;
        }

        .tab-content {
            padding: 0 16px;
        }

        .tab-content .item {
            display: none;
        }

        .tab-content .item.active {
            display: block;
        }
    </style>
</head>

<body>
<div class="tab">
    <div class="tab-nav">
        <h3>每日特价</h3>
        <ul>
            <li><a class="active" href="javascript:" data-id="0">精选</a></li>
            <li><a href="javascript:" data-id="1">美食</a></li>
            <li><a href="javascript:" data-id="2">百货</a></li>
            <li><a href="javascript:" data-id="3">个护</a></li>
            <li><a href="javascript:" data-id="4">预告</a></li>
        </ul>
    </div>
    <div class="tab-content">
        <div class="item active"><img src="./images/tab00.png" alt="" /></div>
        <div class="item"><img src="./images/tab01.png" alt="" /></div>
        <div class="item"><img src="./images/tab02.png" alt="" /></div>
        <div class="item"><img src="./images/tab03.png" alt="" /></div>
        <div class="item"><img src="./images/tab04.png" alt="" /></div>
    </div>
</div>
<script>
    // 采取事件委托的形式 tab栏切换
    // 1. 获取 ul 父元素 因为 ul只有一个
    const ul = document.querySelector('.tab-nav ul')
    // 获取 5个 item
    const items = document.querySelectorAll('.tab-content .item')
    // 2. 添加事件
    ul.addEventListener('click', function (e) {
        // console.log(e.target)  // e.target是我们点击的对象
        // 我们只有点击了 a 才会 进行 添加类和删除类操作
        // console.log(e.target.tagName)  // e.target.tagName 点击那个对象的 标签名
        if (e.target.tagName === 'A') {
            // console.log('我选的是a')
            // 排他思想 ,先移除原来的active
            document.querySelector('.tab-nav .active').classList.remove('active')
            //当前元素添加 active  是 e.target
            // this 指向ul 不能用this
            e.target.classList.add('active')

            // 下面大盒子模块
            // console.log(e.target.dataset.id)
            const i = +e.target.dataset.id
            // 排他思想 ,先移除原来的active
            document.querySelector('.tab-content .active').classList.remove('active')
            // 对应的大盒子 添加 active
            // document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
            items[i].classList.add('active')
        }
    })
</script>
</body>

</html>

阻止元素默认行为

e.preventDefault()

	<form action="https://www.baidu.com">
        <input type="submit" value="免费注册">
    </form>
    <script>
        const form = document.querySelector('form');
        form.addEventListener('click', function (e) {
            e.preventDefault()  // 禁止跳转
        })
    </script>

此时点击这个页面是不会跳转的

其他事件

页面加载事件

为了把

+++

滚动事件

	window.addEventListener('scroll', function () {
            alert('我滚动了')
        })

通过检测页面滚动显示元素

<body style="height: 5000px;">
<img src="gou.jpg" alt="" style="display: none">

<script>
  window.addEventListener('scroll', function () {
    if (document.documentElement.scrollTop >= 500)
      document.querySelector('img').style.display = 'block'
  })
</script>
</body>

这里滚动条上方空出 500px 则显示图片

offset 家族

计算元素相对父级元素{通常为body}的距离

示例:

	const one = document.querySelector('.one');
  	console.log(one.offsetTop); // 距离页面顶部距离
  	console.log(one.offsetLeft);// 距离页面左边距离	

日期对象使用

let date = new Date();
let s = date.toLocaleString();
console.log(s);
2023/7/23 10:42:12

时间戳

1970年1月1日0时0分0秒到现在的毫秒数

console.log(Date.now());
console.log(new Date().getTime());
console.log(+new Date()); [常用]

时间戳实现倒计时

<!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>
        .countdown {
            width: 240px;
            height: 305px;
            text-align: center;
            line-height: 1;
            color: #fff;
            background-color: brown;
            /* background-size: 240px; */
            /* float: left; */
            overflow: hidden;
        }

        .countdown .next {
            font-size: 16px;
            margin: 25px 0 14px;
        }

        .countdown .title {
            font-size: 33px;
        }

        .countdown .tips {
            margin-top: 80px;
            font-size: 23px;
        }

        .countdown small {
            font-size: 17px;
        }

        .countdown .clock {
            width: 142px;
            margin: 18px auto 0;
            overflow: hidden;
        }

        .countdown .clock span,
        .countdown .clock i {
            display: block;
            text-align: center;
            line-height: 34px;
            font-size: 23px;
            float: left;
        }

        .countdown .clock span {
            width: 34px;
            height: 34px;
            border-radius: 2px;
            background-color: #303430;
        }

        .countdown .clock i {
            width: 20px;
            font-style: normal;
        }
    </style>
</head>

<body>
<div class="countdown">
    <p class="next">今天是2222年2月22日</p>
    <p class="title">下班倒计时</p>
    <p class="clock">
        <span id="hour">00</span>
        <i>:</i>
        <span id="minutes">25</span>
        <i>:</i>
        <span id="scond">20</span>
    </p>
    <p class="tips">18:30:00下课</p>
</div>
<script>
    // 随机颜色函数
    // 1. 自定义一个随机颜色函数
    function getRandomColor(flag = true) {
        if (flag) {
            // 3. 如果是true 则返回 #ffffff
            let str = '#'
            let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']
            // 利用for循环随机抽6次 累加到 str里面
            for (let i = 1; i <= 6; i++) {
                // 每次要随机从数组里面抽取一个
                // random 是数组的索引号 是随机的
                let random = Math.floor(Math.random() * arr.length)
                // str = str + arr[random]
                str += arr[random]
            }
            return str

        } else {
            // 4. 否则是 false 则返回 rgb(255,255,255)
            let r = Math.floor(Math.random() * 256)  // 55
            let g = Math.floor(Math.random() * 256)  // 89
            let b = Math.floor(Math.random() * 256)  // 255
            return `rgb(${r},${g},${b})`
        }

    }

    // 页面刷新随机得到颜色
    const countdown = document.querySelector('.countdown')
    countdown.style.backgroundColor = getRandomColor()
    // 函数封装 getCountTime
    function getCountTime() {
        // 1. 得到当前的时间戳
        const now = +new Date()
        // 2. 得到将来的时间戳
        const last = +new Date('2024-4-1 18:30:00')
        // console.log(now, last)
        // 3. 得到剩余的时间戳 count  记得转换为 秒数
        const count = (last - now) / 1000
        // console.log(count)
        // 4. 转换为时分秒
        // h = parseInt(总秒数 / 60 / 60 % 24)   //   计算小时
        // m = parseInt(总秒数 / 60 % 60);     //   计算分数
        // s = parseInt(总秒数 % 60);
        // let d = parseInt(count / 60 / 60 / 24)               //   计算当前秒数
        let h = parseInt(count / 60 / 60 % 24)
        h = h < 10 ? '0' + h : h
        let m = parseInt(count / 60 % 60)
        m = m < 10 ? '0' + m : m
        let s = parseInt(count % 60)
        s = s < 10 ? '0' + s : s
        console.log(h, m, s)

        //  5. 把时分秒写到对应的盒子里面
        document.querySelector('#hour').innerHTML = h
        document.querySelector('#minutes').innerHTML = m
        document.querySelector('#scond').innerHTML = s
    }
    // 先调用一次
    getCountTime()

    // 开启定时器
    setInterval(getCountTime, 1000)
</script>
</body>
</html>

父子兄弟节点

查找父节点    parentNode 
查找所有子节点   children
查找哥哥节点   previousElementSibling
查找弟弟节点   nextElementSibling

<body>
    <div style="width: 500px">
        康熙
        <div class="oneSon">大阿哥</div>
        <div class="twoSon">太子</div>
        <div class="threeSon">三阿哥</div>
        <div class="fourSon">雍正
            <div>章总</div>
        </div>
        <div class="fiveSon">五阿哥</div>
    </div>
<script>
    const c4 = document.querySelector('.fourSon');
    console.log(c4.parentNode.innerText);  // 康熙
    for (let i = 0; i < c4.parentNode.children.length; i++) { // 得到伪数组
        c4.parentNode.children[i].style.color = 'red';
    }
    console.log(c4.previousElementSibling.innerText); // 三
    console.log(c4.nextElementSibling.innerText);  // 五
</script>

+++

增删节点

创建节点

document.createElement

添加节点

e.appendChild

克隆节点

e.children[0].cloneNode(true) 克隆标签和内容

e.children[0].cloneNode() 只克隆标签

删除节点

e.removeChild(li1)

M端事件 了解

触屏事件 触摸 滑动 移开

文档

Swiper中文网-轮播图幻灯片js插件,H5页面前端开发

Window 对象

BOM

浏览器对象模型, dom是bom的一部分

延时函数

setTimeOut

五秒后关闭图片

<body>
    <img src="images/slider01.jpg">

<script>
    const htmlImageElement = document.querySelector('img');
    setTimeout(function () {
        htmlImageElement.style.display = 'none'
    }, 5000)
</script>

location 对象

页面跳转

<script>
    location.href = 'http://www.baidu.com'
</script>

navigator

自动跳转到移动端

<!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>
  <script>
    // 检测 userAgent(浏览器信息)
    !(function () {
      const userAgent = navigator.userAgent
      // 验证是否为Android或iPhone
      const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)
      const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/)
      // 如果是Android或iPhone,则跳转至移动站点
      if (android || iphone) {
        location.href = 'http://m.itcast.cn'
      }
    })();
    // !(function () { })();
    !function () { }()
  </script>
</head>
 
<body>
  这是pc端的页面
  <script>
      // (function () { })()
  </script>
</body>
 
</html>

单独拆出来js代码

<script>
    // 检测 userAgent(浏览器信息)
    !(function () {
      const userAgent = navigator.userAgent
      // 验证是否为Android或iPhone
      const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)
      const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/)
      // 如果是Android或iPhone,则跳转至移动站点
      if (android || iphone) {
        location.href = 'http://m.itcast.cn'
      }
    })();
    // !(function () { })();
    !function () { }()
  </script>

本地存储

浏览器的数据库

容量 5M : sessionMessage | localStorage

https://todomvc.com/examples/vanilla-es6/

localStorage

数据永久存到电脑, 除非手动删除, 否则一直都在

键值对存储

localStorage.setItem(key, value )

	localStorage.setItem('黑剑', '玛利喀斯')
    console.log(localStorage.getItem('黑剑'));
    localStorage.removeItem('黑剑')

sessionStorage

关闭浏览器即消失[session], 用法和 localStorage 一样

+++

存复杂数据 [ JSON ]

const goods = {
      name: '小米',
      price: 2000
    }
    localStorage.setItem('goods', JSON.stringify(goods))
    console.log(JSON.parse(localStorage.getItem('goods')));

+++

map方法

map遍历数组处理数据, 返回新的数组

const arr = ['黑剑', '莲莲', '菈妮', '玛琳娜']
const arr1 = arr.map(function (ele, index) {
    console.log(ele);
    console.log(index);
    return 'boss: ' + ele
})
console.log(arr);
console.log(arr1);

map有返回值, forEach无返回值

join方法

把数组转换成字符串

const arr = ['黑剑', '莲莲', '菈妮', '玛琳娜']
console.log(arr);
console.log(arr.join(''));

image-20230724085603088

+++

正则表达式

正则用 chatgpt 即可

const text = '这年头,总有些人,觉得自己读了两本书,识了几个字'
const reg = /两本书/
console.log(reg.test(text)); // 返回布尔

console.log(reg.exec(text)); // 返回数组
true

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[
  '两本书',
  index: 15,
  input: '这年头,总有些人,觉得自己读了两本书,识了几个字',
  groups: undefined
]

元字符

reg 就是元字符, 是正则通配符格式

const text = 'dbbbbbbbbbbbbbbbbbbbbbbbbbd'
//以字母 "d" 开始和结束的字符串,中间可以包含一个或多个连续的字母 "b"
const reg = /d(b+)d/
console.log(reg.test(text)); // 返回布尔
console.log(reg.exec(text)); // 返回数组

正则匹配规则查表

形式匹配规则
\d一个数字
\w一个字母或数字
.任意字符 {py.} => {[py1], [pyt], [py?]}
*任意个字符(含0)
+至少一个字符
?0或1个字符
{n}n个字符
{n, m}n~m个字符
[]范围
[a-zA-Z_] [0-9a-zA-Z_] {0, 19}[a-zA-Z_][0-9a-zA-Z_]{0, 19}
(P|p)ythonPython或python
^\d数字开头
\d$数字结束
^py$py

Python 正则 re模块

import re

#  r  可以避免转义
print(re.match(r'\d{3}-\d{3,8}$', '010-12345'))

# 识别连续空格, 无论多少个空格都能正常分割
print(re.split(r'\s+', 'ab           c'))

分组

# 分组, 这里用()把reg分成两组
reg = r'^(\d{3})-(\d{3,8})$'
m = re.match(reg, '010-12345')
print(m.group(0))
print(m.group(1))
print(m.group(2))
# 010-12345
# 010
# 12345

js 进阶

动态参数 arguments

const name = ['黑剑', '莲莲', '菈妮', '玛琳娜']

function f() {
    for (let i = 0; i < arguments.length; i++) {
        console.log(arguments[i]);
    }
}

f(name)

剩余参数 …arr

const name = ['黑剑', '莲莲', '菈妮', '玛琳娜']

function f(...arr) {
    for (let i = 0; i < arr.length; i++) {
        console.log(arguments[i]);
    }
}

f(name)

箭头函数

就是 lambda 表达式

没有this arguments super 等等属性, 箭头函数适用于本来需要匿名函数的地方, 也就是lambda表达式

const name = ['黑剑', '莲莲', '菈妮', '玛琳娜']

console.log(name.map(function (name) {
    return name.length
}));

console.log(name.map(name => name.length));

箭头函数使用三元运算符

let simple = a => a > 15 ? 15 : a;
console.log(simple(16)); // 15
console.log(simple(10));// 10
let max = (a, b) => a > b ? a : b;
console.log(max(1, 2)); // 2

数组对象解构

const pig =[
    {name: '莲莲',  age: 18, sex: '女'},
    {name1: '黑剑',  age1: 18, sex1: '男'},
]
const [{name, age, sex},
    {name1, age1, sex1}] = pig

console.log(name)
console.log(name1)
console.log(age)
console.log(age1)
console.log(sex)
console.log(sex1)

++++

原型对象prototype

函数挂载, prototype操作的是函数, 挂载的是对象

function f() {
}
f.prototype.sing = ()=>console.log('sing')
const f1 = new f();
f1.sing()

继承

const Person = {
    name: '莲莲',
    age: 18
}

function Woman (){

}
Woman.prototype = Person
var woman = new Woman();
console.log(woman.name);
console.log(woman.age);

+++

浅拷贝

拷贝对象

Object.assign

const Person = {
    name: '莲莲',
    age: 18
}
let o = {};
// 拷贝对象
Object.assign(o, Person)
console.log(o.name);//莲莲
console.log(o.age);//18

拷贝数组

Array.prototype.concat


// 拷贝数组
arr = [1, '黑剑', 2, true]
arr1 = Array.prototype.concat(arr)
console.log(arr1[1]);//黑剑

深拷贝

const Person = {
    name: '莲莲',
    age: 18
}
let o = {};
// 拷贝对象
function deepCopy(newObj, oldObj) {
    for (let k in oldObj) {
        newObj[k] = oldObj[k]
    }
    return newObj
}

const deepCopy1 = deepCopy(o, Person);
console.log(deepCopy1);
{ name: '莲莲', age: 18 }

+++

)


### 剩余参数   ...arr

```js
const name = ['黑剑', '莲莲', '菈妮', '玛琳娜']

function f(...arr) {
    for (let i = 0; i < arr.length; i++) {
        console.log(arguments[i]);
    }
}

f(name)

箭头函数

就是 lambda 表达式

没有this arguments super 等等属性, 箭头函数适用于本来需要匿名函数的地方, 也就是lambda表达式

const name = ['黑剑', '莲莲', '菈妮', '玛琳娜']

console.log(name.map(function (name) {
    return name.length
}));

console.log(name.map(name => name.length));

箭头函数使用三元运算符

let simple = a => a > 15 ? 15 : a;
console.log(simple(16)); // 15
console.log(simple(10));// 10
let max = (a, b) => a > b ? a : b;
console.log(max(1, 2)); // 2

数组对象解构

const pig =[
    {name: '莲莲',  age: 18, sex: '女'},
    {name1: '黑剑',  age1: 18, sex1: '男'},
]
const [{name, age, sex},
    {name1, age1, sex1}] = pig

console.log(name)
console.log(name1)
console.log(age)
console.log(age1)
console.log(sex)
console.log(sex1)

++++

原型对象prototype

函数挂载, prototype操作的是函数, 挂载的是对象

function f() {
}
f.prototype.sing = ()=>console.log('sing')
const f1 = new f();
f1.sing()

继承

const Person = {
    name: '莲莲',
    age: 18
}

function Woman (){

}
Woman.prototype = Person
var woman = new Woman();
console.log(woman.name);
console.log(woman.age);

+++

浅拷贝

拷贝对象

Object.assign

const Person = {
    name: '莲莲',
    age: 18
}
let o = {};
// 拷贝对象
Object.assign(o, Person)
console.log(o.name);//莲莲
console.log(o.age);//18

拷贝数组

Array.prototype.concat


// 拷贝数组
arr = [1, '黑剑', 2, true]
arr1 = Array.prototype.concat(arr)
console.log(arr1[1]);//黑剑

深拷贝

const Person = {
    name: '莲莲',
    age: 18
}
let o = {};
// 拷贝对象
function deepCopy(newObj, oldObj) {
    for (let k in oldObj) {
        newObj[k] = oldObj[k]
    }
    return newObj
}

const deepCopy1 = deepCopy(o, Person);
console.log(deepCopy1);
{ name: '莲莲', age: 18 }

+++

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用中提到,JavaScript 程序需要被嵌入到 HTML 中才能运行,通常通过 script 标签将 JavaScript 代码引入到HTML文件中。可以使用内部方式,将 JavaScript 代码直接包裹在 script 标签中,也可以使用外部方式,将 JavaScript 代码写在独立的以 .js 结尾的文件中,然后通过 script 标签的 src 属性引入。 关于“javascript pink老师2023”,根据提供的引用内容,无法得知具体指的是什么。如果你有关于这个问题的更多信息或者具体的上下文,请提供更多细节,我将尽力为你解答。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [黑马pink老师 2023JavaScript 第一天笔记](https://blog.csdn.net/Wu_Yingsi/article/details/130295951)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [黑马pink老师 2023JavaScript 第三天笔记](https://blog.csdn.net/Wu_Yingsi/article/details/130479490)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值