一三四——一六七

一三四、JavaScript——_DOM简介

MDNq前端参考文档:DOM 概述 - Web API 接口参考 | MDN (mozilla.org)

一三五、JavaScript——HelloWorld

<!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>
    <button id="btn">点我一下</button>

    <script>
        /*
            要使用DOM来操作网页,我们需要浏览器至少先给我一个对象
                才能去完成各种操作
            所以浏览器已经为我们提供了一个document对象,它是一个全局变量可以直接使用
                document代表的是整个网页
            
        */

        // 打印document 和在控制台中访问document.window效果是一样的
        console.log(document)

        // 获取btn对象,获取id为"btn"的元素
       const btn = document.getElementById("btn")

       //console.log(btn)

       // 修改btn中的文字,通过innerText修改即可
       btn.innerText = "Click ME"

    </script>
    
</body>
</html>
// 打印document 和在控制台中访问document.window效果是一样的
        console.log(document)

    // 获取btn对象,获取id为"btn"的元素
       const btn = document.getElementById("btn")

       //console.log(btn)

 // 修改btn中的文字,通过innerText修改即可
       btn.innerText = "Click ME"

一三六、JavaScript——文件节点

document的整个原型链

 MDN前端参考文档关于Document的部分:https://developer.mozilla.org/zh-CN/docs/Web/API/Document

document对象

                - document对象表示的是整个网页

                - document对象的原型链

                    本身 -> 父类 -> 父类的父类 -> 父类的父类的父类 -> 父类的父类的父类 ->父类的父类的父类的父类

                    HTMLDocument -> Document -> Node -> EnventTarget -> Object.prototype ->null

                - 凡是在原型链上存在的对象的属性和方法都可以通过Document去调用

                - 部分属性:

                    document.documentElement  -- > html根元素

                    document.head  -- > head元素

                    document.title  -- > title元素

                    document.link  -- > 获取页面中所有的超链接

                    ...

 一三七、JavaScript——获取元素节点

 // 获取body标签以及body标签内的内容
        console.log(document.body)

 

<button id="btn">点我一下</button>
    <script>

         // 通过id获取按钮
        const btn = document.getElementById("btn")

        console.log(btn)
    </script>

 

元素节点对象(element)

                - 在网页中,每一个标签都是一个元素节点

                - 如何获取元素节点对象

                    1. 通过document对象来获取元素节点

                    2. 通过document创建元素节点

                - 通过document获取已有的元素节点对象

                    document.getElementById()

                        - 根据id获取一个元素节点对象(只能获取一个,因为id是不能重复的)

                    document.getElementsByClassName()

                        - 根据元素的class属性获取一组元素节点对象

                    document.getElementsByClassName()

                        - 根据元素的class属性值获取一组元素节点对象

                        - 返回的是一个类数组对象

                        - 该方法返回的结果是一个实时更新的集合

                            当网页中新添加元素时,集合也会实时的刷新

                    document.getElementsByTagName()

                        - 根据标签名获取元素节点对象

                        - 返回的结果是实时更新的集合

                        - document.getElementsByTagName("*"): 获取页面中的所有元素

                    document.querySelectorAll()

                        - 根据选择器去页面中查询元素

                        - 会返回一个数组(不会实时更新)

                    document.querySelector()

                        - 根据选择器去页面中查询第一个符合条件的元素

<body>

    <button id="btn">点我一下</button>

    <span class="s1">我是pan</span>
    <span class="s1">我是span</span>
    <span class="s1">我是span</span>
    <span class="s1">我是span</span>
    <span class="s1">我是span</span>


    <div>我是div</div>
    <div>我是div</div>
    <div>我是div</div>
    <div>我是div</div>
    <div>我是div</div>

    <form>
        <input type="text" name="username">
        <input type="radio" name="gender" value="男">
        <input type="radio" name="gender" value="女">
    </form>

    <script>

        /*
            元素节点对象(element)
                - 在网页中,每一个标签都是一个元素节点
                - 如何获取元素节点对象
                    1. 通过document对象来获取元素节点
                    2. 通过document创建元素节点
                - 通过document获取已有的元素节点对象
                    document.getElementById()
                        - 根据id获取一个元素节点对象(只能获取一个,因为id是不能重复的)
                    document.getElementsByClassName()
                        - 根据元素的class属性获取一组元素节点对象
                    document.getElementsByClassName()
                        - 根据元素的class属性值获取一组元素节点对象
                        - 返回的是一个类数组对象
                        - 该方法返回的结果是一个实时更新的集合
                            当网页中新添加元素时,集合也会实时的刷新
                    document.getElementsByTagName()
                        - 根据标签名获取元素节点对象
                        - 返回的结果是实时更新的集合
                        - document.getElementsByTagName("*"): 获取页面中的所有元素
                    document.querySelectorAll()
                        - 根据选择器去页面中查询元素
                        - 会返回一个数组(不会实时更新)
                    document.querySelector()
                        - 根据选择器去页面中查询第一个符合条件的元素
                    
        */

        // 获取body标签以及body标签内的内容
        console.log(document.body)

        // 通过id获取按钮
        const btn = document.getElementById("btn")

        console.log(btn)


        // 通过Class的id的name获取span的内容
        const spans = document.getElementsByClassName("s1")

        // 遍历span标签的内容
        for(let i=0; i<spans.length; i++){
            //将内容都改为“哈哈哈”
            spans[i].innerText = "哈哈哈"+ i
        }

        console.log(spans)


        // 根据标签名div获取元素节点对象
        const divs = document.getElementsByTagName("div")


        // 获取页面中的所有元素
        const tagName = document.getElementsByTagName("*")

        console.log(tagName)


        // 针对form表单中的input
        const genderInput = document.getElementsByName("gender")

        console.log(genderInput)

        // 获取所有标签元素为div的
        const divs2 = document.querySelectorAll("div")

        // 打印的是一个集合 NodeList(5) [div, div, div, div, div]
        console.log(divs2)

        // 获取标签元素为div的,取单个的,一般情况就取第一个
        const divs3 = document.querySelector("div")

        // 在控制台直接打印div,点击显示的是第一个div标签
    </script>
    
