Web APIs - 总结笔记

Web APIs - 语法

DOM - 文档对象模型

1. 页面获取元素

1.1 获取单个元素

document.querySelector(‘选择器’)

document.body // 选中body元素

document.documentElement // 选中html元素

<!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>querySelector-获取单个元素</title>
</head>
<body>

  <div>哇哈哈</div>
  <p>段落</p>
  <span>abc</span>

  <div>1</div>
  <div class="d2">2</div>
  <div id="box3">3</div>

  <p>1</p>
  <p>2</p>
  <p>3</p>

  <p>段落aaa</p>
  <div>
    <p>段落bbb</p>
  </div>
  <div id="box">
    <p>段落1</p>
  </div>
  <p>1</p>
  <p>2</p>

  <script>
    // 1. 获取单个元素   默认第一个
    // document.querySelector('选择器')

    let div1 = document.querySelector('div')  // <div>哇哈哈</div>
    console.log(div1)

    let div2 = document.querySelector('.d2')  // <div class="d2">2</div>
    console.log(div2)

    let div3 = document.querySelector('#box3')  // <div id="box3">3</div>
    console.log(div3)

    let divp = document.querySelector('#box p')  // <p>段落1</p>
    console.log(divp)

    let p6 = document.querySelector('div p:nth-child(1)')  // <p>段落bbb</p>
    console.log(p6)

    // 2. 注意点:
    // 2.1 如果有多个,那么document.querySelector会默认选中第一个
    let p1 = document.querySelector('p')  // <p>段落</p>
    console.log(p1)

    // 2.2 找不到元素即为 null
    let p = document.querySelector('.p')  // null
    console.log(p)

    // 3. 拓展
    // 3.1 body元素
    document.body
    console.log(document.body)  // <body>...</body>
    // 3.2 html元素
    document.documentElement
    console.log(document.documentElement)  // <html>...</html>
  </script>
</body>
</html>

1.2 获取多个元素

document.querySelectorAll(‘css选择器’)

<!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.querySelectorAll-获取多个元素</title>
</head>
<body>
  
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>

  <script>
    // 获取多个元素  
    // document.querySelectorAll('css选择器')

    let divs = document.querySelectorAll('div')
    console.log(divs)  // [div, div, div, div, div]
    console.log(divs[0])  // [div]

    // 打印每一个元素   遍历
    for (let i = 0; i < divs.length; i++) {
      console.log(divs[i])
    }


    // 注意点
    // 1. 返回的是【伪数组】
    //    具有索引值,具有数组length,但是不能使用数组的方法
    // 2. 伪数组【不能直接操作】
    //    因为是伪数组是一个整体,不是具体的某一个
    // 3. 只要使用 document.querySelectorAll 这个方法,不管页面有几个,【拿到的都是伪数组】,【一个也是伪数组】
    // 4. 假如没找到【返回的是伪数组,但是是空的伪数组】
  </script>
</body>
</html>

1.3 早版本-获取元素方法

document.getElementById(‘元素id名’)

document.getElementsByClassName(‘元素类名’)

document.getElementsByTagName(‘元素标签名’)

<!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>
</head>
<body>
  
  <div>哈哈哈</div>
  <div id="box">123</div>

  <div class="cc">1</div>
  <div class="cc">2</div>

  <script>
    // 通过 id 获取    返回一个
    let box1 = document.getElementById('box')
    console.log(box1)  // <div id="box">123</div>

    // 通过类名获取   返回伪数组
    let ccs = document.getElementsByClassName('cc')
    console.log(ccs)  // [div.cc, div.cc]

    // 通过标签名获取    返回伪数组
    let divs = document.getElementsByTagName('div')
    console.log(divs)  // [div, div#box, div.cc, div.cc, box: div#box]
  </script>
</body>
</html>

2. 操作元素

2.1 操作元素 - 文本内容 -

document.write

innerText

innerHTML

<!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>
    .c1 {
      background: skyblue;
    }
  </style>
</head>
<body>

  <div id="box" class="c1">哈哈哈</div>
  
  <script>
    // 操作元素-文本内容:

    // 1. document.write('hhh')
    //    设置内容:到文档上,放到最后

    // 2.innerText
    // 获取元素
    let div1 = document.querySelector('div')
    // 2.1 修改内容
    // 语法: 标签.innerText = 值
    div1.innerText = '你好!'
    // 2.2 获取内容
    // 语法:div1.innerText
    console.log( div1.innerText )  // 你好!

    // 3. innerHTML
    // 语法:元素.innerHTML = 值
    // 3.1 修改内容
    div1.innerHTML = '你好!你好!'
    // 3.2 获取内容
    // 语法:div1.innerHTML
    console.log( div1.innerHTML )  // 你好!你好!

    // 区别:
    // innerText  不管是获取还是设置,只识别文本
    div1.innerText = '<h2>二级标题</h2>'  // 页面上显示的是 <h2>二级标题</h2>
    console.log( div1.innerText )  // <h2>二级标题</h2>
    // innerHTML  不管是获取还是设置,识别文本和标签
    div1.innerHTML = '<h2>二级标题</h2>'  // 页面上显示的是 有样式的二级标题
    console.log( div1.innerHTML )  // <h2>二级标题</h2>
  </script>
</body>
</html>

2.2 操作元素 - 元素属性

元素.属性 = 值

元素.style.属性 = 值

元素.className = ‘’

元素.classList.add(‘类名’)

元素.classList.remove(‘类名’)

元素.classList.toggle(‘类名’)

元素.classList.contains(‘类名’)

<!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>
    div {
      margin: 10px 0;
      width: 100px;
      background: orange;
    }
    .v1 {
      width: 200px;
      height: 100px;
      background-color: gray;
    }
    .v2 {
      width: 400px;
      height: 100px;
      text-align: center;
      line-height: 100px;
      background-color: skyblue;
    }
    .v3 {
      margin: 0 auto;
    }

  </style>
</head>
<body>

  <div id="box" title="标题">哇哈哈</div>
  <div class="divv">111</div>
  <div id="box3" class="v">我是第三个盒子内容</div>

  <script>
    // 操作元素-属性操作
    // 1. 操作-基本属性
    // 获取元素
    let div1 = document.querySelector('div')
    // 1.1 设置属性    语法:元素.属性 = 值
    div1.title = '新标题'
    // 1.2 获取属性    语法:元素.属性
    console.log( div1.title )  // 新标题


    // 2. 操作-样式属性
    // 获取元素
    let div2 = document.querySelector('.divv')
    
    // 2.1 同过 style 属性操作CSS  【设置添加行内样式】  
    //    语法:元素.style.属性 = 值
    //    注意:不准用来获取
    div2.style.width = '100px'
    div2.style.height = '100px'
    div2.style.background = 'skybule'
    // 复合名称的属性名 - 去掉 改为小驼峰命名
    // text-align ==> textAlign
    div2.style.textAlign = 'center'
    div2.style.lineHeight = '100px'
    
    // 2.2 通过 class 属性添加样式    【通过类名操作样式】
    // 获取页面元素
    let div3 = document.querySelector('#box3')
    // 通过添加类名来添加样式
    div3.className = 'v2'
    // 通过添加空类名来清空类名
    div3.className = ''
    // 注意:
    // a) class这个属性不能直接写,改成 className
    // b) 会覆盖之前的类名,只适用于一个类名的情况下

    // 2.3 通过 classList
    // 2.3.1 添加类名 (不会覆盖,添加类名)
    // 语法:元素.classList.add('类名')
    div3.classList.add('v1')
    div3.classList.add('v2')
    div3.classList.add('v3')

    // 2.3.1 删除类名 (删除类名)
    // 语法:元素.classList.remove('类名')
    div3.classList.remove('v2')

    // 2.3.1 切换类名 (有就删除,没有就添加)
    // 语法:元素.classList.toggle('类名')
    div3.classList.toggle('v2')

    // 2.3.1 检测类名 (有返回ture,没有返回false)
    // 语法:元素.classList.contains('类名')
    let flag = div3.classList.contains('v2')
    console.log(flag)
  </script>
</body>
</html>

2.3 操作元素 - 表单元素

checked: 单选、多选 默认选中

disabled: 禁用

selected: 下拉菜单 默认选中

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

  <!-- <input type="text" value="框内的内容"> -->
  
  <input type="text" value="123abc">
  <br>

  <input type="text" value="123">
  <br>

  <input type="checkbox" checked><input type="checkbox"><br>

  <select>
    <option id="op1">北京</option>
    <option>上海</option>
    <option>广州</option>
    <option>深圳</option>
    <option>杭州</option>
    <option id="op5">石家庄</option>
  </select>

  <script>
    // 用户写的内容,相当于 value 的值

    // 1. 基本属性
    // 获取文本框里的内容,相当于获取 value 属性
    // 1.1 获取元素
    let inp1 = document.querySelector('input')
    // 1.2 获取值
    console.log( inp1.value )  // 123abc
    // 1.3 设置值
    inp1.value = 123456
    console.log( inp1.value )  // 123456
    // 1.4 获取表单类型
    console.log( inp1.type )  // text


    // 2. 常用属性
    // checked: 单选、多选 默认选中
    // disabled: 禁用
    // selected: 下拉菜单 默认选中

    // 2.1 disabled: 禁用
    let inp2 = document.querySelector('input:nth-child(3)')
    // 2.1.1 设置表单禁用
    inp2.disabled = true
    // 2.1.2 设置表单解除禁用
    inp2.disabled = false
    // 2.1.3 查看表单是否禁用
    console.log( inp2.disabled )  // false

    // 2.2 checked: 单选多选默认选中
    let inp3 = document.querySelector('input:nth-child(5)')
    let inp4 = document.querySelector('input:nth-child(6)')
    // 2.2.1 设置表单  男 不是默认选中
    inp3.checked = false
    // 2.2.2 设置表单  女 是默认选中
    inp4.checked = true
    // 2.2.3 查看表单是否默认选中
    console.log( inp3.checked )  // false
    console.log( inp4.checked )  // true

    // 2.3 selected: 下拉菜单默认选中
    let select = document.querySelector('select')
    let op5 = document.querySelector('#op5')
    // 2.2.1 设置下拉菜单 select 默认是 石家庄
    op5.selected = true
    // 2.2.2 设置下拉菜单 select 默认不是 石家庄
    op5.selected = false
    // 2.2.3 查看石家庄是不是默认选中
    console.log( op5.selected )  // false 
    
  </script>
