一幅长文细学JavaScript(三)——DOM

举报
ArimaMisaki 发表于 2022/08/17 22:16:54 2022/08/17
【摘要】 文章目录 3 JavaScript DOM3.1 DOM基本术语DOM模型及其作用文档对象模型节点节点的属性文档对象 3.2 DOM文档操作3.2.1 查找网页元素3.2.2 获取元...

3 JavaScript DOM

在前面的JS基础阶段中,我们学习的是ECMAScript标准规定的基本语法,但是只学习基本语法是无法做出网页交互效果的,为此在本章的学习中,我们要进入WebAPIs阶段。

WebAPIs是W3C组织的标准,主要学习DOM和BOM,在这一章节中,我们需要JS基本语法的铺垫,步入学习网页交互功能的道路。


3.1 DOM基本术语

DOM模型及其作用

​ 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model),它是W3C组织推荐的处理可扩展标记语言的标准编程接口,其结构为一颗DOM对象树。如果学过Python爬虫中的Xpath解析框架,你可以很好的理解我上述的话。

image-20220712223121800

​ Js可以通过DOM对HTML文档进行操作,即随心所欲操作Web界面。

  • JavaScript 能改变页面中的所有 HTML 元素
  • JavaScript 能改变页面中的所有 HTML 属性
  • JavaScript 能改变页面中的所有 CSS 样式
  • JavaScript 能删除已有的 HTML 元素和属性
  • JavaScript 能添加新的 HTML 元素和属性
  • JavaScript 能对页面中所有已有的 HTML 事件作出反应
  • JavaScript 能在页面中创建新的 HTML 事件

文档对象模型

  • 文档:一个HTML网页就是一个文档
  • 对象:网页中的每一个部分都转换为了一个对象
  • 模型:表示对象之间的关系,方便我们获取对象

节点

节点Node是构建网页最基本的组成部分。网页中的每一个部分都可看做是一个节点。节点类型多样,属性和方法也不尽相同,最常用的节点可以分为以下四类:

  • 文档节点:整个HTML文档;网页中所有的结点都是以子节点的形式存在,文档对象作为window对象的属性存在,我们不用获取可直接使用。通过该对象我们可以在整个文档访问内查找节点对象,并且可以通过该对象创建各种节点对象。
  • 元素节点:HTML文档中的HTML标签;我们可以通过多种方法访问到元素节点,如document.getElementById()。
  • 属性节点:元素的属性;通过元素节点.getAttributeNode(“属性名”)可以找到属性节点对象,但我们很少使用它。
  • 文本节点:HTML标签中的文本内容;使用元素节点.firstChild可以获取元素节点的文本节点,其一般为元素节点的第一个子节点。

节点的属性

对于每个节点来说都具备nodeName、nodeType、nodeValue三个属性。

nodeName nodeType nodeValue
文档节点 #document 9 Null
元素节点 标签名 1 Null
属性节点 属性名 2 属性值
文本节点 #text 3 文本内容

文档对象

  • 浏览器为我们提供了文档节点对象document,这个对象是window属性。如果你希望访问HTML页面中的任何元素,那么你必须从访问document对象开始。

  • 文档节点对象可以在页面中直接使用,文档节点代表的是整个网页


3.2 DOM文档操作

3.2.1 查找网页元素

方法 说明
document.getElementById(‘id’) 元素id查找元素
document.getElementByTagName(‘name’) 标签名查找元素
document.getElementByClassName(‘name’) 类名查找元素
document.querySelector(‘CSS选择器’) 根据CSS选择器返回第一个元素
document.querySelectorAll(‘CSS选择器’) 通过CSS选择器选择多个元素
document.body 选择body标签的所有内容
document.documentElement 选择html标签的所有内容

:JS是解释性语言,故JS代码必须写在HTML的下方,因为只有HTML生成元素了,JS才能通过DOM操纵元素。