</body>

 一三八、JavaScript——元素的属性和方法

通过元素节点对象获取其他的节点的方法

                element.childNodes 获取当前元素的子节点(会包含空白的节点)

                    子节点包括:文本节点、标签节点等,

                    标签节点后还有空白节点,所以算两个节点,而文本节点后的空白节点是被文本节点一起包含的

                element.children 获取当前元素的子元素

                element.firstElementChild 获取当前元素第一个子元素

                element.lastElementChild 获取当前元素第一个子元素

                element.nextElementSibling 获取当前元素的下一个兄弟元素

                element.previousElementSibling 获取当前元素的前一个兄弟元素

                element.parentNode 获取当前元素的父节点

                element.tagName 获取当前元素的标签名

<body>

    <div id="box1">
        我是box1
        <span class="s1">我是s1</span>
        <span class="s1">我是s1</span>
    </div>
    <span class="s1">我是s1</span>
    <script>
        /*
            div元素的原型链
                HTMLDivElement -> HTMLElement -> Elemnet -> Node -> ---
            
            通过元素节点对象获取其他的节点的方法
                element.childNodes 获取当前元素的子节点(会包含空白的节点)
                    子节点包括:文本节点、标签节点等,
                    标签节点后还有空白节点,所以算两个节点,而文本节点后的空白节点是被文本节点一起包含的
                element.children 获取当前元素的子元素
                element.firstElementChild 获取当前元素第一个子元素
                element.lastElementChild 获取当前元素第一个子元素
                element.nextElementSibling 获取当前元素的下一个兄弟元素
                element.previousElementSibling 获取当前元素的前一个兄弟元素
                element.parentNode 获取当前元素的父节点
                element.tagName 获取当前元素的标签名
        */

        // 获取id为box1的标签。通过documnet去调,则是通过整个网页范围内查找
        const box1 = document.getElementById("box1")

        //
        console.log(box1)

        // 通过box1去调,调用的范围只在box1的标签名内查找
        const spans = box1.getElementsByTagName("span")

        // 打印结果为2,name为box1的标签内的span标签数量为2
        console.log(spans)

       
        // 标签节点后还有空白节点,所以算两个节点,而文本节点后的空白节点是被文本节点一起包含的。算一个
        const cns = box1.childNodes
        
        // 结果为5,说明节点数为5
        // 文本节点一个   标签节点两个  标签节点后的空白节点两个 共5个
        console.log(cns)


    </script>
    
</body>

 一三九、JavaScript——文本节点

<body>

  
    <img src="" alt="">


    <!-- "我是div"在这里就是一个文本节点 -->
    <div id="box1">
        <span>我是box1</span>
    </div>
    <script>

        /*
            在DOM中,网页中的所有文本内容都是文本对象
                可以通过元素来获取其中的文本节点对象,但是我们通常不会这么做

                我们可以直接通过元素去修改其中的文本
                    修改文本的三个属性
                        element.textContent 获取或修改元素中的文本内容
                            - 获取的是标签中的内容,不会考虑css样式
                            - 不考虑样式就是本来的文本是大写,但通过textContent拿到的就是小写

                        element.innerText 获取或修改元素中的文本内容
                            - innerText获取内容时,会考虑css样式
                            - 考虑样式就是本来的文本是大写,但通过innerText拿到的就是大写,保留原有样式

                            - 当字符串中有标签时,会自动对标签进行转义,并不是真正的字符
                        element.innerHTML 获取或修改HTML中的代码
                            - 可以直接向元素中添加HTML代码
                            - innerHTML插入内容时,有被xss注入的风险
        */

        // 先通过id获取到标签的内容
        const box1 = document.getElementById("box1")

        // 通过element.textContent修改文本内容
      //  box1.textContent = "新的内容"
    </script>
    
</body>

 一四零、JavaScript——属性节点

  属性节点(Attr)

                - 在DOM中也是一个对象,通常不需要获取对象而是直接通过元素即可完成对其的各种操作

                - 如何操作属性节点:

                    方式一:

                        读取:元素.属性名(注意:class属性需要用className来读取)

                            读取一个布尔值时,会返回true或false

                        修改: 元素.属性名 = 属性值

                       

                    方式二:

                        读取:元素.getAttribute(属性名)

                        修改:元素.setAttribute(属性名,属性值)

                        删除:元素.removeAttribute(属性名)

<body>
    <input type="text" name="username" value="admin">
    

    <script>
        /*
            属性节点(Attr)
                - 在DOM中也是一个对象,通常不需要获取对象而是直接通过元素即可完成对其的各种操作
                - 如何操作属性节点:
                    方式一: 
                        读取:元素.属性名(注意:class属性需要用className来读取)
                            读取一个布尔值时,会返回true或false
                        修改: 元素.属性名 = 属性值
                        
                    方式二:
                        读取:元素.getAttribute(属性名) 

                        修改:元素.setAttribute(属性名,属性值)

                        删除:元素.removeAttribute(属性名)



        */

        // getElementsByName 因为获取的是Elements,要想获取一个需要加一个索引[0]
       const input = document.getElementsByName("username")[0]

       // 打印内容为:<input type="text" name="username" value="admin">
       console.log(input)

       
       const input1 = document.querySelector("[name=username]")

       console.log(input)


       // 修改:元素.setAttribute(属性名,属性值)
       input.setAttribute("value","孙悟空")
     
    </script>

    
</body>

 一四一、JavaScript——事件

事件(event)

                - 事件就是用户和页面之间发生的交互行为

                    比如:点击按钮、鼠标移动、双击按钮、敲击键盘、松开键盘...

                - 可以通过为事件绑定响应函数(回调函数),来完成用户之间的交互

                - 绑定响应函数的方式

                    1. 可以直接在元素的属性中设置

                    2. 可以通过为元素的指定属性设置回调函数的形式来绑定事件

                    3. 可以通过元素addEventListener()方法来绑定事件