</body>
</html>

3. 定时器

3.1 定时器 - 间歇函数

let 标识符 = setInterval ( 调用函数, 1000 )

clearInterval ( 标识符 )

<!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>
</head>
<body>
  
  <script>
    // 1. 间歇函数
    // 每隔一段时间执行一遍

    // 1.1 创建定时器    时间单位 毫秒
    // 语法: setInterval ( 函数, 间隔时间 )
    // 创建定时器的时候会返回一个标识,可以用变量接收,方便清除定时器
    // 返回的标识其实是数字,用来排序的
    function fn () {
      console.log('你好')
    }
    let timer = setInterval ( fn, 2000 )
    let timer2 = setInterval ( fn, 1000 )

    // 1.2 关闭定时器
    // 语法:clearInterval( 变量名 )
    // 要想清除定时器必须有定时器的标识(名字)
    // 在创建的时候他会返回一个标识(名字)
        // console.log(timer2)  // 2
        // clearInterval(2)  // 【可以,但是千万别这么用】
    // 标识可以用标识符数字,但是【不要写数字】,有的浏览器第一个定时器标识返回0,有的返回1
    clearInterval(timer)
  </script>
</body>
</html>

3.2 定时器 - 延迟函数

let 标识符 = setTimeout ( 调用函数, 1000 )

clearTimeout ( 标识符 )

<!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>
</head>
<body>
  
  <script>
    // 延时性定时器、一次性定时器

    // 创建语法:setTimeout( 函数, 时间 )
    let timer = setTimeout( function () {
      console.log('定时器');
    }, 1000 )

    // 清除语法:clearTimeout(定时器标识)
    clearTimeout(timer)
  </script>
</body>
</html>

4. 事件 - DOM L2 - 【推荐】

4.1 点击事件

click 单击事件

dblclick 双击事件

<!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>
</head>
<body>
  
  <input type="button" value="点击">
  <img src="./images/1.webp" alt="">
  <div>我是div</div>

  <script>
    // 监听事件(注册事件)    // 语法:元素.addEventListener('事件', 函数)

    // 1. click:  单击事件
    // 获取元素
    let btn = document.querySelector('input')
    // 添加单击事件
    btn.addEventListener('click', function() {
      console.log('你点击了我')
    })

    // 2. dblclick 双击事件
    let img = document.querySelector('img')
    img.addEventListener('dblclick', function() {
      console.log('你双击了图片!!!')
    })


    // 注意:
    // 1. 可以给任何元素添加事件

    // 2. 添加事件三要素
    // 2.1 事件源:加给哪个元素,那个元素就是事件源
    // 2.2 事件类型:是一个什么样的事件
    // 2.3 事件处理函数:函数 当事件触发就会执行函数
  </script>
</body>
</html>

4.2 鼠标事件 - 鼠标经过/鼠标离开

4.2.1 mouseenter/mouseleave 【推荐】

mouseenter 鼠标经过 [ 推荐 ]

mouseleave 鼠标离开 [ 推荐 ]

mouseover 鼠标经过

mouseout 鼠标离开

<!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>
    div {
      border: 1px solid red;
      height: 200px;
    }
  </style>
</head>
<body>
  
  <div>哇哈哈</div>
  <br>

  <script>
    // 1. 鼠标事件
    let div = document.querySelector('div');
    // 1.1 鼠标经过  mouseenter 
    div.addEventListener('mouseenter', function() {
      div.style.background = 'skyblue'
    })
    // 1.2 鼠标离开  mouseleave
    div.addEventListener('mouseleave', function() {
      div.style.background = 'pink'
    })
  </script>
</body>
</html>
4.2.2 mouseover/mouseout
<!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>
  
  <div>
    <p>段落</p>
  </div>

  <script>
    // 怎样查看点击事件支不支持冒泡
    // 事件对象里的 bubbles 属性 可以查看支不支持冒泡  布尔类型 true 支持,反之

    let div = document.querySelector('div')
    let p = document.querySelector('p')
    // mouseenter/mouseleave: 不支持冒泡【推荐】
    // mouseover/mouseout: 支持冒泡

    // 【推荐】
    div.addEventListener('mouseenter', function() {
      console.log('经过');
    })
    div.addEventListener('mouseleave', function() {
      console.log('离开');
    })
      
    // div.addEventListener('mouseover', function() {
    //   console.log('经过');
    // })
    // div.addEventListener('mouseout', function() {
    //   console.log('离开');
    // })
      
    // 怎样查看点击事件支不支持冒泡
    div.addEventListener('click', function(e) {
    console.log( e )
    // 事件对象里的 bubbles 属性 可以查看支不支持冒泡  布尔类型 true 支持,反之
    })
  </script>
</body>
</html>

4.3 焦点事件

focus 获取焦点

blur 失去焦点

<!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>
</head>
<body>
  
  <input type="text">
  <br>

  <input type="text" class="inpp">
  <br>

  <script>
    // 1. 焦点事件  【表单项事件】
    let inp = document.querySelector('input')
    // 1.1 获取焦点  focus
    inp.addEventListener('focus', function() {
      console.log('获得焦点')
    })
    // 1.2 失去焦点  blur
    inp.addEventListener('blur', function() {
      console.log('失去焦点')
    })

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

4.4 键盘事件

keydown 按键按下

keyup 按键抬起

<!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>
</head>
<body>
  
  
  <script>
    // 按键事件
    // keydown:按键按下  
    // keyup:按键抬起

    // 监听事件:按键按下
    document.addEventListener('keydown', function() {
      console.log('keydowm');
    })
    // 监听事件:按键抬起
    document.addEventListener('keyup', function() {
      console.log('keyup');
    })
  </script>
</body>
</html>

4.5 文本事件

input 输入事件

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

  <input type="text">
  <br>

  <input type="text" class="inpp">
  <br>

  <script>
    // 1. 文本事件(输入事件)  【表单项事件】
    let inpp = document.querySelector('.inpp')
    // 1.1 输入事件
    inpp.addEventListener('input', function() {
      console.log( inpp.value )
    })
  </script>
</body>
</html>

4.6 滚动事件

scroll 滚动事件

<!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>
    body {
      height: 3000px;
      border: 2px solid red;
    }
    div {
      margin: 0 auto;
      width: 500px;
      height: 500px;
      border: 1px solid #ccc;
      overflow: auto;
    }
  </style>
</head>
<body>
  
  <div>
    <p>1</p>
    <p>2</p>
    <p>3</p>
    <p>4</p>
    <p>5</p>
    <p>6</p>
    <p>7</p>
    <p>8</p>
    <p>9</p>
    <p>10</p>
  </div>

  <script>
    // scroll: 滚动事件 
    // 谁有滚动条加给谁

    // let div = document.querySelector('div')
    // div.addEventListener('scroll', function() {
    //   console.log('滚动中...');
    // })

    // 如果整个窗口具有滚动条,要添加滚动事件
    // scroll事件要加给 window【推荐】或者document
    window.addEventListener('scroll', function() {
      console.log('滚动中...');
    })
  </script>
</body>
</html>

4.7 加载事件

load 加载事件

<!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>
</head>
<body>
  
  <img src="./images/b1.jpg" alt="">

  <script>
    // 引入路径的时候都是需要加载的

    // load: 加载事件
    // 资源加载完成之后触发的事件

    // let img = document.querySelector('img')
    // img.addEventListener('load', function() {
    //   console.log('加载完毕');
    // })

    // 等所有资源加载完毕后执行 load
    window.addEventListener('load', function() {
      console.log('OK');
    })
  </script>
</body>
</html>

4.8 DOM加载事件

DOMContentLoaded DOM加载

<!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>事件-DOM加载</title>
  <script>
    // DOM加载:DOMContentLoaded
    // 加给document

    // 所有文本加载完毕执行
    document.addEventListener('DOMContentLoaded', function() {
      let div = document.querySelector('div')
      div.innerHTML = '456'
    })
  </script>
</head>
<body>
  <img src="./images/b1.jpg" alt="">
  <div>123</div>
</body>
</html>

4.9 事件-尺寸改变

resize 尺寸改变事件

<!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>
    div {
      margin: 10px;
      padding: 10px;
      border: 10px solid #333;
      width: 200px;
      height: 200px;background-color: purple;
    }
  </style>
</head>
<body>
  
  <div></div>

  <script>
    // resize: 尺寸改变事件
    window.addEventListener('resize', function() {
      let width = document.documentElement.clientWidth
      console.log( '尺寸改变...' )
        console.log( width );
    })
  </script>
</body>
</html>

4.10 事件 - 内容改变

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>事件-改变执行</title>
    <style>
      img {
        position: relative;
        left: -18px;
        bottom: 1px;
        vertical-align: middle;
      }
    </style>
  </head>
  <body>
    <label> 昵称:<input type="text" /><span></span> </label>

    <script>
      // change:事件
      // 发生改变才触发事件

      // 获取元素
      let inp = document.querySelector("input")
      // 添加改变触发条件
      inp.addEventListener("change", function () {
        // 创建检测汉字正则
        let reg = /^[\u4e00-\u9fa5]{2,4}$/
        // 判断用户输入文字和正则是否符合
        if (reg.test(inp.value)) {
          inp.nextElementSibling.innerHTML = `<img src="./images/right.png">`
        } else {
          inp.nextElementSibling.innerHTML = `<img src="./images/error1.png">`
        }
      })
    </script>
  </body>