<!DOCTYPE html>
<html lang="zh-cn">
<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>
    <!-- HTML元素 -->
    <div id = "test">测试案例1</div>
    <p>测试案例2</p>
    <p>测试案例3</p>
    <div class="c1">测试案例4</div>
    <div class = "c2">测试案例5</div>
    <div id = "c3">测试案例6</div>
    <div id = "c3">测试案例7</div>
    
    <script>
        //1 通过ID找元素,注意ID大小写敏感,返回值为
        var test1 = document.getElementById('test');
        console.log(test1);
        console.dir(test1);//等同于log,用于查看元素结构
        
        //2 通过标签名找元素,这种方式选中所有同名标签,返回值为伪数组
        var test2 = document.getElementsByTagName('p');
        console.log(test2);

        //3 通过类名找元素,该方法仅支持IE9以上,返回值为伪数组
        var test3 = document.getElementsByClassName('c1');
        console.log(test3);
        
        //4 通过选择器查找第一个元素
        var test4 = document.querySelector('.c2');
        console.log(test4);
        
        //5 通过选择器选定所有元素
        var test5 = document.querySelectorAll('#c3');
        console.log(test5);
        var test6 = document.querySelectorAll('*');
        console.log(test6);
        
        //6 得到body元素
        var test7 = document.body;
        console.log(test7);

        //7 得到html元素
        var test8 = document.documentElement;
        console.log(test8);
    </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

3.2.2 获取元素内容

:推荐学完事件再回来看

方法 说明
元素节点.innerText 获取HTML元素标签间的内容
元素节点.innerHTML 获取HTML元素标签间内容以及标签
元素节点.属性 获取HTML元素的属性值
元素节点.style.样式 获取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>Document</title>
    <style>
        #Test5 p{
            height:50px;
            width:100px;
            background: pink;
        }
    </style>
</head>
<body>
    <!-- 测试组件 -->
    <button>测试按钮1</button>
    <div>测试内容1</div>
    <br>
    <div>
        <button id = "testbtn2">测试按钮2</button>
        <p id = "test2">测试内容2</p>
    </div>
    <br>
    <div>
        <button id = "testbtn3">测试按钮3——图片1</button>
        <button id = "testbtn4">测试按钮4——图片2</button>
        <br>
        <img src = "./img_103.jpg" alt = "" id = "testimg" width = 300px>
    </div>
    <div id = "Test5">
        <p>测试内容5</p>
        <br>
        <button>测试按钮5</button>
    </div>
    
    <script>
        /*======innerText======*/
        //1 获取事件源
        var btn1 = document.querySelector('button');
        var div1 = document.querySelector('div');

        //2 注册事件
        btn1.onclick = function(){
            div1.innerText = '测试内容已改变';
        }
        
        /*======innerHTML======*/
        //1 获取事件源
        var btn2 = document.getElementById('testbtn2')
        var p2 = document.getElementById('test2');
        //2 注册事件
        btn2.onclick = function(){
            p2.innerHTML = '<strong>测试内容已改变</strong>';
        }

        /*======元素节点.属性======*/
        //1 获取事件源
        var btn3 = document.getElementById('testbtn3');
        var btn4 = document.getElementById('testbtn4');
        var img3  = document.getElementById('testimg');
        //2 注册事件
        btn3.onclick = function(){
            img3.src = './img_103.jpg';
        }
        btn4.onclick = function(){
            img3.src = './img_112.jpg';
        }

        /*======元素节点.style.样式======*/
        //1 获取事件源
        var btn5 = document.querySelector('#Test5 button');
        var p5 = document.querySelector('#Test5 p');
        //2 注册事件
        btn5.onclick = function(){
            p5.style.background = 'skyblue';
        }
    </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

新的策略——修改样式

说明:如果要想通过DOM修改CSS样式,一个样式就要一条语句,十分难受。为此,我们可以将修改后的样式放在一个选择器中,当我们需要很多组件同时变成该样式时,使用元素.className修改该元素的所属的类,这样就可以给该元素附上提前准备好的样式。

:className方法并不是添加类,而是覆盖类。这就意味着如果元素此前拥有的类将会被覆盖。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        /*提前准备一个样式*/
        .Test1{
            color: yellowgreen;
            background: pink;
        }
    </style>
</head>
<body>
    <div>测试内容1</div>
    <button>测试按钮1</button>
    <script>
        var div1 = document.querySelector('div');
        var btn1 = document.querySelector('button');
        btn1.onclick = function(){
            div1.className = 'Test1';
        }
    </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

更好的策略——修改样式

说明:之前的className容易覆盖以前的类名,故我们可以使用classList方式来追加和删除类名。

方式 说明
元素.classList.add(‘类名’) 追加一个类
元素.classList.remove(‘类名’) 删除一个类
元素.classList.toggle(‘类名’) 切换一个类
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        /*提前准备一个样式*/
        .Test1{
            color: yellowgreen;
            background: pink;
        }

        /*样式2*/
        .Test2{
            background-color: aqua;
        }
    </style>