<body>
    <!-- ondblclick指双击按钮跳出弹框 -->
    <!-- <button id="btn" ondblclick="alert('你点我干嘛')">点我一下</button> -->

    <button id="btn">点我一下</button>

    <script>
        /*
            事件(event)
                - 事件就是用户和页面之间发生的交互行为
                    比如:点击按钮、鼠标移动、双击按钮、敲击键盘、松开键盘...
                - 可以通过为事件绑定响应函数(回调函数),来完成用户之间的交互
                - 绑定响应函数的方式
                    1. 可以直接在元素的属性中设置
                    2. 可以通过为元素的指定属性设置回调函数的形式来绑定事件
                    3. 可以通过元素addEventListener()方法来绑定事件
        */

        // 1.获取到按钮对象
        const btn = document.getElementById("btn")

        // 2.为按钮对象的事件属性设置响应函数,即点击了就会响应
        btn.onclick = function(){
            alert("点击按钮后调用的函数")
        }

        // 设置了新的绑定之后,新的绑定会将旧的绑定覆盖
        btn.onclick = function(){
            alert("设置新的绑定")
        }

        // 3. 通过元素addEventListener()方法来绑定事件
        btn.assEventListener("click", function(){
            alert("哈哈哈")
        })

        // 不会被覆盖,按顺序依次出现
        btn.assEventListener("click", function(){
            alert("嘻嘻嘻")
        })
    </script>
</body>