</html>

5. 早期版本 - 事件 - DOM L0 【不推荐】

元素.onclick = function () {}

<!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>DOM L0-事件</title>
</head>
<body>
  
  <input type="button" value="点击">

  <script>
    let btn = document.querySelector('input')
    // DOM L0:
    // 单击事件
    btn.onclick = function () {
      console.log('a')
    }
    btn.ondblclick = function() {
      console.log('双击事件')
    }
    // DOM L2:  【建议,新事件可以用】
    // 新事件  手指按下
    btn.addEventListener('click', function() {
      console.log('b')
    })
  </script>
</body>
</html>

6. 函数类型

function fn () {} 具名函数

let fn = function () {} 匿名函数

;(function () {})() 立即执行函数

;(function () {}()) 立即执行函数

<!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>
</head>
<body>
  
  
  <script>
    // 1. 具名函数、命名函数
    function fn() {
      console.log(123)
    }
    fn()

    // 2. 匿名函数
    // 函数也是一种数据类型的一种
    // 函数表达式
      let fnn = function () {
        console.log(456)
      }
      fnn()
    
    // 3. 立即执行函数、自调用函数、自执行函数【写的时候在函数的最开始加一个分号】
    // 写法一
    ;(function () {
      console.log(111)
    })()
    // 写法二
    ;(function () {
      console.log(222)
    }())

    // 4. 回调函数
    // 高阶函数:一个函数他的形参是一个函数那么他就是高阶函数
    // 回调函数:给其他函数当作参数的函数称为回调函数
    function fun (a) {
      // 函数不调用不执行
      console.log(a)  // function () {console.log(a)}
      a()  // 1233
    }
    // let n = function () {console.log(a)}
    fun( function () {console.log(1233)} )
  </script>
</body>
</html>

7. 环境变量 - this

事件处理函数中的 this 指向 事件源

<!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>环境变量-this</title>
</head>
<body>
  
  <input type="button" value="点击">
  
  <script>
    // 1. this 在全局变量里指向的是 window
    console.log(this)  // window

    // 2. 函数中 this 指向 window
    function fn() {
      console.log(this)  // window
    }
    setInterval(function() {
      console.log(this)  // window
    }, 1000)

    // 3. 事件处理函数中的 this 指向 事件源
    let btn = document.querySelector('input')
    btn.addEventListener('click', function() {
      // 事件源处理函数 this ==> 事件源 btn
      console.log(this) // btn
    })

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

8. 节点操作

查看节点类型 – nodeType

查看节点名称 – nodeName == tagName 【返回大写标签名】

父节点的查找 – 子节点.parentNode

子节点的查找 – .childNodes .children .fristChild .lastchild .fristElementChild .lastElementChild

前一个兄弟节点 – img.previousSibling

下一个兄弟节点 – img.nextSibling

前一个元素兄弟节点 --【掌握】img.previousElementSibling

下一个元素兄弟节点 --【掌握】元素.nextElementSibling

创建标签:document.createElement(‘标签名’)

追加节点:父节点.appendChild(子节点)

追加节点:父.insertBefore.(新, 旧)

克隆节点:元素.cloneNode()

删除节点:父元素.removeChild(子元素)

8.1 查找节点

<!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>
</head>
<body>
  <div>
    <p>段落</p>
    <img src="./images/b01.jpg">
    <h3>标题</h3>
  </div>

  <script>
    // 获取页面 div 元素
    let div = document.querySelector('div')
    // 获取页面 img 元素
    let img = document.querySelector('img')

    // 0. 元素节点返回1,属性节点2,文本节点返回3

    // 0.1 查看节点类型  nodeType
    console.log( div.childNodes[0].nodeType )  // 3  // 文本节点
    console.log( div.childNodes[1].nodeType )  // 1  // 元素节点
    // 0.2 查看节点名称  nodeName == tagName  【返回大写标签名】
    console.log( div.childNodes[1].nodeName )  // P 
    console.log( div.childNodes[2].nodeName )  // #text
    console.log( div.childNodes[3].tagName )  // IMG


    // 1. 查找节点
    // 当我们获取到一个节点,可以通过这个节点获取他的关系节点

    // 1.1 父节点的查找    子节点.parentNode
    // 查找img的父节点【掌握】  
    console.log( img.parentNode ) // <div></div>
    // 查找img的爷爷节点  
    console.log( img.parentNode.parentNode )  // body
    // 查找img的祖节点
    console.log( img.parentNode.parentNode.parentNode )  // html
    console.log( img.parentNode.parentNode.parentNode.parentNode )  // document
    console.log( img.parentNode.parentNode.parentNode.parentNode.parentNode )  // null

    // 1.2 子节点的查找  .childNodes  .children  .fristChild  .lastchild  .fristElementChild  .lastElementChild  
    // 1.2.1 获取所有子节点【返回伪数组】    节点包括:文本节点、元素节点、注释节点、......
    console.log( div.childNodes )  // [text, p, text, img, text, h3, text]
    // 1.2.2 获取所有元素子节点【掌握】【返回伪数组】   节点包括:元素子节点
    console.log( div.children )  // [p, img, h3]
    // 1.2.3 第一个节点儿子    .firstChild
    console.log( div.firstChild )  // #Text
    // 1.2.4 最后一个节点儿子    .lastChild
    console.log( div.lastChild )  // #Text
    // 1.2.5 第一个元素节点儿子【掌握】  .fristElementChild
    console.log( div.lastElementChild )  // <p></p>
    // 1.2.6 最后一个元素节点儿子【掌握】  .lastElementChild
    console.log( div.lastElementChild )  // <h3></h3>

    // 1.3 兄弟节点
    // 1.3.1 前一个兄弟节点
    console.log( img.previousSibling )  // #text
    // 1.3.2 下一个兄弟节点
    console.log( img.nextSibling )  // #text
    // 1.3.3 前一个元素兄弟节点【掌握】
    console.log( img.previousElementSibling )  // <p>段落</p>
    // 1.3.4 下一个元素兄弟节点【掌握】
    console.log( img.nextElementSibling )  // <h3>标题</h3>
  </script>
</body>
</html>

8.2 新增节点

8.2.1 创建新增节点
<!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>
  
  <div>
    <h1>标题</h1>
  </div>
  <input type="button" value="点击">

  <script>
    // 功能:点击按钮,给div里增加一个img

    // 获取元素
    let btn = document.querySelector('input')
    let div = document.querySelector('div')
    let h1 = document.querySelector('h1')

    // 监听事件-点击事件
    btn.addEventListener('click', function() {
      // 1.创建标签:document.createElement('标签名')
      let imgs = document.createElement('img')
      // 设置src
      imgs.src = './images/1.webp'

      // 2. 增加节点
      // 2.1 追加节点:在父元素内部的最后添加子元素
      // 父节点.appendChild(子节点)
      div.appendChild(imgs)
      // 2.2 插入节点:在旧节点的前边插入新节点
      // 父.insertBefore.(新, 旧)
      div.insertBefore(imgs, h1)
    })
  </script>
</body>
</html>
8.2.2 克隆节点(复制节点)
<!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>
</head>
<body>
  <input type="button" value="点击" class="inp" />
    <div class="box" style="border: 1px solid #ccc">
      <img src="./images/b01.jpg" alt="" />
    </div>

    <script>
      // 克隆节点(复制节点)
      // 克隆:元素.cloneNode()  默认 false  克隆本身  不克隆元素里的节点内容
      // 克隆:元素.cloneNode(true)  添加true 就克隆全部  本身加全部子节点

      // 获取元素
      let btnn = document.querySelector(".inp")
      let divv = document.querySelector(".box")
      // 添加事件
      btnn.addEventListener("click", function () {
        // 克隆divv
        let dd = divv.cloneNode(true)
        // console.log( d )
        // 追加到 body 里面
        document.body.appendChild(dd)
      })
    </script>
</body>
</html>
8.2.3 移动追加节点
<!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>
</head>
<body>
  
  <input type="button" value="点击">
  <div class="d1">
    <img src="./images/1.webp" alt="">
  </div>
  <div class="d2">

  </div>

  <script>
  // 获取元素 
  let btn = document.querySelector('input')
  let img = document.querySelector('img')
  let d2 = document.querySelector('.d2')

  btn.addEventListener('click', function() {
    d2.appendChild(img)
  })
  </script>
</body>
</html>

8.3 删除节点

<!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>
</head>
<body>
  
  <input type="button" value="点击">

  <div>
    <img src="./images/1.webp" alt="">
  </div>

  <script>
    // 语法:父元素.removeChild(子元素)

    // 获取元素
    let btn = document.querySelector('input')
    let img = document.querySelector('img')
    
    // 点击事件
    btn.addEventListener('click', function() {
      img.parentNode.removeChild(img)
    })
  </script>
</body>
</html>

9. 时间对象

new Date()

new Date().toLocaleString()

9.1 创建时间对象

<!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>
</head>
<body>
  <script>
    // 0. 要想用到时间,必须先创建一个时间对象

    // 0.1 转换时间显示格式
    // 语法:时间变量.toLocaleString()
    // 含义:把时间转换成本地格式

    // 1. 创建时间对象 【返回的是外国时间格式】
    // 1.1 创建当前时间日期
    let t1 = new Date()
    console.log(t1.toLocaleString())
    // 1.2 创建指定时间日期  【返回日期为字符转形式】
    let t2 = new Date('2000-1-1 6:6:6')
    console.log(t2.toLocaleString())
    // 1.3 创建指定时间日期  【返回日期为数字形式】
    let t3 = new Date(2000, 1, 1, 6, 6, 6)
    console.log(t3.toLocaleString())
  </script>
