2024字节青训营笔记(三) DOM相关知识

91 阅读3分钟

DOM作用

开发网页特效、实现用户交互

DOM树

体现了标签和标签的关系

DOM对象 (重要)

<div>123</div>

    <script>
        const div = document.querySelector('div')
        console.dir(div);
    </script>

DOM核心思想,把网页内容当作对象

document是一个对象,整个页面中最大的一个对象

获取DOM元素

CSS选择器获取

只匹配的第一个元素

<div class="box">123</div>

    <div class="box">abc</div>

    <script>
        const box = document.querySelector('div')
        console.log(box)

    </script>

获取所有的

<div class="box">123</div>

    <div class="box">abc</div>

    <script>
        const box = document.querySelectorAll('div')
        console.log(box)

    </script>

SelectorAll获得的是伪数组

 <ul>
        <li>我的首页</li>

        <li>产品介绍</li>

        <li>联系方式</li>

    </ul>

    <script>
        const lis = document.querySelectorAll('ul li')
        for (let i = 0; i < lis.length; i++) {
            console.log(lis[i]);
        }
    </script>

操作元素内容

.innerText

只改内容,不解析标签

<div class="box">文字内容</div>

    <script>
        const box = document.querySelector('.box')
        box.innerText = '盒子'
    </script>

.innerHTML

也可以解析标签

<div class="box">文字内容</div>

    <script>
        const box = document.querySelector('.box')
        box.innerHTML = '<strong>更换</strong>'
    </script>

随机数抽奖案例

 <div>
        <li one></li>

        <li two></li>

        <li three></li>

    </div>

    <script>
        const personArr = ['小明', '小红', '小蓝', '小绿', '小粉']
        const radom = Math.floor(Math.random() * personArr.length)


        const lis = document.querySelectorAll('div li')
        for (let i = 0; i < lis.length; i++) {
            const radom = Math.floor(Math.random() * personArr.length)
            lis[i].innerHTML = personArr[radom]
            personArr.splice(radom, 1)
        }
    </script>

修改元素属性

常用属性

<img src="tk.jpg" alt="">
    <script>
        const pic = document.querySelector('img')
        pic.src = 'h.jpg'
    </script>

刷新随机修改图片案例:

 <img src="pic1.jpg" alt="">
    <script>
        function getRandom(N, M) {
            return Math.floor(Math.random() * (M - N + 1)) + N
        }
        const img = document.querySelector('img')
        const random = getRandom(1, 7)
        img.src = `pic${random}.jpg`
    </script>

修改样式

通过style

<div class="box"></div>

    <script>
        const box = document.querySelector('.box')
        box.style.width = '300px'
        box.style.backgroundColor = 'yellow'
        box.style.border = '2px solid red'
        box.style.borderBottom = '2px solid pink'
    </script>

记得加单位、小驼峰命名

通过类名(修改的样式很多的时候)

 const div = document.querySelector('div')
 div.className = 'box'
div {
            width: 200px;
            height: 200px;
            background-color: pink;
        }

        .box {
            background-color: aqua;
        }

注意会直接覆盖以前的类名,可以两个类名都写上

classList(常用,重点!)

追加类

const div = document.querySelector('div')
        div.classList.add('active')

删除类

div.classList.remove('box')

切换类

toggle,有就删掉,没有就加上

修改表单属性

获取表单里的内容只能用value,innerHTML不可以

<input type="text" value="电脑">
    <script>
        const uname = document.querySelector('input')
        console.log(uname.value);
    </script>
const uname = document.querySelector('input')
 uname.value = '我要买电脑'

复选框,是否勾选,checked改为ture或者false

<input type="checkbox" name="" id="">
    <script>
        const ipt = document.querySelector('input')
        ipt.checked = true
    </script>

button,禁用,disabled

const button = document.querySelector('button')
 button.disabled = false

自定义属性

xxx.dataset.xxx

<div data-id="1" data-s="不知道">1</div>

    <div data-id="2">2</div>

    <div data-id="3">3</div>

    <div data-id="4">4</div>

    <div data-id="5">5</div>

    <script>
        const one = document.querySelector('div')
        console.log(one.dataset.id);
        console.log(one.dataset.s);
    </script>

定时器-间歇函数

用于网页中的倒计时

开启定时器:

setInterval(function () {
            console.log('一秒执行一次');
        }, 1000)
function fn() {
            console.log('一秒执行一次');

        }
        setInterval(fn, 1000)

函数名不需要加括号,每个定时器都有一个编号

关闭定时器:

 function fn() {
            console.log('一秒执行一次');

        }
        let n = setInterval(fn, 1000)
        clearInterval(n)

阅读用户协议案例

<button>已阅读用户协议(5)</button>

    <script>
        const button = document.querySelector('button')
        button.disabled = true

        let i = 5
        let num = setInterval(function () {
            i--
            button.innerHTML = `已阅读用户协议(${i})`
            if (i == 0) {
                clearInterval(num)
                button.disabled = false
                button.innerHTML = '同意协议'
            }
        }, 1000)
    </script>