一四二、JavaScript——文档的加载

  • 网页是自上而下加载的,如果将js代码编写到网页的上边(button按钮的上面
  • js代码在执行时候,网页还没有加载完毕,这时候会出现无法获取到DOM对象的情况

                window.onload 事件会在窗口中的内容加载完毕之后才触发

                    - 会等待所有文档都加载完成才会触发

                document对象的DOMContentLoaded事件会在窗口中的内容加载完成之后才会触发

                    - 当前文档加载完成就触发

                如何解决这个问题

                    1. 将script标签写到body标签的最后的位置

                    2. 将代码编写到window.onload的回调函数中,因为window.onload的回调函数是最后执行的,所以此时script可以放在任意位置,只要放在里面就可以最后执行

                    3. 将代码编写到document对象的DOMContentLoaded的回调函数中(执行的时机早)

                    4. 将代码编写到外部的js文件中,然后以defer的形式引入(执行的时机更早,早于DOMContentLoaded)

                开发过程中常用1,引外部文件时常用4

<body>

    <button id="btn">点我一下</button>
    <script>

        /*
            网页是自上而下加载的,如果将js代码编写到网页的上边(button按钮的上面)
                js代码在执行时候,网页还没有加载完毕,这时候会出现无法获取到DOM对象的情况


                window.onload 事件会在窗口中的内容加载完毕之后才触发
                    - 会等待所有文档都加载完成才会触发
                document对象的DOMContentLoaded事件会在窗口中的内容加载完成之后才会触发
                    - 当前文档加载完成就触发

                如何解决这个问题:
                    1. 将script标签写到body标签的最后的位置
                    2. 将代码编写到window.onload的回调函数中,因为window.onload的回调函数是最后执行的,所以此时script可以放在任意位置,只要放在里面就可以最后执行
                    3. 将代码编写到document对象的DOMContentLoaded的回调函数中(执行的时机早)
                    4. 将代码编写到外部的js文件中,然后以defer的形式引入(执行的时机更早,早于DOMContentLoaded)

                开发过程中常用1,引外部文件时常用4

        */


        // 可以放在任意位置,因为window.onload的回调函数总在最后执行
        // window.onload() = function(){
        //     const btn = document.getElementById("btn")
        //     console.log(btn)
        // }

        // document对象的DOMContentLoaded的回调函数,只能通过 document.addEventListener调用
        document.addEventListener("load", function (){

            const btn = document.getElementById("btn")
            console.log(btn)
        })

        const btn = document.getElementById("btn")
        console.log(btn)

    </script>


<!-- 代码编写到外部的js文件中,然后以defer的形式引入 -->
    <!-- <script defer src="链接"></script> -->

一四六、JavaScript——元素的修改

  • appendChild() 用于给节点添加一个子节点

  • insertAdjacentElement(添加的位置,要添加的元素) 可以向元素任意位置添加元素i

  • 添加的位置:

                        beforeend:标签的最后

                        afterbegin:标签的开始

                        beforebeing:与标签处于同级,在标签的前边插入元素(兄弟元素)

                        afterend:与标签处于同级,在标签的后边插入元素(兄弟元素)

  • insertAdjacentHTML("插入的位置", "插入的标签")

  • replaceWith("参与替换掉的元素")

  • remove() 方法来删除元素

<body>

    <button id="btn01">按钮01</button>
    <button id="btn02">按钮02</button>

    <hr>
    
    <ul id="list">
        <li id="swk">孙悟空</li>
        <li id="zbj">猪八戒</li>
        <li id="shs">沙和尚</li>

    </ul>

    <script>

        /*
            点击按钮后,向ul中添加一个唐僧
        */

        // 获取ul
        const list = document.getElementById("list")
      

        // 获取按钮
        const btn01 = document.getElementById("btn01")
        const btn02 = document.getElementById("btn02")

        btn01.onclick = function() {

            // 创建一个li
            const li = document.createElement("li")
            // 向li中添加文本
            li.textContent = "唐僧"
            // 给li添加id属性
            li.id = "ts"

            // // appendChild() 用于给节点添加一个子节点
            // list.appendChild(li)
            // console.log(list)

            // insertAdjacentElement(添加的位置,要添加的元素)可以向元素任意位置添加元素i
            // 两个参数:1.添加的位置 2.要添加的元素
            /*
                添加的位置:
                    beforeend:标签的最后
                    afterbegin:标签的开始
                    beforebeing:与标签处于同级,在标签的前边插入元素(兄弟元素)
                    afterend:与标签处于同级,在标签的后边插入元素(兄弟元素)
            */
            list.insertAdjacentElement("afterbegin",li)

            // insertAdjacentHTML("插入的位置", "插入的标签")
            list.insertAdjacentHTML("", "<li id='bgj'>白骨精</li>")

        }

        btn02.onclick = function() {

            // 创建一个蜘蛛精替换孙悟空
            const li = document.createElement("li")
            li.textContent = "蜘蛛精"
            li.id = "zzj"

            // 获取孙悟空
            const swk = document.getElementById("swk")

            // replaceWith() 使用一个元素替换当前元素
            // replaceWith("参与替换掉的元素")
            swk.replaceWith(li)

            // remove() 方法来删除元素
            swk.remove()
        }
    </script>
</body>

一五零、JavaScript——节点的复制

 涉及的方法

                添加list.appendChild(l1)

                    将l1添加到list中

                复制const newL1 = li.cloneNode(true)

                    复制l1和l1下的子节点,l1标签里的文本节点就属于l1的子节点

<body>

    <button id="btn01">点我一下</button>

    <ul id="list1">
        <li id="l1">孙悟空</li>
        <li id="l2">猪八戒</li>
        <li id="l3">孙悟空</li>

    </ul>

    <ul id="list2">
        <li >蜘蛛精</li>
    </ul>

    <script>

        /*

            涉及的方法
                添加:list.appendChild(l1)
                    将l1添加到list中
                复制:const newL1 = li.cloneNode(true)
                    复制l1和l1下的子节点,l1标签里的文本节点就属于l1的子节点
        */

        /*
            点击按钮后,将id为l1的元素添加到list2中

        */

        // 先获取按钮
       const btn01 = document.getElementById("btn01")
       const list2 = document.getElementById("list2")
       const l1 = document.getElementById("l1")
       // 点击按钮触发的函数
       btn01.onclick = function() {

            /*
                使用 cloneNode()方法对节点进行复制时,它会复制节点的所有特点包括各种属性
                    这个方法只会默认复制当前节点,即只复制标签节点,不会复制文本节点,
                    可以传递一个true作为参数,这样该方法也会将元素的子节点一起复制

            */
           const newL1 = li.cloneNode(true)  // 用来对节点进行复制


           // 防止id完全重复,重新赋值一个id即可
           newL1.id = "newL1"

            // 利用appendChild,点击按钮后,将l1添加到list2中去
            list2.appendChild(l1)
       }

    </script>
    
</body>

 一五一、JavaScript——修改css样式

  •  在stylE标签中,

     在样式的结尾在结尾加 !important

     表示优先级最高,最先执行

      background-color: #4ead56 !important;

  • 修改样式的方式: 元素.style.样式名 = 样式值

  •  如果样式名中含有"-",例如"background-color"则需要将样式表修改为驼峰命名法"backgroundColor"

  • "background-color" -> "backgroundColor"

<style>
        .box1 {
            width: 200px;
            height: 200px;
            background-color: #4ead56 !important;

            /* 
                在stylE标签中,
                在样式的结尾在结尾加 !important
                表示优先级最高,最先执行
                background-color: #4ead56 !important;
             */

        }
    </style>


</head>
<body>
    <button id="btn">点我一下</button>

    <hr />

    <div class="box1"></div>


    <script>
        /*
            点击按钮后,修改box1的宽度

        */
       const btn = document.getElementById("btn")
       // querySelector方法:选中页面中出现的第一个标签
       const box1 = document.querySelector(".box1")

       // 点击按钮触发的函数
       btn.onclick = function() {
        // 修改.box1的样式
        // 修改样式的方式: 元素.style.样式名 = 样式值
        box1.style.width = "600px"
        box1.style.height = "600px"

        // 如果样式名中含有"-",例如"background-color"则需要将样式表修改为驼峰命名法"backgroundColor"
        // "background-color" -> "backgroundColor"
         box1.style.backgroundColor = "yellow";  
       }

    </script>
</body>

一五二、JavaScript——读取样式

                getComputedStyle()

                    -它会返回一个对象,这个对象中包含了当前元素的所有生效的样式

                    - 获取具体的样式数值:对象.width  获取样式的宽度

                    - 伪元素获取样式信息:getComputedStyle(要获取的样式对象, "要获取的为元素")

               

                宽度以及高度的计算:

                    - 一般通过: "对象.width" 读取样式宽度时,都是带宽度的

                    - 通过 parseInt(对象.width)将 200px 中的px消除

                    - 再通过 + "px" 的方式加上单位

                返回值

                    - 返回的一个对象,对象中存储了当前元素的样式

               

                注意

                    - 样式对象中返回的样式值,不一定能拿来直接计算,有可能是auto

                        所以使用时,一定要确保值偶是可以计算的才去计算


    <style>
        .box1 {
            width: 200px;
            height: 200px;
            background-color: #4ead56 !important;

            /* 
                在stylE标签中,
                在样式的结尾在结尾加 !important
                表示优先级最高,最先执行
                background-color: #4ead56 !important;
             */
        }

        /* 
            伪元素
         */
         .box1::before {
            content: "hello";
            color:red;
         }
    </style>


</head>
<body>
    <button id="btn">点我一下</button>

    <hr />

    <div class="box1"></div>


    <script>
        /*
            点击按钮后,读取css的样式

        */
       const btn = document.getElementById("btn")
       // querySelector方法:选中页面中出现的第一个标签
       const box1 = document.querySelector(".box1")

       // 点击按钮触发的函数
       btn.onclick = function() {

            // 不会用这种方式来读取样式
            // console.log(box1.style.width)

            /*
                getComputedStyle()
                    -它会返回一个对象,这个对象中包含了当前元素的所有生效的样式
                    - 获取具体的样式数值:对象.width  获取样式的宽度
                    - 伪元素获取样式信息:getComputedStyle(要获取的样式对象, "要获取的为元素")
                
                宽度以及高度的计算:
                    - 一般通过: "对象.width" 读取样式宽度时,都是带宽度的
                    - 通过 parseInt(对象.width)将 200px 中的px消除
                    - 再通过 + "px" 的方式加上单位

                返回值
                    - 返回的一个对象,对象中存储了当前元素的样式
                
                注意
                    - 样式对象中返回的样式值,不一定能拿来直接计算,有可能是auto
                        所以使用时,一定要确保值偶是可以计算的才去计算
            */
           const styleObj = getComputedStyle(box1)

           // 获取为元素的样式信息
           const beforeObj = getComputedStyle(box1, "before")

           // 通过 parseInt(对象.width)将 200px 中的px消除 
           // 再通过 + "px" 的方式加上单位
           parseInt(styleObj.width) + 100 + "px"

           // 获取元素的样式
           console.log(styleObj.width)
       }

    </script>
</body>

一五三、JavaScript——通过属性读取样式

                元素.clientHeight

                元素.clientWidth

                    - 获取元素内部的宽度和高度(包括内容区和内边距,width和padding)

                    - 返回的结果就是纯数字,不带单位

                元素.offsetHeight

                元素.offsetWidth

                    - 获取元素的可见框的大小(包括内容区、内边距和边框)

                    - 返回的结果就是纯数字,不带单位

               

                元素.scrollHeight

                元素.scrollWidth

                    - 获取元素滚动区域的大小

                元素.offsetParent

                    - 获取元素定位的父元素

                    - 定位父元素,离当前元素最近的开启了定位的祖先元素

                        如果所有的元素都没有开启定位则返回body


 

                元素.offsetTop

                元素.offsetLeft

                    - 获取元素相对于起定位父元素的偏移量

   <style>
        #box1 {
            width: 200px;
            height: 200px;
            padding: 50px;
            margin: 50px;
            border: 10px red solid;
            background-color:aqua;
            /* 设置多余的部分溢出, */
            overflow: auto;
        }

        #box2 {
            width: 100px;
            height: 500px;
            background-color:chartreuse;
        }
    </style>
    