</body>
</html>

9.2 时间日期对象

<!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>
</head>
<body>
  <script>
    // 获取当前日期
    let t = new Date()
    console.log(t.toLocaleString())
      
    // 获取 年
    let year = t.getFullYear()
    console.log(year)
      
    // 获取 月
    let month = t.getMonth() + 1
    console.log(month);
    // 返回值:0-11;返回的时间要比实际时间小 1;所以显示月份需要加 1

    // 获取 日
    let date = t.getDate()
    console.log(date)

    // 获取 时
    let hours = t.getHours()
    console.log(hours);

    // 获取 分
    let minutes = t.getMinutes()
    console.log(minutes);

    // 获取 秒
    let seconds = t.getSeconds()
    console.log(seconds);

    // 获取 毫秒
    let milliseconds = t.getMilliseconds()
    console.log(milliseconds);

    // 获取 星期几  
    let day = t.getDay()
    console.log(day);
    // 返回值:0-6;0 为星期日


    // 设置时间方法
    // 获取时间语法中的 get 改为 set
    // 不可以赋值,直接放到输出语句里【星期几不可以设置】

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

10. 时间戳

<!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>
</head>
<body>
  <script>
    // 时间戳:是指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式

    // 获取时间戳

    // 方法一   
    // 可以指定时间 获取对应的时间戳
    let t = new Date()  // 获取当前时间
    let re = t.getTime()  // 获取当前时间的时间戳
    console.log( re )

    // 方法二    
    // 可以指定时间 获取对应的时间戳
    console.log( +new Date() ) // 现在时间的时间戳

    // 方法三  
    // 不可以指定时间
    console.log( Date.now() ) //现在的时间戳
  </script>
</body>
</html>

11. 事件对象

11.1 事件对象

<!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>
</head>
<body>
  <script>
    // 事件对象:事件触发时产生的对象
      // 记录了和事件相关信息
    // 使用事件对象
    // 事件对象-使用:在事件处理函数,添加第一个形参就接受的事件处理对象
    // 通常:e、ev、e_、ev_、event
    document.addEventListener('click', function (e) {
      console.log(e);
    })

    document.addEventListener('dblclick', function (ev) {
      console.log(ev);
    })
  </script>
</body>
</html>

11.2 事件对象 - 鼠标移动

<!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;
    }
    div {
      margin-top: 200px;
      margin-left: 150px;
      width: 200px;
      height: 200px;
      background-color: skyblue;
    }
  </style>
</head>
<body>
  <div></div>
  <script>
    let div = document.querySelector('div')
    div.addEventListener('click',function(e) {
      // 获取事件对象的类型
      // 事件对象.type
      // 获取事件的类型
      console.log( e.type )
      // 获取鼠标的位置
      // 事件对象.clientX、事件对象.clientY
      // 获取鼠标距离可视窗口的位置
      console.log( e.clientX, e.clientY )
      // 事件对象.pageX、事件对象.pageX
      // 获取鼠标距离文档的位置
      console.log( e.pageX, e.pageY )
      // 事件对象.offsetX、事件对昂.offsetY
      // 获取鼠标距离当前元素的位置
      console.log( e.offsetX, e.offsetY )
    })
  </script>
</body>
</html>

11.3 事件对象 - 键盘按键值

<!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>按键值-e.key</title>
</head>
<body>
  <script>
    // 1. key  按键值
    // 他是事件对象的属性
    // 判断用户的按键值,根据不同的键值做出不同的操作
    document.addEventListener('keydown', function(e) {
      // 事件对象.key
      // console.log(e.key)
      if ( e.key === 'q' ) {
        console.log('q技能')
      } else if ( e.key === 'w' ) {
        console.log('w技能')
      }

    // 2. keyCode  键码值 -- 不推荐
    // if ( e.keyCode === 81 ) {
    //   console.log('全技能')
    // }

    // 3. 判断有没有按下功能健
    // 会返回一个布尔值
    console.log(e.ctrlKey)  // ture 或 fasle
    console.log(e.altKey)  // ture 或 fasle
    console.log(e.shiftKey)  // ture 或 fasle
    })
  </script>
</body>
</html>

12. 事件流

12.1 事件冒泡

<!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>
      div {
        width: 200px;
        height: 200px;
        background-color: red;
      }
      p {
        width: 100px;
        height: 100px;
        background-color: skyblue;
      }
    </style>
  </head>
  <body>
    <div>
      <p>段落</p>
    </div>

    <script>
      // 事件冒泡:
      // 含义:当一个元素被触发时,同样的事件将会在该元素的所有祖先中依次被触发,这一过程称为事件冒泡
      // 大白话:当一个元素触发事件后,会依次向上调用所有父元素的同名事件
      let p = document.querySelector('p')
      let div = document.querySelector('div')
      p.addEventListener('click', function() {
        console.log('p');
      })

      // 此时他的父级div也被点击了  没反应是因为没有事件监听
      div.addEventListener('click', function() {
        console.log('div');
      })

      // 此时他的父级的父级body也被点击了  没反应是因为没有事件监听
      document.body.addEventListener('click', function() {
        console.log('body');
      })

      // 此时他的父级的父级父级html也被点击了  没反应是因为没有事件监听
      document.documentElement.addEventListener('click', function() {
        console.log('html');
      })

      // 此时他的父级的父级父级父级document也被点击了  没反应是因为没有事件监听
      document.addEventListener('click', function() {
        console.log('document');
      })
    </script>
  </body>
</html>

12.2 事件捕获

<!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>
    <!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>
          div {
            width: 200px;
            height: 200px;
            background-color: red;
          }
          p {
            width: 100px;
            height: 100px;
            background-color: skyblue;
          }
        </style>
      </head>
      <body>
        <div>
          <p>段落</p>
        </div>

        <script>
          // 事件捕获
          // 每一个下级都会执行,也就是反过来的冒泡
          // DOM.addEventListener(事件类型, 事件处理函数, 是否开启捕获(布尔值,默认false))
          // 开启了捕获,事件冒泡还是存在的,但是没法开启,两者只能开启一个
          let p = document.querySelector("p")
          let div = document.querySelector("div")
          p.addEventListener(
            "click",
            function () {
              console.log("p")
            },
            true
          )

          div.addEventListener(
            "click",
            function () {
              console.log("div")
            },
            true
          )

          document.body.addEventListener(
            "click",
            function () {
              console.log("body")
            },
            true
          )

          document.documentElement.addEventListener(
            "click",
            function () {
              console.log("html")
            },
            true
          )

          document.addEventListener(
            "click",
            function () {
              console.log("document")
            },
            true
          )
        </script>
      </body>
    </html>

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

12.3 事件对象 - 阻止事件流动

<!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>
    <!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>
          div {
            width: 200px;
            height: 200px;
            background-color: red;
          }
          p {
            width: 100px;
            height: 100px;
            background-color: skyblue;
          }
        </style>
      </head>
      <body>
        <div>
          <p>段落</p>
        </div>

        <script>
          // 阻止事件流动  事件对象.stopPropaagation()
          let p = document.querySelector("p")
          let div = document.querySelector("div")
          p.addEventListener("click", function (e) {
            console.log("p执行了")
            // 阻止事件冒泡  谁产生的冒泡给谁
            // 事件对象.stopPropaagation()
            e.stopPropagation()
          })
          div.addEventListener("click", function () {
            console.log("div执行了")
            // 阻止事件捕获  谁产生的捕获给谁
            // 事件对象.stopPropaagation()
            // e.stopPropagation()
          })
        </script>
      </body>
    </html>

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

12.4 事件对象 - 阻止默认行为

<!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>
  </head>
  <body>
    <a href="http://www.baidu.com">连接</a>

    <script>
      let a = document.querySelector("a")
      a.addEventListener("click", function (e) {
        console.log("你好")

        // 阻止默认行为
        // 事件对象.preventDefault()
        e.preventDefault()
      })
    </script>
  </body>
</html>

13. 注册事件区别

<!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>
  </head>
  <body>
    <input type="button" value="点击" />

    <script>
      // 获取元素
      let btn = document.querySelector("input")

      // 注册事件区别:

      // 区别一: 事件数量
      // on:同类型的事件 on 只能注册一个,多个时后边覆盖前面
      // addEventListener:同类型的事件 事件监听 可以注册多个
      // 注册事件
      btn.onclick = function () {
        console.log(1) // 会被覆盖
      }
      btn.onclick = function () {
        console.log(2) // 2
      }

      function f1() {
        console.log("a")
      }
      function f2() {
        console.log("b")
      }
      btn.addEventListener("click", f1) // a
      btn.addEventListener("click", f2) // b

      // 区别二: 开启捕获
      // on:无法开启捕获
      // addEventListener:给第三个参数加true,可以开启捕获
      // 开启捕获
      btn.addEventListener("click",function () {
          console.log("a")
      },true)

      // 区别三: 移除事件
      // on:事件源.on事件类型 = null
      // addEventListener:事件源.removeEventListener('事件类型', 事件处理函数名);【匿名含数无法移除】
      // 移除事件
      btn.onclick = null
      btn.removeEventListener("click", f1)
      btn.removeEventListener("click", f2)
    </script>
  </body>
</html>

15. 最先触发事件的元素