</head>
<body>
    <div class = "Test1">测试内容1</div>
    <button class = "add-btn">追加样式类</button>
    <button class = "remove-btn">删除样式类</button>
    <button class = "toggle-btn">切换样式类</button>
    <script>
        var div = document.querySelector('div')
        var add_btn = document.querySelector('.add-btn')
        var remove_btn = document.querySelector('.remove-btn')
        var toggle_btn = document.querySelector('.toggle-btn')
        console.log(add_btn);
        console.log(remove_btn);
        add_btn.onclick = function(){
            div.classList.add('Test2')
        }

        remove_btn.onclick = function(){
            div.classList.remove('Test2');
        }

        toggle_btn.onclick = function(){
            div.classList.toggle('Test1');
        }
    </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

3.2.3 改变元素内容

说明:我们可以通过以下方法修改元素的内容

方法 说明
元素节点.innerText =新内容 改变元素的标签值
元素节点.innerHTML = 新元素 改变元素
元素节点.属性 = 新的属性值 改变元素的属性值
元素节点.setAttribute(属性, 值) 改变元素的属性值
元素节点.style.样式 = 新的属性值 改变 HTML 元素的行内样式值

3.2.4 操作网页元素

创建 HTML 元素节点:document.createElement(element)

创建 HTML 属性节点:document.createAttribute(attribute)

创建 HTML 文本节点:document.createTextNode(text)

删除 HTML 元素:元素节点.removeChild(element)

添加 HTML 元素:元素节点.appendChild(element)

替换 HTML 元素:元素节点.replaceChild(element)

在指定的子节点前面插入新的子节点:元素节点.insertBefore(element)


3.2.5 获取元素偏移

说明:offset指偏移量,我们使用offset系列相关属性可以动态地获取该元素的位置、大小等。需要注意的是,获取的仅有数值而无单位

方法 说明
元素.offsetWidth 返回自身包括padding、边框、内容区的宽度,返回数值不带单位
元素.offsetHeight 返回自身包括padding、边框、内容区的高度,返回数值不带单位
元素.offsetParent 获取离当前元素最近的开启了定位的祖先元素
元素.offsetTop 返回元素相对带有定位父元素上方的偏移
元素.offsetLeft 返回元素相对带有定位父元素左边框的偏移
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin:0;
            padding:0;
        }
        .div{
            background-color: pink;
            height: 200px;
            width: 200px;
            border: 2px solid red;
            padding:2px;
        }
    </style>
</head>
<body>
    <div class = "div"></div>
    <script>
        var div = document.querySelector(".div")
        // offsetWidth返回自身包括padding、边框、内容区的宽度,返回数值不带单位
        console.log(div.offsetWidth);
        // offsetHeight返回自身包括padding、边框、内容区的高度,返回数值不带单位
        console.log(div.offsetHeight);
        // offsetParent获取离当前元素最近的开启了定位的祖先元素
        console.log(div.offsetParent);
        // offsetTop返回元素相对带有定位父元素上方的偏移
        console.log(div.offsetTop);
        // offsetLeft返回元素相对带有定位父元素左边框的偏移
        console.log(div.offsetLeft);
    </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

offset和style的区别

offset style
offset可以得到任意样式表中的样式值 style只能得到行内样式表中的样式值
offset系列获得的数值是不带单位的 style.width获得的是带有单位的字符串
offsetWidth包含padding+border+width style.width获得不包含padding和border的值
offsetWidth等属性属于只读属性 style.widh是可读写属性,可以获取也可以赋值

3.2.6 获取元素可视区