</head>
<body>
    <button id="btn">点我一下</button>
    <hr>
    <div id="box1">
        <div id="box2"></div>
    </div>
    <script>

        const btn = document.getElementById("btn")
        const box1 = document.getElementById("box1")

        btn.onclick = function() {
            /*
                元素.clientHeight
                元素.clientWidth
                    - 获取元素内部的宽度和高度(包括内容区和内边距,width和padding)
                    - 返回的结果就是纯数字,不带单位

                元素.offsetHeight
                元素.offsetWidth
                    - 获取元素的可见框的大小(包括内容区、内边距和边框)
                    - 返回的结果就是纯数字,不带单位
                
                元素.scrollHeight
                元素.scrollWidth
                    - 获取元素滚动区域的大小

                元素.offsetParent
                    - 获取元素定位的父元素
                    - 定位父元素,离当前元素最近的开启了定位的祖先元素
                        如果所有的元素都没有开启定位则返回body


                元素.offsetTop
                元素.offsetLeft
                    - 获取元素相对于起定位父元素的偏移量

            */
        }

        console.log(box1.clientWidth)

    </script>
</body>

 

一五四、JavaScript——操作class

  • 元素.classList.add(class名称,class名称) :向元素中添加一个或多个class

                元素.classList.remove(class名称) :删除一个或多个class

                元素.classList.toggle(class名称) :切换class

                元素.classList.replace(class1, class2) :1去掉class1,替换成class2

                box1.classList.contains("box1"): 判断是否含有某个class

<body>

    <button id="btn">点我一下</button>

    <hr />

    <div  class="box1"></div>


    <script>

        const btn = document.getElementById("btn")

        // querySelector取网页中第一次出现的标签
        const box1 = document.querySelector(".box1")

        btn.onclick = function() {
            /*
                除了直接修改样式外,也可以通过修改class属性来简介修改样式

                被替换的.className += " 具体替换的"  
                注意具体替换的前有空格
                box1.className += " box2"
            */

            // box1.className += " box2"

            /*
                元素.classList.add(class名称,class名称) :向元素中添加一个或多个class
                元素.classList.remove(class名称) :删除一个或多个class
                元素.classList.toggle(class名称) :切换class
                元素.classList.replace(class1, class2) :1去掉class1,替换成class2
                box1.classList.contains("box1"): 判断是否含有某个class

            */

            // 元素.classList 是一个对象,对象中提供了对当前元素的类的各种操作方法
            box1.classList.add(box2)

            box1.classList.remove(box2)

            box1.classList.toggle("box2")

            // 把1去掉替换成2
            box1.classList.replace("box1","box2")

            // 检查是否包含
            box1.classList.contains("box1")

        }

    </script>
</body>

  

一五五、JavaScript——事件对象简介

 event 事件

                - 事件对象

                - 事件对象是由浏览器在事件触发时所创建的对象

                    这个对象中封装了事件相关的各种信息

                - 通过事件对象可以获取到事件的详细信息

                    比如:鼠标的坐标,键盘的按键

                - 浏览器在创建事件对象后,会将事件作为响应函数的参数传递

                    所以我们可以在事件的回调函数中定义一个形参来接收事件对象

   <style>
        #box1 {
            width: 300px;
            height: 300px;
            border: 10px greenyellow solid;
        }

    </style>
</head>
<body>

    <div id="box1"></div>
    
    <script>

        /*
            event 事件
                - 事件对象
                - 事件对象是由浏览器在事件触发时所创建的对象
                    这个对象中封装了事件相关的各种信息
                - 通过事件对象可以获取到事件的详细信息
                    比如:鼠标的坐标,键盘的按键
                - 浏览器在创建事件对象后,会将事件作为响应函数的参数传递
                    所以我们可以在事件的回调函数中定义一个形参来接收事件对象
        */

       // onmousemove鼠标移动事件
    //    box1.onmousemove = function() {
    //     console.log("鼠标移动了")
    //    }

    // 方式1:回调函数传入参数用来记录
    //    box1.onmousemove = function(event) {
    //     console.log(event)
    //    }

    // 方式2:匿名函数传入形参命名为event
    // box1.onmousemove = event => {
    //     console.log(event)
    // }
    
    const box1 = document.getElementById("box1")
    // addEventListener("事件", 函数)
    box1.addEventListener("mousemove", event => {
        // console.log(event)
        
        // 打印鼠标的坐标
        console.log(event.clientX, event.clientY)

        // 让鼠标坐标显示在网页中
        box1.textContent = event.clientX + "," +event.clientY

    })
    </script>