<!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>
      div {
        width: 200px;
        height: 200px;
        background-color: red;
      }
      p {
        width: 100px;
        height: 100px;
        background-color: orange;
      }
    </style>
  </head>
  <body>
    <div>
      <p>段落</p>
    </div>

    <script>
      // 站在document的角度看  最先触发的事件源
      document.addEventListener("click", function (e) {
        // 事件对象.target:最先触发事件的元素
        console.log(e.target)
      })

      let div = document.querySelector("div")
      let p = document.querySelector("p")

      // 站在div的角度看  最先触发的事件源
      div.addEventListener("click", function (e) {
        // 事件对象.target:最先触发事件的元素
        console.log(e.target)
      })

      // 站在p的角度看  最先触发的事件源
      p.addEventListener("click", function (e) {
        // 事件对象.target:最先触发事件的元素
        console.log(e.target)
      })
    </script>
  </body>
</html>

16. 事件委托

<!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>
      li {
        margin: 10px 0;
        height: 30px;
        border: 1px solid #ccc;
      }
    </style>
  </head>
  <body>
    <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>
      <li>9</li>
      <li><a href="#">连接</a></li>
    </ul>

    <script>
      // 获取元素
      // let lis = document.querySelectorAll('li')
      let ul = document.querySelector("ul")

      // 事件委托:把事件委托给上级元素(不一定是父级)

      // 实现事件委托:(利用事件冒泡)
      // 第一步:把事件注册给上级元素
      // 第二部:利用事件对象.target找到最先触发事件的元素
      // 第三步:用nodeName判断这个元素是不是我们需要【注意nodeName的返回值为大写标签名】
      ul.addEventListener("click", function (e) {
        // e.target有可能是我们要找的元素也有可能不是
        // 如果e.target是我们要找的元素在加背景颜色
        if (e.target.nodeName === "LI") {
          e.target.style.background = "skyblue"
        }
      })

      // 动态创建的也会有事件
      let newLi = document.createElement('li')
      newLi.innerHTML = '新的li'
      ul.appendChild(newLi)
        
    </script>
  </body>
</html>

17. 三大家族

17.1 三大家族 - scroll家族

元素.scrollWidth、元素.scrollHeight

元素.scrollTop、元素.scrollLeft

<!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>三大家族-scroll家族</title>
    <style>
      div {
        margin: 10px;
        padding: 10px;
        width: 200px;
        height: 200px;
        background-color: orange;
        border: 2px solid red;
        overflow: auto;
      }
    </style>
  </head>
  <body>
    <button>点击回顶部</button>
    <div>
      <p>1</p>
      <p>2</p>
      <p>3</p>
      <p>4</p>
      <p>5</p>
      <p>6</p>
      <p>7</p>
      <p>8</p>
      <p>9</p>
      <p>10</p>
    </div>

    <script>
      // 获取元素
      let div = document.querySelector("div")
      let btn = document.querySelector("button")

      // scroll: scrollWidth、scrollHeight
      // 包含:内容 + padding + 溢出
      // 注意:获取的是数字值,只读属性
      console.log(div.scrollWidth, div.scrollHeight)
      // div.scrollWidth = 1000;  只读属性
      div.style.width = "500px"

      // scroll: scrollTop、scrollLeft
      // 获取元素卷出去的距离
      // 注意:获取的是数字
      // 注意:可获取可赋值
      div.addEventListener("scroll", function () {
        console.log(div.scrollTop)
      })
      btn.addEventListener("click", function () {
        div.scrollTop = 0
      })
    </script>
  </body>
</html>

17.2 三大家族 - offset家族

元素.offsetWidth、元素.offsetHeight

元素.offsetLeft、元素.offsetTop

<!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>三大家族-offset家族</title>
    <style>
      .box {
        margin: 10px;
        padding: 10px;
        width: 200px;
        height: 200px;
        border: 1px solid red;
        background-color: skyblue;
      }
      .father {
        position: relative;
        width: 200px;
        height: 200px;
        background-color: red;
      }
      .son {
        position: absolute;
        left: 20px;
        top: 30px;
        width: 100px;
        height: 100px;
        background-color: pink;
      }
    </style>
  </head>
  <body>
    <div class="box"></div>
    <div class="father">
      <div class="son"></div>
    </div>

    <script>
      // 获取元素
      let box = document.querySelector(".box")
      let father = document.querySelector(".father")
      let son = document.querySelector(".son")

      // 获取元素大小
      // 包含:内容 + padding + border
      // 注意:返回数字类型,只读属性
      console.log(box.offsetWidth, box.offsetHeight)

      // 获取相对于父盒子定位的位置
      // 如果上级都没定位就参照于文档(窗口、body)定位
      // 注意:返回数字型,只读属性
      console.log(son.offsetLeft, son.offsetTop)
    </script>
  </body>
</html>

17.3 三大家族 - clinet家族

元素.clientWidth、元素.clientHeight

元素.clientLeft、元素.clientTop

<!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>三大家族-clinet家族</title>
  <style>
    div {
      margin: 10px;
      padding: 10px;
      border: 10px solid #333;
      width: 200px;
      height: 200px;background-color: purple;
    }
  </style>
</head>
<body>
  
  <div></div>

  <script>
    let div = document.querySelector('div')
    // 获取元素大小
    // 包含:内容 + padding
    // 注意:数字类型,只读属性
    console.log( div.clientWidth,div.clientHeight );

    // 获取边框线的宽度
    console.log( div.clientLeft,div.clientTop )
  </script>
</body>
</html>

BOM - 浏览器对象模型

1. window对象

<!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>window对象</title>
</head>
<body>
  
  <script>
    // window: 全局对象,顶级对象
    
    // window对象:  5个BOM属性
    // navigator对象
    // location对象
    // document对象
    // history对象
    // screen对象

    // window  浏览器最大
    // document  文档最大

    // console.log( windows )  // windows 对象
    // console.log( this )  // windows 对象

    window.alert('弹出警告窗')
    window.prompt('请输入您的密码:')
    window.confirm('请确认密码')

    let timer = window.setInterval(function() {
      console.log('定时器')
    }, 1000)
    // 因为 window对象 最大,所以不写默认 window对象 开始找
    clearInterval(timer)

    function a () {
      console.log('a函数');
    }
    // a()
    // console.log( window )
    window.a()
  </script>
</body>
</html>

1.1 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>navigator对象</title>
  </head>
  <body>
    <script>
      // navigator对象
      // 浏览器对象

      // console.log( navigator )
      // console.log( navigator.userAgent )

      // 检测 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"
        }
      })()
    </script>
  </body>
</html>

1.2 location对象 - [ 地址栏对象 ]

<!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>location对象</title>
  </head>
  <body>
    <script>
      // location对象
      // 地址栏对象
        
      // console.log( window.location )
      // console.log( location )

      // 互联网协议
      // http://主机名:端口/路径/文件名?账号=whh&密码=123#哈希值(哈希值随便定义别中文)
      // http://主机名:80/user/a/b/index.html?user=whh&pwd=123#hash

      // 本地协议
      // file://

      document.addEventListener("click", function () {
        // 1. 属性:
        // 1.1 href:
        // 获取网页完整地址
        // console.log( location.href )
        // 更改地址
        // location.href = 'http://www.baidu.com'
        // 1.2 获取带的参数
        console.log(location.search)
        // 1.3 获取哈希值
        console.log(location.hash)

        // 2.方法:
        // 2.1 重新加载当前的 url
        location.reload()
        // 加 ture 强制刷新
        location.reload(true)

        // 2.2 加载指定的url
        // 产生历史记录(页面是可以返回的)
        location.assign("http://www.baidu.com")

        // 2.3 替换url
        // 不产生历史记录(页面不可返回)
        location.replace("http://www.baidu.com")
      })
    </script>
  </body>
</html>

1.3 document对象 - [ 文档对象 ]

 // 就是之前学的 - DOM对象

1.4 history对象 - [ 历史记录对象 ]

<!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>history对象</title>
  </head>
  <body>
    <script>
      // history对象
      // 历史记录对象

      console.log(window.history)
      console.log(history)

      // 1. history.length: 浏览网页次数
      // history.length

      // 2. history.back(): 返回历史记录的前一个
      // history.back()

      // 3.history.forward(): 前进历史记录的下一个
      // history.forward()

      // 4.history.go(): 正数为前进历史第num个,负数返回历史记录个
      // history.go(num)
    </script>
  </body>
</html>

1.5 screen对象 - [ 屏幕对象 ]

屏幕分辨率宽高: screen.width, screen.height

去除任务栏后的宽高: screen.availWidth, screen.availHeight

<!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>screen对象</title>
  </head>
  <body>
    <script>
      // screen对象
      // 屏幕对象

      // 1. 屏幕分辨率大小
      console.log(screen.width, screen.height)

      // 2. 除去任务栏的宽高
      console.log(screen.availWidth, screen.availHeight)
    </script>
  </body>
</html>

2. JS执行机制

同步

异步

<!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>JS执行机制</title>
  </head>
  <body>
    <script>
      // JS是单线程:同一时间只能做一件事

      // 为了处理这个问题:同步异步

      // 同步:前一个任务结束在执行后一个
      // 做水的十分钟完毕后在洗菜炒菜
      // 上来就要执行的代码 for  while  console.log

      // 异步:
      // 烧水的十分钟内去洗菜炒菜
      // 回调形式代码  各种事件  两个定时函数

      console.log(111)

      setTimeout(function () {
        console.log(222)
      }, 0)

      console.log(333)

      // 页面输出顺序
      // 111
      // 333
      // 222
    </script>
  </body>
</html>

3. 本地存储

存数据: localStorage.setItem(‘键’, ‘值’)

取数据: localStorage.getItem(‘键名’)

删数据: localStorage.removeItem(‘键名’)