自动轮播图案例

   const img = document.querySelector('.slider-wrapper img')
    const p = document.querySelector('.slider-footer p')

    let i = -1
    setInterval(function () {
      i++
      img.src = sliderData[i].url
      p.innerHTML = sliderData[i].title

      document.querySelector('.slider-indicator .active').classList.remove('active')

      document.querySelector(`.slider-indicator li:nth-child(${i + 1})`).classList.add('active')
      if (i == 7) {
        i = -1
      }
    }, 1000)

classList.remove 移除上一个不用的小圆点 有事件发生,用一个函数响应

语法:元素对象.addEventListenter('事件类型',要执行的函数)

三要素:DOM元素(事件源),事件类型,调用函数

 <button>点击</button>

    <script>
        const button = document.querySelector('button')
        button.addEventListener('click', function () {
            alert('你好')
        })
    </script>

随机点名案例机点名案例点名案例

    <script>
        // 数据数组
        const arr = ['马超', '黄忠', '赵云', '关羽', '张飞']
        const qs = document.querySelector('.qs')

        // 开始
        let num = 0
        let random = 0

        const start = document.querySelector('.start')
        start.addEventListener('click', function () {
            num = setInterval(function () {
                random = parseInt(Math.random() * arr.length)
                qs.innerHTML = arr[random]
            }, 35)

            if (arr.length === 1) {
                start.disable = true
                end.disable = true
            }

        })

        //关闭
        const end = document.querySelector('.end')
        end.addEventListener('click', function () {
            clearInterval(num)
            arr.splice(random, 1)
            console.log(arr);
        })

    </script>

鼠标事件

mouseenter

mouseleave

<script>
        const div = document.querySelector('div')
        div.addEventListener('mouseenter', function () {
            console.log('我来了');

        })
        div.addEventListener('mouseleave', function () {
            console.log('我走了');

        })
    </script>

完整版轮播图

自动播放,鼠标移开停止播放

let num = setInterval(function () {
            //自动调用点击!!!!!!
            next.click()
        }, 1000)

        const slider = document.querySelector('.slider')
        slider.addEventListener('mouseenter', function () {
            clearInterval(num)
        })

        slider.addEventListener('mouseleave', function () {
            clearInterval(num)
            //重新开启一个
            num = setInterval(function () {
                //自动调用点击!!!!!!
                next.click()
            }, 1000)
            console.log(num);

        })

num不是同一个,每次开启的都是新的

焦点事件

focus blur

<input type="text">

    <script>
        const input = document.querySelector('input')
        input.addEventListener('focus', function () {
            console.log('有焦点触发');
        })
        input.addEventListener('blur', function () {
            console.log('失去焦点触发');
        })
    </script>

小米搜索框案例

<script>
        const input = document.querySelector('input')
        const ul = document.querySelector('.result-list')

        input.addEventListener('focus', function () {
            ul.style.display = 'block'
            input.classList.add('search')
        })
        input.addEventListener('blur', function () {
            ul.style.display = 'none'
            input.classList.remove('search')
        })
    </script>

键盘事件

const input = document.querySelector('input')
        input.addEventListener('keydown', function () {
            console.log('键盘按下了');

        })
        input.addEventListener('keyup', function () {
            console.log('键盘弹起了了');
        })

按下和弹起是连续发生的

输入文本事件

 input.addEventListener('input', function () {
            console.log('文本输入了');

        })

评论字数案例

transition: all 0.5s; 淡入淡出

div.innerHTML = ${input.value.length}/200字

    <style>
        input {
            width: 200px;
            height: 20px;
        }

        input:focus {
            width: 300px;
        }

        div {
            opacity: 0;
            width: 100px;
            height: 10px;
            transition: all 0.5s;
        }
    </style>

</head>

<body>
    <input type="text" placeholder="发一条友善的评论吧">
    <div>0/200字</div>

    <script>
        const input = document.querySelector('input')
        const div = document.querySelector('div')
        input.addEventListener('input', function () {
            div.innerHTML = `${input.value.length}/200字`
        })
        input.addEventListener('focus', function () {
            div.style.opacity = 1
        })
        input.addEventListener('blur', function () {
            div.style.opacity = 0
        })
    </script>

</body>

事件对象

存事件触发时的相关信息

可以判断用户按下哪个键,点击了哪个元素

比如按下回车键,就可以发布信息

用event,ev,e表示

常用属性

const input = document.querySelector('input')
        input.addEventListener('keyup', function (e) {
            console.log(e.key);
        })
input.addEventListener('keyup', function (e) {
            if (e.key === 'Enter')
                console.log('按下了回车键');
        })

trim方法

去除字符串左右的空格

const str = '         lyt'
console.log(str.trim())

评论回车发布案例

<script>
    const tx = document.querySelector('#tx')
    const item = document.querySelector('.item')
    const text = document.querySelector('.text')
    tx.addEventListener('keyup', function (e) {
      if (e.key === 'Enter') {
        if (tx.value.trim() !== '') {
          item.style.display = 'block'
          text.innerHTML = tx.value
          tx.value = ''
        }
      }
    })
  </script>