</body>

 

 一五六、JavaScript——event对象

MDN前端参考文档Event - Web APIs | MDN (mozilla.org)

在DOM中存在着多种不同类型的事件对象

                - 多种事件对象有一个共同的祖先 Event

                    - event.target 触发事件的对象

                    - event,currentTarget 绑定事件的对象(问this)

                    - event.stopPropaggation() 停止事件的向上传导

                    - event.preventDefault() 取消默认行为

                - 事件的冒泡(bubble)

                    - 事件的冒泡就是指事件的向上传导

                    - 当元素的某个事件被触发后,其祖先元素上的相同元素也会被触发

                    - 冒泡的存在大大简化了代码的编写,但在一些场景下我们并不希望冒泡存在

 <style>
        #box1 {
            width: 300px;
            height: 300px;
            background-color: antiquewhite;
        }

    </style>
</head>
<body>
    <div id="box1"></div>
    
    <script>
        /*
            在DOM中存在着多种不同类型的事件对象
                - 多种事件对象有一个共同的祖先 Event
                    - event.target 触发事件的对象
                    - event,currentTarget 绑定事件的对象(问this)
                    - event.stopPropaggation() 停止事件的向上传导
                    - event.preventDefault() 取消默认行为
                - 事件的冒泡(bubble)
                    - 事件的冒泡就是指事件的向上传导
                    - 当元素的某个事件被触发后,其祖先元素上的相同元素也会被触发
                    - 冒泡的存在大大简化了代码的编写,但在一些场景下我们并不希望冒泡存在
        */
        // 获取box1
        const box1 = document.getElementById("box1")
        // addEventListener("事件", "函数")
        box1.addEventListener("click", event => {
            // alert(event)
          
            // console.log(event)

            /*
                在事件的响应函数中:
                    event.target 表示的是触发事件的对象,由谁引发的事件就显示谁

            */
           // 打印 <div id="box1"></div>;因为是由于box1触发的
           console.log(event.target)
        })

    </script>
</body>

 一五七、JavaScript——事件的冒泡


    <style>
        #box1{
            width: 100px;
            height: 100px;
            background-color: cornflowerblue;
            border-radius: 50%;
            position: absolute;
        }

        #box2{
            width: 500px;
            height: 500px;
            background-color: coral;
        }
        #box3{
            width: 200px;
            height: 200px;
            background-color: aqua;
        }
        #box4{
            width: 100px;
            height: 100px;
            background-color: brown;
        }

    </style>
</head>
<body>
    <div id="box1"></div>
    <!-- 创建一个box2 -->
    <div id="box2"></div>

    <div id="box3" onclick="alert(3)">
        <div id="box4" onclick="alert(4)"></div>
    </div>

    <script>
        /*
            使小绿球可以跟鼠标一起移动

            事件的冒泡和元素的样式无关,只和结构有关

        */

        const box1 = document.getElementById("box1")
        const box2 = document.getElementById("box2")

        // 绑定鼠标移动事件,并传入形参event
        // 并且绑定在整个界面上,而不是box1上
        document.addEventListener("mousemove", (event) => {
            // console.log(111)

            // 图标跟随鼠标移动
            box1.style.left = event.x + "px"
            box1.style.top = event.y + "px"

        })

        // 取消box2的事件的冒泡
        box2.addEventListener("mousemove", (event) => {
            
            // 取消事件的冒泡,这样再box2的区域小球就不会随着鼠标移动
            event.stopPropagation()
        })


    </script>
    
</body>

一五八、JavaScript——事件的委派

<body>
    <button id="btn">点我一下</button>

    <hr>

    <ul id="list">
        <li><a href="javascript:;">链接1</a></li>
        <li><a href="javascript:;">链接2</a></li>
        <li><a href="javascript:;">链接3</a></li>
        <li><a href="javascript:;">链接4</a></li>
    </ul>
 
    <script>

        // 获取所有为ul标签中的a标签
        const links = document.querySelectorAll("ul a")
        // 获取list标签
        const list = document.getElementById("list")
        const btn = document.getElementById("btn")

        for(let i=0; i<links.length; i++) {
            links[i].addEventListener("click", event => {
 
                alert(event.target.textContent)
            })
        }

        // 点击按钮后,在ul中新增一个li
        btn.addEventListener("click", () => {
            // 通过insertAdjacentHTML("插入的位置", "插入的内容") 直接插入标签
            list.insertAdjacentHTML("beforeend", "<li><a href='javascript:;'>新超链接</a></li>")
        })

        /*
            上面虽然实现了点击按钮新增链接的功能,但还经历了遍历和点击添加的,

            我一个希望
                只绑定一次事件,即可以让所有的超链接,包括当下和未来的超链接都具有这些事情
            
            思路:
            可以将事件统一绑定给document,这样点击超链接时由于事件的冒泡
                会导致document上的点击事件被触发,这样只绑定依次,所有的超链接都会具有这些事件

            委派就是将本该绑定多个元素的的事件,统一绑定给一个共同事件
        */

        // 获取list中的所有链接
        const linkes = list.getElementsByTagName("a")


        // 将点击事件扩大到整个网页,即对象是document
        document.addEventListener("click", (event) => {
            // 在执行代码前,判断一下事件是由谁来触发
            // 检查event.target 是否在 links 中存在
            // 但link打印出来是 "HTMLCollection [a,a,a,a]" 我们需要的是数组
            // 调用静态方法 Arrary.form(linkes) 后,数组变为[a,a,a,a]
            // 或者直接用展开运算符展开[...linkes] 效果是一样的

            // 判断如果触发事件在linkes中出现了
            if([...links].includes(event.target)) {
                  // 点击事件触发后显示触发的文本 
                  alert(event.target.textContent)
            }
        }) 

    </script>
    