<!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>
  </head>
  <body>
    <script>
      // 本地存储
      // 把数据存到本地浏览器里

      // 方式一: localStorage    空间 5M
      // 声明周期永久生效,除非手动删除 否则关闭页面也会存在
      // 可以多窗口(页面)共享(同一浏览器可共享)
      // 以键值对的形式存储使用

      // 1. 存数据
      // 语法: localStorage.setItem('键', '值')
      localStorage.setItem("userName", "张三丰")
      // localStorage.setItem( 'age', '22' )
      // 注意:如果键名相同,键值覆盖
      localStorage.setItem("age", "24")

      // 2. 取数据
      // 语法: localStorage.getItem('键名')
      let re = localStorage.getItem("age")
      console.log(re)
      let userName = localStorage.getItem("userName")
      console.log(userName)
      // 注意:取数据,取得是不存在的键名取到的是 null
      let uName = localStorage.getItem("uName")
      console.log(uName) // null

      // 3. 删数据
      // 语法: localStorage.removeItem('键名')
      localStorage.removeItem("age")
      localStorage.removeItem("userName")
    </script>
  </body>
</html>

4. JSON对象

复杂数据 转为 JSON 字符串: JSON.stringify(变量名)

JSON 字符串 还原 复杂数据: JSON.parse(变量名)

<!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>JSON对象</title>
  </head>
  <body>
    <script>
      // uname == '张三丰'
      // age == 22
      // score == 99
      // localStorage.setItem('uname', '张三丰')
      // localStorage.setItem('age', 22)
      // localStorage.setItem('score', 99)

      let obj = { uname: "张三丰", age: 22, score: 99 }
      // 1. 复杂数据 转换 JSON 字符串
      let str = JSON.stringify(obj)
      // 2. 存数据
      localStorage.setItem("arr", str)
      // 3. 取数据
      let re = localStorage.getItem("arr")
      // 4. JSON 字符串 还原 复杂数据
      let ree = JSON.parse(re)
      console.log(ree)

      let arr = [
        { uname: "刘备", age: 26 },
        { uname: "关羽", age: 25 },
        { uname: "张飞", age: 24 },
        { uname: "马超", age: 23 },
        { uname: "黄忠", age: 22 },
      ]
      localStorage.setItem("arr", JSON.stringify(arr))
      let rree = JSON.parse(localStorage.getItem("arr"))
      console.log(rree)
    </script>
  </body>
</html>

5. 自定义属性

<!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>
  </head>
  <body>
    <!-- 自定义属性 -->
    <!-- index="666"  为自定义属性 -->
    <!-- data-type="elm"  为自定义属性 【 H5新增 自定义属性前加data- [ 推荐 ] 】 -->
    <div id="box" title="div标题" index="666" data-type="elm">hihi</div>

    <script>
      // 自定义属性
      // 作用: 为了让元素附加的带属性

      let div = document.querySelector("div")
      // console.log( div.index );  // 这样写是不对的 undefined

      // 1. 获取自定义的属性
      // 语法: getAttribute('属性名')
      console.log(div.getAttribute("index"))
      console.log(div.getAttribute("data-type"))

      // 2. 设置添加自定义的属性
      // 语法:setAttribute('属性名', '属性值')
      // 有就更改,没有就增加
      div.setAttribute("index", "999")
      div.setAttribute("aaa", "bbb")

      // 3. 移除自定义的属性
      div.removeAttribute("index")
      // div.removeAttribute('data-type')

        
      // 针对于:data-xxx 的自定义属性:
      // 语法:元素.dataset.xxx
      // 查
      console.log(div.dataset.type)
      // 增
      div.dataset.abc = "aabbcc"
      // 改
      div.dataset.type = "pipi"
    </script>
  </body>
</html>

6. 正则表达式 - 创建 - 基本使用

<!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>
  </head>
  <body>
    <script>
      // 字面量:一眼就看出来数据类型

      // 正则表达式
      // 作用:用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象
      // 场景:验证表单,过滤敏感词

      // 1. 创建正则
      // 1.1 字面量创建正则表达式
      let reg = /哇哈哈/ // 含义:匹配(包含)123字符
      console.log(reg) // /哇哈哈/
      // 1.2 实例化对象创建正则表达式
      let regg = new RegExp(/abc/)
      console.log(regg) // /abc/

      // 2.正则查找匹配
      // 2.1 查看正则表达式与指定的字符串是否匹配
      // 语法:变量名.test()
      // 返回值:true, false
      // 正则表达式与指定的字符串匹配 ,返回true,否则false
      let re = reg.test("asdgfadgfadsgfgaw哇哈哈dsadfagdfajgdalksgnvoa")
      console.log(re) // true

      // 2.2 在一个指定字符串中执行一个搜索匹配
      // 语法:变量名.exec()
      // 返回值:数组, null
      // 如果匹配成功,exec() 方法返回一个数组,否则返回null
      let ree = reg.exec("asdgfadgfadsgfgaw哇哈哈dsadfagdfajgdalksgnvoa")
      console.log(ree) // ['哇哈哈', index: 17, input: 'asdgfadgfadsgfgaw哇哈哈dsadfagdfajgdalksgnvoa', groups: undefined]

      // 普通字符:
      // 大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。也就是说普通字符只能够匹配字符串中与它们相同的字符。

      // 元字符(特殊字符):
      // 是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
      // 比如,规定用户只能输入英文26个英文字母,普通字符的话 abcdefghijklm…..
      // 但是换成元字符写法: [a-z]

      // 正则测试工具:
      // http://tool.oschina.net/regex
    </script>
  </body>
</html>

7. 元字符(特殊字符)

  • 普通字符:

    • 大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。也就是说普通字符只能够匹配字符串中与它们相同的字符。
  • 元字符(特殊字符):

    • 是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
      • 比如,规定用户只能输入英文26个英文字母,普通字符的话 abcdefghijklm……
      • 但是换成元字符写法: [a-z]
  • 正则测试工具:

    • http://tool.oschina.net/regex

7.1 元字符-边界符

<!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>
  </head>
  <body>
    <script>
      // 1. ^: 以xxx为开头
      // xxx为一个整体,区分大小写
      let reg1 = /^abc/
      console.log(reg1.test("aabbcc")) // false
      console.log(reg1.test("abc123abc")) // true
      console.log(reg1.test("Abc")) // false
      console.log(reg1.test("a123")) // false

      // 2. $: 以xxx为结尾
      let reg2 = /abc$/
      console.log(reg2.test("123Abc")) // false
      console.log(reg2.test("abcabc123")) // false
      console.log(reg2.test("abcabc")) // true

      // 3. ^$: 同时使用^$具有精确匹配含义
      // 以a为开头,以c为结尾,中间只能是b
      let reg3 = /^abc$/
      console.log(reg2.test("Abc")) // false
      console.log(reg2.test("Abc123")) // false
      console.log(reg2.test("abcabc")) // false
      console.log(reg2.test("abc")) // true
    </script>
  </body>
</html>

7.2 元字符 - 量词符

<!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>
  </head>
  <body>
    <script>
      // 【注意:逗号两边不要出现空格】
      // 1. *: 0次或者更多次 >= 0
      let reg1 = /^a*$/
      console.log(reg1.test("")) // true
      console.log(reg1.test("a")) // true
      console.log(reg1.test("aa")) // true
      console.log(reg1.test("Aaa")) // false
      console.log(reg1.test("b")) // false
      console.log(reg1.test("ab")) // false

      // 2. +: 1次或者更多次 >= 1
      let reg2 = /^a+$/
      console.log(reg2.test("")) // false
      console.log(reg2.test("a")) // true
      console.log(reg2.test("aa")) // true
      console.log(reg2.test("Aaa")) // false
      console.log(reg2.test("b")) // false
      console.log(reg2.test("ab")) // false

      // 3. ?: 0次或者1次
      let reg3 = /^a?$/
      console.log(reg3.test("")) // true
      console.log(reg3.test("a")) // true
      console.log(reg3.test("aa")) // false
      console.log(reg3.test("Aaa")) // false
      console.log(reg3.test("b")) // false
      console.log(reg3.test("ab")) // false

      // 4. {n}:重复n次
      let reg4 = /^a{3}$/
      console.log(reg4.test("")) // false
      console.log(reg4.test("a")) // false
      console.log(reg4.test("aa")) // false
      console.log(reg4.test("aaa")) // true
      console.log(reg4.test("aAa")) // false
      console.log(reg4.test("aaaa")) // false

      // 5. {n,}:重复n次或者更多次
      let reg5 = /^a{3,}$/
      console.log(reg5.test("")) // false
      console.log(reg5.test("a")) // false
      console.log(reg5.test("aa")) // false
      console.log(reg5.test("aaa")) // true
      console.log(reg5.test("aAa")) // false
      console.log(reg5.test("aaaa")) // true
      console.log(reg5.test("aaaaa")) // true

      // 6. {n,m}:重复n次到m次
      let reg6 = /^a{3,4}$/
      console.log(reg6.test("")) // false
      console.log(reg6.test("a")) // false
      console.log(reg6.test("aa")) // false
      console.log(reg6.test("aaa")) // true
      console.log(reg6.test("aAa")) // false
      console.log(reg6.test("aaaa")) // true
      console.log(reg6.test("aaaaa")) // false

      let reg = /^a*b+c?d*$/
      console.log(reg.test("bd")) // true
      console.log(reg.test("abcddddddd")) // true
      console.log(reg.test("bcccdd")) // false
    </script>
  </body>
</html>

7.3 元字符 - 字符集合