方法 说明
元素.clientWidth 返回自身包括padding、内容区宽度、不含边框,返回数值不带单位
元素.clientHeight 返回自身包括padding、内容区高度、不含边框,返回数值不带单位
元素.clientTop 返回元素上边框的大小
元素.cllientLeft 返回元素左边框的大小
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div{
            width: 200px;
            height: 200px;
            background-color: pink;
            border: 3px solid skyblue;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <div></div>

    <script>
        var div = document.querySelector('div');
        console.log(div.clientWidth); //200,说明不包含边框
        console.log(div.clientHeight);//200 说明不包含边框
        console.log(div.clientLeft);//3 边框的左边宽度为3
        console.log(div.clientTop);//3 边框的顶部宽度为3
    </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

3.2.7 获取元素滚动

方法 说明
元素.scrollTop 返回被卷去的上侧距离,返回数值不带单位
元素.scrollLeft 返回被卷去的左侧距离,返回数值不带单位
元素.scrollWidth 返回自身实际的宽度,不含边框,返回数值不带单位
元素.scrollHeight 返回自身实际的高度,不含边框,返回数值不带单位

image-20220723112541620

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div{
            width:50px;
            height:100px;
            background-color: pink;
            overflow: scroll;
            border: 3px solid red;
        }
    </style>
</head>
<body>
    <div>测试内容1  测试内容1  测试内容1  测试内容1  </div>
    <script>
        var div = document.querySelector('div');
        console.log(div.scrollHeight);//208 表名内容+padding的宽度为208
        console.log(div.scrollTop); //0 表明没有内容在滚动条上面
        console.log(div.scrollWidth);//33 表名内容+padding的宽度为33
        console.log(div.scrollLeft);//0表名没有内容在滚动条左侧
    </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

3.2.8 元素节点导航

说明:在前面的选择器中,我们通通都是使用DOM提供的方法来获取元素,但这些方法逻辑性不强且繁琐。为此,Js还提供了利用节点层级来获取元素。

方法 描述
元素节点.parentNode 返回元素的父节点。
元素节点.parentElement 返回元素的父元素。
元素节点.childNodes 返回元素的一个子节点的数组(包含空白文本Text节点)。
元素节点.children 返回元素的一个子元素的集合(不包含空白文本Text节点)。但其为非标准方法
元素节点.firstChild 返回元素的第一个子节点(包含空白文本Text节点)。
元素节点.firstElementChild 返回元素的第一个子元素(不包含空白文本Text节点)。
元素节点.lastChild 返回元素的最后一个子节点(包含空白文本Text节点)。
元素节点.lastElementChild 返回元素的最后一个子元素(不包含空白文本Text节点)。
元素节点.previousSibling 返回某个元素紧接之前节点(包含空白文本Text节点)。
元素节点.previousElementSibling 返回指定元素的前一个兄弟元素(相同节点树层中的前一个元素节点)。
元素节点.nextSibling 返回某个元素紧接之后节点(包含空白文本Text节点)。
元素节点.nextElementSibling 返回指定元素的后一个兄弟元素(相同节点树层中的下一个元素节点)。
<div>我是div</div>
    <span>我是span</span>
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ul>
    <div class="box">
        <span class = "erweima">×</span>
    </div>
    <script>
        // 1.通过已知元素节点获取最近的父节点
        var erweima = document.querySelector('.erweima')
        // var box = document.querySelector('.box') 传统写法
        var box = erweima.parentNode //元素导航写法
        console.log(box);
        
        // 2.通过已知元素节点获取所有的子节点,子节点中既有元素节点也有文本节点
        // 通常不建议使用该方法来获取子节点,因为太麻烦了
        var ul = document.querySelector('ul')
        console.log(ul.childNodes);

        // 3.非标准方法,但其获得所有浏览器认可,用于选取已知元素节点的所有子元素节点
        console.log(ul.children);

        // 4.获取第一个子节点
        console.log(ul.firstChild);

        // 5.获取第一个元素子节点
        console.log(ul.firstElementChild);

        // 6.获取最后一个子节点
        console.log(ul.lastChild);

        // 7.获取最后一个元素子节点
        console.log(ul.lastElementChild);
    </script>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

3.2.9 查找网页元素

属性 说明
document.anchors 返回拥有 name 属性的所有<a> 元素
document.baseURI 返回文档的绝对基准 URI
document.body 返回 <body> 元素
document.cookie 返回文档的 cookie
document.doctype 返回文档的 doctype
document.documentElement 返回 <html> 元素
document.documentMode 返回浏览器使用的模式
document.documentURI 返回文档的 URI
document.domain 返回文档服务器的域名
document.forms 返回所有 <form> 元素
document.embeds 返回所有 <embed> 元素
document.images 返回所有 <img> 元素
document.lastModified 返回文档更新的日期和时间
document.title 返回 <title> 元素
document.scripts 返回所有 <script> 元素

3.3 DOM文档事件

3.3.1 事件入门

事件基本概念

事件:编程时系统内发生的动作或者发生的事情

事件监听:让程序检测是否有事件发生,一旦有事件触发,就立即调用一个函数做出响应,也称为注册事件。


事件的三要素

  • 事件源:事件被触发的对象
  • 事件类型:如何触发
  • 事件调用的函数:要做什么事

执行事件的过程

  1. 获取事件源
  2. 注册事件(绑定事件)
  3. 添加事件处理程序

3.3.2 事件绑定

事件监听版本

版本 写法
DOM L0 事件源.on事件 = function(){}
DOM L2 事件源.addEventListener(事件,事件处理函数,布尔值)

  • L0和L2有很大区别,我们会在后面讨论。
  • 第三个参数时布尔值,指定使用事件冒泡还是事件捕获,如果是true则为捕获,如果是false则为传播,此参数可省略。
  • 在IE9之前不支持L2,可使用attachEvent()代替。

IE9之前的事件绑定

格式:事件源.attachEvent(事件,事件处理函数)

说明:官方在文档中明确指出,在实际开发中不要使用该方式


事件监听发展史

  • DMO L0:是DOM发展的第一个版本
  • DOM L1:1998.10.1称为W3C推荐标准
  • DOM L2:使用addEventListener注册事件
  • DOM L3:DOM3级别事件模块在DOM2级事件的基础上重新定义了这些事件,也添加了一些新事件类型
<!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 = "btn1">测试按钮1</button>
    <button id = "btn2">测试按钮2</button>

    <script>
        /*老版写法*/
        var btn1 = document.getElementById("btn1");
        btn1.onclick = function(){
            alert('按钮1已被点击');
        }


        /*新版写法*/
        var btn2 = document.getElementById("btn2");

        btn2.addEventListener("click", function(){
            alert('按钮2已被点击');
        })
    </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

3.3.3 窗口事件

:在下面各类型事件的使用中,我们不推荐一个一个全部死记,要用什么查什么即可。

属性 描述
onblur 当窗口失去焦点时运行脚本。
onfocus 当窗口获得焦点时运行脚本。
onload 当文档加载之后运行脚本。
onresize 当调整窗口大小时运行脚本。常用作响应式布局。
onstorage 当 Web Storage 区域更新时(存储空间中的数据发生变化时)运行脚本。
DOMContentLoaded 不包括样式表、图片、flash等,仅当DOM加载完成即触发时间,适合用于页面图片较多的情况

3.3.4 鼠标事件

属性 描述
onclick 当单击鼠标时运行脚本。
ondblclick 当双击鼠标时运行脚本。
onmousedown 当按下鼠标按钮时运行脚本。
onmouseup 当松开鼠标按钮时运行脚本。
onmousemove 当鼠标指针移动时运行脚本。
onmouseover 当鼠标指针移至元素之上时运行脚本,不可以阻止冒泡。
onmouseout 当鼠标指针移出元素时运行脚本,不可以阻止冒泡。
onmouseenter 当鼠标指针移至元素之上时运行脚本,可以阻止冒泡。
onmouseleave 当鼠标指针移出元素时运行脚本,可以阻止冒泡。
onmousewheel 当转动鼠标滚轮时运行脚本。
onscroll 当滚动元素的滚动条时运行脚本。

3.3.5 键盘事件

属性 描述
onkeydown 当按下按键时运行脚本。
onkeyup 当松开按键时运行脚本。
onkeypress 当按下并松开按键时运行脚本。

3.3.6 焦点事件

属性 描述
focus 获得焦点
blur 失去焦点

3.3.7 文本事件

属性 描述
input 用户输入文本时开始运行脚本

3.3.8 表单事件

属性 描述
onblur 当元素失去焦点时运行脚本。
onfocus 当元素获得焦点时运行脚本。
onchange 当元素改变时运行脚本。
oninput 当元素获得用户输入时运行脚本。
oninvalid 当元素无效时运行脚本。
onselect 当选取元素时运行脚本。
onsubmit 当提交表单时运行脚本。

3.3.9 媒体事件

属性 描述
onabort 当发生中止事件时运行脚本。
oncanplay 当媒介能够开始播放但可能因缓冲而需要停止时运行脚本。
oncanplaythrough 当媒介能够无需因缓冲而停止即可播放至结尾时运行脚本。
ondurationchange 当媒介长度改变时运行脚本。
onemptied 当媒介资源元素突然为空时(网络错误、加载错误等)运行脚本。
onended 当媒介已抵达结尾时运行脚本。
onerror 当在元素加载期间发生错误时运行脚本。
onloadeddata 当加载媒介数据时运行脚本。
onloadedmetadata 当媒介元素的持续时间以及其它媒介数据已加载时运行脚本。
onloadstart 当浏览器开始加载媒介数据时运行脚本。
onpause 当媒介数据暂停时运行脚本。
onplay 当媒介数据将要开始播放时运行脚本。
onplaying 当媒介数据已开始播放时运行脚本。
onprogress 当浏览器正在取媒介数据时运行脚本。
onratechange 当媒介数据的播放速率改变时运行脚本。
onreadystatechange 当就绪状态(ready-state)改变时运行脚本。
onseeked 当媒介元素的定位属性不再为真且定位已结束时运行脚本。
onseeking 当媒介元素的定位属性为真且定位已开始时运行脚本。
onstalled 当取回媒介数据过程中(延迟)存在错误时运行脚本。
onsuspend 当浏览器已在取媒介数据但在取回整个媒介文件之前停止时运行脚本。
ontimeupdate 当媒介改变其播放位置时运行脚本。
onvolumechange 当媒介改变音量亦或当音量被设置为静音时运行脚本。
onwaiting 当媒介已停止播放但打算继续播放时运行脚本。

3.3.10 排他思想

排他思想:当前元素为A状态,其他为B状态

应用:轮播图等

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .pink{
            background-color: pink;
        }
    </style>
</head>
<body>
    <button class = 'pink'>测试按钮1</button>
    <button>测试按钮2</button>
    <button>测试按钮3</button>

    <script>
        var btns = document.querySelectorAll('button');
        for (var i = 0; i < btns.length; i++) {
            btns[i].addEventListener('click',function(){
                document.querySelector('.pink').classList.remove('pink');
                this.classList.add('pink');
            })
        }
    </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

3.3.11 事件冒泡

事件冒泡:事件的向上传导。当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div{
            background: skyblue;
            width: 300px;
            height: 300px;
        }
        
        div  div{
            background: pink;
            height: 50px;
            width:50px;
        }
    </style>
</head>
<body>
    <div>
        <div></div>
    </div>

    <script>
        var innerDiv = document.querySelector('div > div');
        var outerDiv = document.querySelector('div');

        innerDiv.onclick = function(){
            alert("您点击了内层");
        }

        outerDiv.onclick = function(){
            alert("您点击了外层");
        }
    </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

3.3.12 事件委派

事件委派:为多个元素绑定同一个事件。

事件委派原理:利用事件冒泡。将事件统一绑定给祖先元素后,点击后代元素,则后代元素会冒泡到祖先元素上去寻找事件。

事件委派的好处:通过委派可以减少事件绑定的次数,提高程序的性能。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        p{
            background-color: greenyellow;
        }
    </style>
</head>
<body>
    <div class = "divClass">
        <p>测试内容1</p>
        <p>测试内容2</p>
        <p>测试内容3</p>
    </div>

    <script>
        var div1 = document.querySelector('div');
        /*target属性用于返回一个事件触发对象*/
        div1.onclick = function(event){
            if(event.target.className != 'divClass'){
                alert('测试内容已被点击');
            }
        }
    </script>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

3.3.13 事件传播

事件流

说明:事件流描述的是从页面中接收事件的顺序。事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。如我们给一个div注册点击事件:

image-20220815234456616

这时候我们需要先去寻找这个元素,这个过程我们称为捕获阶段,找到当前目标后,进入当前目标阶段,对目标进行事件的执行,最后进入冒泡阶段,div元素执行事件后,父级元素如果有相同类型的事件,则也会触发,如两者都具有点击事件。

事件捕获

在HTML DOM中有两种事件传播方式:冒泡捕获。我们在前面已经谈论过冒泡,冒泡就是从内而外发生事件,而捕获则和冒泡反着来。


回到事件绑定

方法 说明
事件源.addEventListener(事件,事件处理函数,布尔值) 绑定事件
事件源.removeEventListener(事件,事件处理函数) 解绑事件

  • L2绑定事件允许向相同元素添加多个不同类型的事件,且不覆盖
  • L2绑定和解绑只支持IE8之后的版本

3.3.14 事件对象

事件对象简介

说明:只要绑定了事件,则系统会自动创建一个事件对象event,可简写为e或evt。我们将其写于事件回调函数的参数列表中。


事件对象常用属性和方法

事件对象属性方法 说明
e.target 返回触发事件的对象
e.srcElement 返回触发事件的对象 ie6-8才可使用
e.type 返回事件的类型
e.cancelBubble 阻止事件冒泡 ie6-8使用
e.returnValue 阻止默认事件发生 ie6-8使用
e.preventDefault() 阻止默认事件发生
e.stopPropagation() 阻止事件冒泡

文章来源: blog.csdn.net,作者:ArimaMisaki,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/chengyuhaomei520/article/details/126356845

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。