</body>

一六零、JavaScript——事件的捕获

        事件的传播机制:

                - 在DOM中,事件的传播可以分为三个阶段:

                    1.捕获阶段 (由祖先元素向目标元素进行事件的捕获)(默认情况下,事件不会在捕获阶段触发)

                    2.目标阶段 (触发事件的对象)

                    3.冒泡阶段 (由目标元素向祖先元素的进行事件的冒泡)

                - 事件的捕获,指事件从外向内的传导

                    捕获是从外向里捕获

                    冒泡是由里向外捕获

                    当我们当前元素的触发事件以后,会先从当前元素的最大祖先元素开始事件的捕获

                - 如果希望在捕获阶段触发事件,可以将addEventListener的第三个参数设置为true

                    一般情况下我们不希望事件在捕获阶段触发,所以通常不需要设置addEventListener第三个参数为true

                    eventPhase 表示事件触发的阶段,结果是数字

                        1 表示捕获阶段 2 表示目标阶段 3 表示冒泡阶段

   <style>
        #box1 {
            width: 300px;
            height: 300px;
            background-color: aquamarine;
        }
        #box2 {
            width: 200px;
            height: 200px;
            background-color:crimson
        }
        #box3 {
            width: 100px;
            height: 100px;
            background-color:darkblue;
        }
    </style>
</head>
<body>

    <div id="box1">
        <div id="box2">
            <div id="box3">
            </div>
        </div>
    </div>

    <script>
        /*
            事件的传播机制:
                - 在DOM中,事件的传播可以分为三个阶段:
                    1.捕获阶段 (由祖先元素向目标元素进行事件的捕获)(默认情况下,事件不会在捕获阶段触发)
                    2.目标阶段 (触发事件的对象)
                    3.冒泡阶段 (由目标元素向祖先元素的进行事件的冒泡)

                - 事件的捕获,指事件从外向内的传导
                    捕获是从外向里捕获
                    冒泡是由里向外捕获
                    当我们当前元素的触发事件以后,会先从当前元素的最大祖先元素开始事件的捕获

                - 如果希望在捕获阶段触发事件,可以将addEventListener的第三个参数设置为true
                    一般情况下我们不希望事件在捕获阶段触发,所以通常不需要设置addEventListener第三个参数为true
                    eventPhase 表示事件触发的阶段,结果是数字
                        1 表示捕获阶段 2 表示目标阶段 3 表示冒泡阶段
        */
        const box1 = document.getElementById("box1")
        const box2 = document.getElementById("box2")
        const box3 = document.getElementById("box3")

        box1.addEventListener("click", event => {
            alert(event.eventPhase)  //eventPhase 表示事件触发的阶段
        },true)

        
        box2.addEventListener("click", event => {
            alert(2)
        })

        
        box3.addEventListener("click", event => {
            alert(3)
        })
    </script>
    
</body>

 一六一、JavaScript——BOM简介

 BOM

                - 浏览器对象模型

                - BOM为我们提供了一组对象,通过这组对象可以完成对浏览器的各种操作

                - BOM对象

                    - Window —— 代表浏览器窗口(全局对象)

                    - Navigator —— 浏览器的对象(可以用来识别浏览器)

                    - Location —— 浏览器的地址栏信息

                    - History —— 浏览器的历史记录(控制浏览器前进后退)

                    - Screen —— 屏幕的信息

                - BOM对象是作为window对象的属性保存的,所以可以直接在JS中访问这些对象

一六二、JavaScript——Navigator 

      - BOM对象
                    - MDN前端参考文档:https://developer.mozilla.org/en-US/docs/Web/API/Navigator
                    - Navigator —— 浏览器的对象(可以用来识别浏览器)
                        userAgent 返回一个用来描述浏览器信息的字符串

<body>
    <script>
        /*
                - BOM对象
                    - MDN前端参考文档:https://developer.mozilla.org/en-US/docs/Web/API/Navigator
                    - Navigator —— 浏览器的对象(可以用来识别浏览器)
                        userAgent 返回一个用来描述浏览器信息的字符串
                    
        */
       // console.log(navigator.userAgent)


       function getBrowserName(userAgent) {
  // The order matters here, and this may report false positives for unlisted browsers.

  if (userAgent.includes("Firefox")) {
    // "Mozilla/5.0 (X11; Linux i686; rv:104.0) Gecko/20100101 Firefox/104.0"
    return "Mozilla Firefox";
  } else if (userAgent.includes("SamsungBrowser")) {
    // "Mozilla/5.0 (Linux; Android 9; SAMSUNG SM-G955F Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/9.4 Chrome/67.0.3396.87 Mobile Safari/537.36"
    return "Samsung Internet";
  } else if (userAgent.includes("Opera") || userAgent.includes("OPR")) {
    // "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_5_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 OPR/90.0.4480.54"
    return "Opera";
  } else if (userAgent.includes("Edge")) {
    // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299"
    return "Microsoft Edge (Legacy)";
  } else if (userAgent.includes("Edg")) {
    // "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36 Edg/104.0.1293.70"
    return "Microsoft Edge (Chromium)";
  } else if (userAgent.includes("Chrome")) {
    // "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36"
    return "Google Chrome or Chromium";
  } else if (userAgent.includes("Safari")) {
    // "Mozilla/5.0 (iPhone; CPU iPhone OS 15_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Mobile/15E148 Safari/604.1"
    return "Apple Safari";
  } else {
    return "unknown";
  }
}

const browserName = getBrowserName(navigator.userAgent);
console.log(`You are using: ${browserName}`);

    </script>
</body>

一六三、JavaScript——Location