<!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>
  </head>
  <body>
    <script>
      // 字符集合:[很多字符]  多选一
      // 表示匹配多选一

      // 1. /^[abc]$/: 在 a、b、c 中选一个
      let reg1 = /^[abc]$/
      console.log(reg1.test("a")) // true
      console.log(reg1.test("ab")) // false
      console.log(reg1.test("aa")) // false
      console.log(reg1.test("abc")) // false

      // 2. /^[a-z]$/: 小写字母 a 到 z 中选一个
      let reg2 = /^[a-z]$/
      console.log(reg2.test("a")) // true
      console.log(reg2.test("M")) // false
      console.log(reg2.test("D")) // false
      console.log(reg2.test("aa")) // false
      console.log(reg2.test("AB")) // false

      // 3. /^[a-zA-Z]$/: 小写字母 a 到 z, 大写字母 A 到 Z 中选一个
      let reg3 = /^[a-zA-Z]$/
      console.log(reg3.test("a")) // true
      console.log(reg3.test("M")) // true
      console.log(reg3.test("D")) // true
      console.log(reg3.test("ab")) // false
      console.log(reg3.test("Ab")) // false
      console.log(reg3.test("6")) // false

      // 4. /^[a-zA-Z0-9]$/: 小写字母 a 到 z, 大写字母 A 到 Z, 数字 0 到 9 中选一个
      let reg4 = /^[a-zA-Z0-9]$/
      console.log(reg4.test("a")) // true
      console.log(reg4.test("M")) // true
      console.log(reg4.test("D")) // true
      console.log(reg4.test("ab")) // false
      console.log(reg4.test("Ab")) // false
      console.log(reg4.test("6")) // true

      // 5. /^[a-zA-Z0-9_-]$/:  小写字母 a 到 z, 大写字母 A 到 Z, 数字 0 到 9, _(下划线) -(中划线) 中选一个
      let reg5 = /^[a-zA-Z0-9_-]$/
      console.log(reg5.test("a")) // true
      console.log(reg5.test("M")) // true
      console.log(reg5.test("-")) // true
      console.log(reg5.test("ab")) // false
      console.log(reg5.test("Ab")) // false
      console.log(reg5.test("6")) // true
      console.log(reg5.test("_")) // true
    </script>
  </body>
</html>

7.4 元字符 - 其他元字符

<!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>
</head>
<body>
  <script>
    // 1. [^]: 取反
    // /^[^a-z]$/  除了小写字母 a 到 z 中 的其他一个
    let reg1 = /^[^a-z]$/
    console.log( reg1.test('k') ) // false
    console.log( reg1.test('*') ) // true
    console.log( reg1.test('kk') ) // false

    // 2. .: 匹配除了 \n(换行) 之外的任意的单个字符
    let reg2 = /^.$/
    console.log( reg2.test('k') ) // true
    console.log( reg2.test('*') ) // true
    console.log( reg2.test('aa') ) // false
    console.log( reg2.test('\n') ) // false

    // 3.1 (): 组  
    // 3.2 |: 或
    let reg3 = /^(.|\n)$/  // 匹配任意一个单字符
    console.log( reg3.test('a') ) // true
    console.log( reg3.test('6') ) // true
    console.log( reg3.test('*') ) // true
    console.log( reg3.test('_') ) // true
    console.log( reg3.test('-') ) // true
    console.log( reg3.test('!') ) // true
    console.log( reg3.test('\n') ) // true

    // 4. 注意: [] 的注意事项
    // [] 有转义字符的作用
    let reg4 = /^[男|女]$/
    console.log( reg4.test('男') ) // true
    console.log( reg4.test('|') ) // true
    console.log( reg4.test('女') ) // true
    let reg5 = /^[.\n]$/
    console.log( reg5.test('*') ) // false
    console.log( reg5.test('.') ) // true
    console.log( reg5.test('\n') ) // true

    // 男或女
    // /^[男女]$/  ==  /^(男|女)$/

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

7.5 元字符 - 预定义类

<!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>
</head>
<body>
  <script>
    // 预定义:提前定义好某些模式,用的时候直接使用就好

    // 1. \d: [0-9]
    let reg1 = /^\d$/
    console.log( reg1.test('6') ) // true
    console.log( reg1.test('a') ) // false

    // 2. \D: [^0-9]
    let reg2 = /^\D$/
    console.log( reg2.test('6') ) // false
    console.log( reg2.test('66') ) // false
    console.log( reg2.test('a') ) // true

    // 3. \w: [A-Za-z0-9_]
    let reg3 = /^\w$/
    console.log( reg3.test('*') ) // false
    console.log( reg3.test('M') ) // true

    // 4. \W: [^A-Za-z0-9_]
    let reg4 = /^\w$/
    console.log( reg4.test('*') ) // true
    console.log( reg4.test('M') ) // false

    // 5. \s: [\r\n\t]
    let reg5 = /^\s$/
    console.log( reg5.test('a') ) // false
    console.log( reg5.test(' ') ) // ture

    // 5. \S: [^\r\n\t]
    let reg6 = /^\S$/
    console.log( reg6.test('a') ) // true
    console.log( reg6.test(' ') ) // false
  </script>
</body>
</html>

8. 正则表达式 - 修饰符

<!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>
  </head>
  <body>
    <script>
      // 字符串
      let str = " abcdABCD "

      // trim: 去除字符串两端的空格
      // 语法:字符串.trim()
      str = str.trim()
      // console.log( str ); // abcdABCD

      // replace: 字符串替换
      // 语法:字符串.replace( 旧, 新 )
      str = str.replace("c", "$")
      // console.log( str ); // ab$dABCD

      // 修饰符
      // 1. g: 全局匹配
      str = str.replace(/c/g, "&&")
      console.log(str) // ab&&dABCD

      // 2. i: 忽略大小写
      str = str.replace(/c/i, "&&")
      console.log(str) // ab&&dAB&&D
    </script>
  </body>
</html>

Web APIs - 案例