环境对象

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

普通和函数里面this指向的是window

谁调用函数,this就指向谁

如果一样的对象有很多个,用this就不会弄混了

const btn = document.querySelector('button')
        btn.addEventListener('click', function () {
            this.style.color = 'red'

        })

回调函数

将函数A作为参数传递给B,函数A就是回调函数

tab切换案例

“先干掉别人,自己登基”

const as = document.querySelectorAll('.tab-nav a')
    for (let i = 0; i < as.length; i++) {
      as[i].addEventListener('mouseenter', function () {
        document.querySelector('.tab-nav .active').classList.remove('active')
        this.classList.add('active')

        document.querySelector('.tab-content .active').classList.remove('active')
        document.querySelector(`.tab-content .item:nth-child(${i + 1})`).classList.add('active')
      })
    }

全选框案例

<script>
    const checkAll = document.querySelector('#checkAll')
    const cks = document.querySelectorAll('.ck')

    checkAll.addEventListener('click', function () {
      for (let i = 0; i < cks.length; i++) {
        cks[i].checked = checkAll.checked;
      }
    })

  </script>
// 小控制大
    for (let i = 0; i < cks.length; i++) {

      cks[i].addEventListener('click', function () {
        checkAll.checked = document.querySelectorAll('.ck:checked').length === cks.length
      })
    }

querySelector () 里面的类是css的类,而不是script的DOM元素

事件流 指事件执行过程的流动路径

捕获阶段,冒泡阶段

实际中使用冒泡多

事件捕获

<div class="father">
        <div class="son"></div>
    </div>
    <script>
        const fa = document.querySelector('.father')
        const so = document.querySelector('.son')

        fa.addEventListener('click', function () {
            alert('我是爸爸')

        }, true)
        so.addEventListener('click', function () {
            alert('我是儿子')
        }, true)
    </script>

只点击儿子的盒子,会有两次提醒,先是父亲的提醒,然后再到儿子的提醒(从大的往下流动,直到找到目标)

事件冒泡

把true去掉

点击儿子的盒子,会有两次提醒,先是儿子的提醒,然后再到父亲的提醒(从小的往上流动,调用所有父级)

阻止冒泡(阻止流动传播)

事件对象.stopPropagation()

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

解绑事件

<script>
        const button = document.querySelector('button')
        function fn() {
            alert('点击了')
        }
        button.addEventListener('click', fn)
        button.removeEventListener('click', fn)
    </script>

函数fn写在外面,remove之后再点击就不会再有显示了

鼠标经过离开的区别

mouseenter,mouseleave没有冒泡

mouseover,mouseout有冒泡

事件委托

代替for循环

把子元素绑定在父元素身上,点击子元素,会冒泡到父元素,从而触发父元素事件

<ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <p>6</p>
    </ul>
    <script>
        const ul = document.querySelector('ul')
        ul.addEventListener('click', function (e) {
            if (e.target.tagName === 'LI') {
                e.target.style.color = 'red'
            }
        })
    </script>

tagName是区分ul中所有不同种类元素的方法,小li会变色,p不会变色

tab栏案例

<script>
    const ul = document.querySelector('.tab-nav ul')
    ul.addEventListener('click', function (e) {
      if (e.target.tagName === 'A') {
        document.querySelector('.tab-nav .active').classList.remove('active')
        e.target.classList.add('active')
        const i = e.target.dataset.id
        document.querySelector('.tab-content .active').classList.remove('active')

        document.querySelector(`.tab-content .item:nth-child(${+i + 1})`).classList.add('active')
      }
    })
  </script>

i是一个字符串,前面要+1变成数字

阻止默认行为

e.preventDefault()

<script>
        const form = document.querySelector('form')
        form.addEventListener('submit', function (e) {
            e.preventDefault()
        })
    </script>

其他事件

页面加载事件

加载外部资源完了,再触发

js写在head中时使用

load事件,监听整个事件,给widow加

DOMContentLoaded

给document加

无需等待样式表、图像完全加载

页面滚动事件

scrollTop 往上滚了多少像素,被卷去的头部

div滚动了多少

<script>
        const div = document.querySelector('div')
        div.addEventListener('scroll', function () {
            console.log(div.scrollTop);
        })
    </script>

window页面滚动,先隐藏div,页面滚动一定长度再出现

<script>
        const div = document.querySelector('div')

        window.addEventListener('scroll', function () {
            const n = document.documentElement.scrollTop
            if (n >= 100) {
                div.style.display = 'block'
            }
            else {
                div.style.display = 'none'
            }
        })
    </script>

scroll是可读写的

document.documentElement.scrollTop = 800

这样一打开就是已经滚了800的位置

电梯栏案例

<script>
    const ele = document.querySelector('.xtx-elevator')
    window.addEventListener('scroll', function () {
      const n = document.documentElement.scrollTop
      if (n >= 300) {
        ele.style.opacity = 1
      }
      else {
        ele.style.opacity = 0
      }
    })
  </script>