location表示的是网站的地址栏的信息

                    - 可以直接将location的值修改为一个新的地址,这样会使得网页发生跳转

                    - location.assign() 跳转到一个新的地址 (可以通过回退按钮回退到原来的地址)

                    - location.replac() 跳转到一个新的地址 (无法通过回退按钮回退到原来的地址)

                    - location.reload() 刷新页面,可以传递一个true来强制清缓存刷新

                    - location.replac() 跳转到一个新的地址 (无法通过回退按钮回退到原来的地址)

                    - location.href 获取当前地址

一六四、JavaScript——History

MDN前端文档:https://developer.mozilla.org/en-US/docs/Web/API/History 

                history.back() 浏览器回退

                history.forward() 浏览器前进

                history.go() 可以向前跳转也可以向后跳转,取决于括号中输入的数字,正数向前,负数向后

<body>
    <button id="btn">点我一下</button>

    <script>
        const btn = document.getElement("btn")
        btn.onclick = () => {
            /*
                history.back() 浏览器回退

                istory.forward() 浏览器前进

                history.go() 可以向前跳转也可以向后跳转,取决于括号中输入的数字,正数向前,负数向后
            */

            // 后退
            history.back()

            // 前进
            history.forward()

            // 
            history.go()

        }
    </script>
</body>

一六五、JavaScript——定时器

通过定时器,可以是代码再指定时间后执行

                - 设置定时器打方式有两种:

                    setTimeout() (只执行一次)

                        - 参数

                            1. 回调函数(要执行的代码)

                            2. 间隔的时间(毫秒)

                        clearTimeout()

                            - 关闭定时器

                   

                    setInterval() (每隔一段时间就会执行依次)

                        - 参数:

                            1. 回调函数(要执行的代码)

                            2. 间隔的时间(毫秒)

                        clearInterval()

                            - 关闭定时器

<body>
    <h1 id="num"></h1>

    <script>
        /*
            通过定时器,可以是代码再指定时间后执行
                - 设置定时器打方式有两种:
                    setTimeout() (只执行一次)
                        - 参数
                            1. 回调函数(要执行的代码)
                            2. 间隔的时间(毫秒)
                        clearTimeout()
                            - 关闭定时器
                    
                    setInterval() (每隔一段时间就会执行依次)、
                        - 参数:
                            1. 回调函数(要执行的代码)
                            2. 间隔的时间(毫秒)
                        clearInterval()
                            - 关闭定时器
        */
       
       const timer =  setTimeout(() => {
            alert("我是定时器中的代码")
        },1000)

        // 关闭定时器
        clearTimeout(timer)



        const numH1 = document.getElementById("num")

        let num = 0
       // 构建一个定时器,在指定时间不断生成数字并显示在H1标签中
        const timeres = setInterval(() => {
            num++
            numH1.textContent = num

            // 判断如果定时器的数字到200,则关闭定时器
            if(num === 200) {
                clearInterval(timeres)
            }
        },500)

    </script> 
</body>

一六六、JavaScript——调用栈

            时间循环(event loop)

                - 函数在每次执行时,都会产生一个执行环境

                - 执行环境负责存储函数执行的一切数据

                - 问题:函数的执行环境要存储到哪里

                    - 函数执行环境存储到了一个叫做调用栈的地方

                    - 栈,是一种数据结构,特点:后进先出

               

                调用栈(call stack)

                    - 调用栈负责存储函数的执行环境

                    - 当一个函数被调用时,它的执行环境会作为一个栈帧

                        插入到调用栈的栈项,函数执行完毕其他栈会自动从栈中弹出

                        调用栈中放的都是正在执行的函数

   <script>
        /*
            时间循环(event loop)
                - 函数在每次执行时,都会产生一个执行环境
                - 执行环境负责存储函数执行的一切数据
                - 问题:函数的执行环境要存储到哪里
                    - 函数执行环境存储到了一个叫做调用栈的地方
                    - 栈,是一种数据结构,特点:后进先出
                
                调用栈(call stack)
                    - 调用栈负责存储函数的执行环境
                    - 当一个函数被调用时,它的执行环境会作为一个栈帧
                        插入到调用栈的栈项,函数执行完毕其他栈会自动从栈中弹出
                        调用栈中放的都是正在执行的函数

        */

        function fn(){
            let a = 10;
            let b = 20;

        }
    </script>

 

 一六七、JavaScript——消息队列

                消息队列

                    - 队列,是一种数据结构, 特点:先进先出

                    - 当我们触发一个事件时,其响应函数并不是直接就添加到调用栈中的

                        因为调用栈中又可能会存在一些还没有执行完的代码

                    - 事件触发后,JS引擎是将事件响应函数插入到消息队列中排队

   <script>

    /*
            时间循环(event loop)
                - 函数在每次执行时,都会产生一个执行环境
                - 执行环境负责存储函数执行的一切数据
                - 问题:函数的执行环境要存储到哪里
                    - 函数执行环境存储到了一个叫做调用栈的地方
                    - 栈,是一种数据结构,特点:后进先出
                    

                
                调用栈(call stack)
                    - 调用栈负责存储函数的执行环境
                    - 当一个函数被调用时,它的执行环境会作为一个栈帧
                        插入到调用栈的栈项,函数执行完毕其他栈会自动从栈中弹出
                        调用栈中放的都是正在执行的函数

                消息队列
                    - 队列,是一种数据结构, 特点:先进先出
                    - 当我们触发一个事件时,其响应函数并不是直接就添加到调用栈中的
                        因为调用栈中又可能会存在一些还没有执行完的代码
                    - 事件触发后,JS引擎是将事件响应函数插入到消息队列中排队
                        

        */


        function fn() {
            let a = 10
            let b = 20

            function fn2() {
                console.log("fn2")
            }

            fn2()

            console.log("fn!")
        }

        fn()

        console.log(1111)

        const btn = document.getElementById("btn")
        btn.onclick = function() {
            console.log("按钮被点击了")
        }
    </script>

  一六八、JavaScript——消息队列

猜你喜欢

转载自blog.csdn.net/z972065491/article/details/129101441