1. 练习-页面随机背景颜色

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

  <script>
    // 封装函数 获取一个 0 - 255 (包含255随机数)
    function getColor() {
      return Math.floor( Math.random() * 256 )
    } 
    document.body.style.background = `rgb(${getColor()}, ${getColor()}
    // 语法:元素.style.属性名 = 值
    // document.body.style.background = `rgb(${getColor()}, ${getColor()}, ${getColor()})`
  </script>
</body>
</html>

2. 案例-定时器案例

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

	<script>
			
	// 1. 思考倒计时功能
    // 2. 思考用到哪个页面元素
    // 思路:

    // 定时器实现每隔一秒修改 input 的 value 值,让数字每隔一秒减 1
    let btn = document.querySelector('#btn')
    // 因为没有一个变量表示时间,所以没法减,自己定义一个变量用来表示时间
    let i = 5

    // 定义函数
    function fn() {

      // 让 i-- 达到计时,并显示到页面
      i--
      // 当 i 改变后,设置到value中,让用户看到
      btn.value = `已阅读用户协议(${i})`

      // 增加计时器结束条件
      if (i === 0) {
        // 让按钮变成可点击状态
        btn.disabled = false
        // 关闭计时器
        clearInterval(t1)
        // 计时结束后 把时间去掉
        btn.value = `已阅读用户协议`
      }
    }

    let t1 = setInterval( fn, 1000 )
	</script>
</body>
</html>

3. 案例 - 全选反选

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

    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>
      // 功能一
      // 点击大选框所有小选框跟着选中
      // 功能二
      // 取消大选框小选矿跟着取消

      // 获取元素
      let checkAll = document.querySelector('#checkAll')
      let all = document.querySelector('.all')
      let cks = document.querySelectorAll('.ck')

      // 功能一
      // 点击全选按钮控制小按钮选中选不中
      checkAll.addEventListener('click', function() {
        // 获取全选的 checked
        let flag = checkAll.checked
        // 让小按钮的选中选不中跟随大按钮
        for (let i = 0; i < cks.length; i++) {
          cks[i].checked = flag
        }
        // 判断文字: 大按钮为选中的话返回 '取消'; 为未选中返回 '全选' 返回到桌面上
        all.innerHTML = flag ? '取消' : '全选'
      })


      // 如果所有小按钮都是选中的那么大按钮就为选中
      // 如果所有小按钮只要有一个未选中大按钮就为未选中
      // 给所有小按钮添加点击事件


      // 功能二
        
      // 方法一
      // 判断按钮的个数 和 选中按钮的个数
      /* for (let i = 0; i < cks.length; i++) {
        cks[i].addEventListener('click', function() {
          // 点击一次小按钮,判断一次要不要让大按钮选中
          // 小按钮的个数
          let len1 = cks.length
          // 被选中的小按钮个数
          // ck:checked   按钮并被选中
          let len2 = document.querySelectorAll('.ck:checked').length

          checkAll.checked = len1 === len2

          // // 判断
          // if (len1 === len2) {
          //   checkAll.checked = true
          // } else {
          //   checkAll.checked = false
          // }
        })
      } */


      // 方法二
      // 点击一次小按钮,判断一次三个小按钮是否都被选中
      // 如果三个小按钮都被选中,则大按钮选中  否则反之
      // 给三个小按钮添加点击事件
      for (let i = 0; i < cks.length; i++) {
        cks[i].addEventListener('click', function() {
          // 三个小按钮的总初始为false
          let flag = true
          // 遍历小所有小按钮是否被选中
          for (let j = 0; j < cks.length; j++) {
            // 和初始true做 && 运算 这样 一个为假 都为假
            flag = flag && cks[j].checked
            // console.log(flag)
          }
          // console.log(flag)
          
          // 判断  如果三个小按钮都被选中,大按钮也为选装,并更换后面文字
          checkAll.checked = flag ? true : false
          // 判断文字: 大按钮为选中的话返回 '取消'; 为未选中返回 '全选' 返回到桌面上
          all.innerHTML = flag ? '取消' : '全选'
        })
      }
    </script>
  </body>

</html>

4. 案例 - 排他思想

<!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>
</head>
<body>
  
  <input type="button" value="点击">
  <input type="button" value="点击">
  <input type="button" value="点击">
  <input type="button" value="点击">
  <input type="button" value="点击">
  <input type="button" value="点击">
  <input type="button" value="点击">
  <input type="button" value="点击">

  <script>
    // 获取元素
    let btns = document.querySelectorAll('input')

    // 循环添加点击事件
    // 点击谁 谁的背景颜色变为 天蓝色,其他颜色不能有背景颜色
    // 排他思想:
    //  1. 先清除所有的背景颜色
    //  2. 在给自己添加背景颜色

    // 循环遍历 bnts 添加点击事件
    for (let i = 0; i < btns.length; i++) {
      btns[i].addEventListener('click', function(){
        // 1. 先清除所有的背景颜色
        for (let j = 0; j < btns.length; j++) {
          btns[j].style.background = ''
        }
        // 2. 在给自己添加背景颜色
        // 这里的 this 指向的是 事件源 也就是被点击的那个
        this.style.background = 'skyblue'
      })
    }
  </script>
</body>
</html>

5. 练习 - 新增节点

<!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>
</head>
<body>
  
  <input type="button" value="点击">
  <div></div>

  <script>
    // 点击按钮往div里面添加p标签
    // 获取元素
    let btn = document.querySelector('input')
    let div = document.querySelector('div')

    // 添加事件
    btn.addEventListener('click',function() {
      // 创建 p 标签
      let p = document.createElement('p')
      p.innerText = '我是一个新的 P 标签'

      // 放到 div 里
      div.appendChild(p)
    })
  </script>
</body>
</html>

6. 案例 - 时间格式化

<!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>
      div {
        height: 100px;
        font-size: 30px;
        text-align: center;
        line-height: 100px;
        color: orange;
        background-color: skyblue;
      }
    </style>
  </head>
  <body>
    <div>时间</div>

    <script>
      // 转换时间格式 YYYY-MM-DD HH:mm:ss
        
      // 获取元素
      let div = document.querySelector("div")

      // 封装函数:页面显示一次当前时间
      function showTime() {
        // 获取时间日期对象
        let t = new Date()
        // 分别获取单个时间信息  年 月 日 时 分 秒
        let year = t.getFullYear()
        let month = t.getMonth() + 1
        let date = t.getDate()
        let hours = t.getHours()
        let minutes = t.getMinutes()
        let seconds = t.getSeconds()
        // 设置内容之前查看是否补0操作
        month = month < 10 ? "0" + month : month
        date = date < 10 ? "0" + date : date
        hours = hours < 10 ? "0" + hours : hours
        minutes = minutes < 10 ? "0" + minutes : minutes
        seconds = seconds < 10 ? "0" + seconds : seconds
        // 设置内容
        div.innerText = `${year}-${month}-${date} ${hours}:${minutes}:${seconds}`
      }
      // 现在页面显示一次当前时间
      showTime()
      // 每隔一秒调用一遍函数
      setInterval(showTime, 1000)
    </script>
  </body>
</html>

7. 案例 - tab栏切换

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8" />
  <title>案例-tab栏切换</title>
  <style type="text/css">
    * {
      margin: 0;
      padding: 0;
    }

    ul {
      list-style: none;
    }

    .wrapper {
      width: 1000px;
      height: 475px;
      margin: 0 auto;
      margin-top: 100px;
    }

    .tab {
      border: 1px solid #ddd;
      border-bottom: 0;
      height: 36px;
      width: 320px;
    }

    .tab li {
      position: relative;
      float: left;
      width: 80px;
      height: 34px;
      line-height: 34px;
      text-align: center;
      cursor: pointer;
      border-top: 4px solid #fff;
    }

    .tab span {
      position: absolute;
      right: 0;
      top: 10px;
      background: #ddd;
      width: 1px;
      height: 14px;
      overflow: hidden;
    }

    .products {
      width: 1002px;
      border: 1px solid #ddd;
      height: 476px;
    }

    .products .main {
      float: left;
      display: none;
    }

    .products .main.active {
      display: block;
    }

    .tab li.active {
      border-color: red;
      border-bottom: 0;
    }
  </style>
</head>

<body>
  <div class="wrapper">
    <ul class="tab">
      <li class="tab-item active">国际大牌<span></span></li>
      <li class="tab-item">国妆名牌<span></span></li>
      <li class="tab-item">清洁用品<span></span></li>
      <li class="tab-item">男士精品</li>
    </ul>
    <div class="products">
      <div class="main active">
        <a href="###"><img src="imgs/guojidapai.jpg" alt="" /></a>
      </div>
      <div class="main">
        <a href="###"><img src="imgs/guozhuangmingpin.jpg" alt="" /></a>
      </div>
      <div class="main">
        <a href="###"><img src="imgs/qingjieyongpin.jpg" alt="" /></a>
      </div>
      <div class="main">
        <a href="###"><img src="imgs/nanshijingpin.jpg" alt="" /></a>
      </div>
    </div>
  </div>

  <script>
    // 获取元素
    let tabItems = document.querySelectorAll('.tab-item')
    let mains = document.querySelectorAll('.main')

    // 遍历 tabItems 添加点击事件
    for (let i = 0; i < tabItems.length; i++) {
      tabItems[i].addEventListener('click', function() {
        // 排他思想
        // 1. 遍历所有的 tabItems 和 mains  清除类名
        for (let j = 0; j < tabItems.length; j++) {
          // 清除类名
          // 清除tabItems的所有类名
          tabItems[j].classList.remove('active')
          // 清除mains的所有类名
          mains[j].classList.remove('active')
        }
        // 2. 给自己添加类名
        // 给点击的tabItems[i]添加类名  这里的this指向的是事件源,调用者
        this.classList.add('active')
        // 给tabItems[i]对应的mains[i]添加类名
        mains[i].classList.add('active')
      })
    }
    
  </script>

</body>

</html>

8. 练习 - 递归延迟性定时器

<!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>
      div {
        height: 60px;
        font-size: 40px;
        text-align: center;
        line-height: 60px;
        color: orange;
        background-color: gray;
      }
    </style>
  </head>
  <body>
    <div>时间</div>

    <script>
      function showTime() {
        let t = new Date()
        document.querySelector("div").innerHTML = `${t.toLocaleString()}`
        setTimeout(showTime, 1000)
      }
      showTime()
      // setInterval( showTime, 1000 )
    </script>
  </body>
</html>

Web APIs - 知识点

  • Web APIs:操作网页文档或者浏览器的一堆方法

1. DOM

  • 定义
    • DOM(Document Object Model): 文档对象模型
  • 作用
    • 实现网页效果,交互效果
  • 节点
    • 元素节点、属性节点、文本节点、注释节点

2. 事件

  • 定义
    • 在编程时系统内发生的动作或发生的事情

2.1 事件监听

  • 就是让程序检测是否有事件产生,一旦有触发,就立即调用一个函数做出相应,也成为(注册事件)
  • 语法
    • 元素.addEventListener(‘事件’, 函数)

3. 排他思想

  • 逻辑

    1. 先清除所有的背景颜色

    2. 在给自己添加背景颜色

  • 思维

    1. 先干掉所有人
    2. 在复活自己

4. 节点操作

4.1 节点操作

  • 返回值:1 为元素节点;2为属性节点;3为文本节点

    1. 查看节点类型
    • 语法:父.childNodes[0].nodeType
    • 会返回指一个数
    1. 查看节点名称
    • 语法:父.childNodes[0].nodeName == 父.childNodes[0].tagName
    • 会返回指一个数

4.2 查找节点

    1. 父节点查找
    • 语法:子.parentNode
    • 返回一个节点
    1. 子节点查找
    • 查找所有子节点
      • 语法:父.childNodes
      • 返回一个伪数组
    • 查找所有元素子节点
      • 语法:父.children
      • 返回一个伪数组
    • 查找第一个元素子节点
      • 语法:父.fristElementChild
      • 返回一个元素节点
    • 查找最后一个元素子节点
      • 语法:父.lastElementChild
      • 返回一个元素节点
    1. 兄弟节点的查找
    • 查找前一个兄弟元素节点
      • 语法:自.previousElementSibling
      • 返回一个元素节点
    • 查找下一个兄弟元素节点
      • 语法:自.nextElementSibling
      • 返回一个元素节点

4.3 增加节点

  • 第一步:新建元素
    • 语法:let elmt = document.createElement(‘标签名’)
    • 返回一个元素,配合变量接收使用
  • 第二部:增加节点
    • 增加节点
      • 语法:父.appendChild(新)
      • 在父元素内部,最后添加一个新元素
    • 插入节点
      • 语法:父.insertBefore(新, 旧)
      • 在父元素内部,旧元素的前面插入一个新元素

4.4 克隆节点

  • 克隆节点本身,不克隆元素里面的内容
    • 语法:被克隆元素.cloneNode() == 被克隆元素.cloneNode(false)
    • 返回一个元素
    • 默认
  • 克隆节点本身,克隆元素里面的内容
    • 语法:被克隆元素.cloneNode(true)
    • 返回一个元素
  • 然后追加到某个节点下

4.5 移动追加元素

  • 第一步:获取到想要移动的元素【不是新建】
  • 第二部:增加到某个节点下

4.6 删除节点

  • 语法:删除元素的父元素.removeChild(要删除的元素)

5. 重绘和回流

【重绘不一定引起回流,而回流一定会引起重绘】

  • .trim() 去除字符串两端的空格

BOM - 浏览器对象模型

1. window

  • 全局对象

2. swiper插件

  • 功能

    • 专门做轮播图的插件网站
  • 网址

    • https://www.swiper.com.cn/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值