web前端学习笔记——DOM

时间:2024-10-07 07:13:35

存档!(虽然笔记有点乱)
以下是全程跟着pink老师的讲课视频整理的课程笔记,有一些案例截图没找着

1. Web API

学习目标:

  • Web APIs阶段与JavaScript语法阶段的关联性有哪些?
  • 能够说出什么是API?
  • 能够说出什么是Web API?

1.1 Web APIs 和JavaScript基础的关联性

JavaScript的组成:ECMAScript、DOM、BOM

ECMAScript(JavaScript语法) DOM(页面文档对象模型)+ BOM(浏览器对象模型)
这是**JavaScript基础** 这是 Web APIs
1. 学习的是 ECMAScript 标准规定的基本语法 1. Web APIs 是 W3C 组织的标准
2.要求掌握JS基础语法 APIs主要学习的是 DOM 和 BOM
3.目的是为了JS后面的课程打基础、做铺垫 3. 主要学习**页面交互功能**,以JS基础的课程内容为基础

1.2 API 和 Web API

  • API:(Application Programming Interface 应用程序接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节

    API是给程序员提供的一种工具,以便能更轻松的实现想要完成的功能。

例如:手机充电的接口,我们不关心充电线是如何制作的,也不关心手机内部变压器,内部怎么存储电等,我们只知道,当数据线插进充电接口时就可以充电,这个充电接口就是一个API

  • Web API 是浏览器提供的一套操作浏览器功能和页面元素的API(BOM 和 DOM)

1.3 API 和 Web API 小结

  1. API 是为程序员提供的一个接口,帮助我们实现某种功能,会使用就可以了,不必纠结如何实现
  2. Web API 主要针对于浏览器提供的接口,主要针对于浏览器做交互效果
  3. Web API 一般都有输入和输出(函数的传参和返回值),Web API 很多都是方法和函数
  4. 可以用学习内置对象方法的思路去学习Web API

2. DOM

学习目标:

  • 能够说出什么是DOM?
  • 如何获取页面元素?
  • 如何给元素注册事件?
  • 怎么操作DOM元素的属性呢?
  • 如何创建元素?
  • 怎么来操作DOM节点?

2.1 DOM 简介

文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理可扩展标记语言(HTML / XML)的标准编程接口

“W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问、更新文档的内容、结构和样式。”

通过DOM接口可以改变网页的内容、结构和样式。

DOM 树

在这里插入图片描述

DOM 里面的一些专有名词:

  • 文档:一个页面就是一个文档,在DOM中使用 document 表示
  • 元素:页面中的所有标签都是元素,在DOM中使用 element 表示
  • 节点:页面中的所有内容都是节点(标签、属性、文本、注释等),在DOM中使用 node 表示

DOM把以上内容都看作是一个对象→所以叫做文档对象模型

2.2 获取元素

如何获取页面元素

实际开发中DOM主要用来操作元素,但是得先获取才可以操作,获取页面的元素有以下几种方式:

  • 根据ID获取
  • 根据标签名获取
  • 通过HTML5新增的方法获取
  • 特殊元素获取
  • () 打印我们返回的元素对象 更好的查看里面的属性和方法
①通过ID获取

()方法 (通过Id获取元素)

Document的方法 getElementById()返回一个匹配特定 ID的元素. 由于元素的 ID 在大部分情况下要求是独一无二的,这个方法自然而然地成为了一个高效查找特定元素的方法。

  • 语法:
var document  = (id)
  • 1
  • 参数:

element是一个 Element 对象。如果当前文档中拥有特定ID的元素不存在则返回null.

id是大小写敏感的字符串,代表了所要查找的元素的唯一ID.

  • 返回的是一个元素对象(object)
<body>
    <div id="timer">2022-03-07</div>
    <script>               // 因为文档自上而下加载 所以得先有标签 所以把script写到标签下面
        var timer = document.getElementById('timer');
        console.log(timer);
        console.log(typeof timer);         // object  返回的是一个元素对象 
        // ()打印我们返回的元素对象 更好的查看里面的属性和方法
        console.dir(timer);                // div#timer    
    </script>

</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

注意: (1)‘id’ 拼写一定要准确,大小写不能写错

​ (2)getElementById() 只有在作为 document 的方法时才能起作用,而在DOM中的其他元素下无法生效。这是因为 ID 值在整个网页中必须保持唯一。因此没有必要为这个方法创建所谓的 “局部” 版本。


②通过标签名获取

1、() (通过标签名获取元素们)

返回一个包括所有给定标签名称的元素的HTML集合HTMLCollection整个文件结构都会被搜索,包括根节点。返回的 HTML集合是动态的, 意味着它可以自动更新自己来保持和 DOM 树的同步而不用再次调用 ()

  • 语法:
var elements = document.getElementsByTagName(name);
  • 1
  • 简单来说:返回的是带有标签名的对象集合,是以伪数组的形式存储;
  • 得到的元素是动态的,只需要更改HTML代码,不需要更改JS代码即可自动更新。
  • 如果想要一次打印标签里面的元素对象,可以采取遍历的方式
  • 如果页面只有一个<li></li>,返回的还是伪数组
  • 如果页面中没有这个元素,则返回一个空的伪数组

获取某个元素(父元素)内部所有指定标签名的子元素:

2、element(父元素).getElementsByTagName('标签名');

注意: 父元素必须是单个对象,获取的时候不包括父元素自己

<body>
    <ul>
        <li>知否知否应是绿肥红瘦1</li>
        <li>知否知否应是绿肥红瘦2</li>
        <li>知否知否应是绿肥红瘦3</li>
        <li>知否知否应是绿肥红瘦4</li>
        <li>知否知否应是绿肥红瘦5</li>
    </ul>

    <ol id="ol">
        <li>父元素必须是指定的单个元素</li>
        <li>父元素必须是指定的单个元素</li>
        <li>父元素必须是指定的单个元素</li>
        <li>父元素必须是指定的单个元素</li>
        <li>父元素必须是指定的单个元素</li>
    </ol>

    <script>
        var lis = document.getElementsByTagName('li');
        console.log(lis);          // ()获取到标签内的所有元素
        console.log(lis[2]);       // 如果要获取指定的某一行元素,需要指定

        // 依次打印里面的元素对象可以采用遍历的方式
        for (var i = 0; i < lis.length; i++) {
            console.log(lis[i]);
        }

        // 获取 <ol> 里面的元素用element(指定父元素).getElementsByTagName()
        // var ol = ('ol');
        // (ol[0].getElementsByTagName('li'));

        // 上面获取ol中li的方法不常用,实际开发中常用以下的方法:   在 ol 中添加 id
        var ol = document.getElementById('ol');
        console.log(ol.getElementsByTagName('li'));
    </script>
</body>
  • 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

③ 通过HTML5 新增的方法获取(IE9以上)

1、() (通过类名获取元素们)

2、('选择器') 返回指定选择器的第一个元素对象,里面的类选择器、id选择器要添加符号 .box #nav

3、('选择器') 返回指定选择器的所有元素对象

<body>
    <div class="box">盒子1</div>
    <div class="box">盒子2</div>
    <div id="nav">
        <ul>
            <li>首页</li>
            <li>产品</li>
        </ul>
    </div>

    <script>
        // 1. 通过类名获取元素集合  ();
        var boxs = document.getElementsByClassName('box');
        console.log(boxs);

		// 2. querySelector('选择器'); 返回指定选择器的第一个元素对象
		// 切记切记:里面的类选择器、id选择器要添加符号  .box   #nav
		var firstBox = document.querySelector('.box');
        console.log(firstBox);

        var nav = document.querySelector('#nav');
        console.log(nav);

        var li = document.querySelector('li');
        console.log(li);     // <li>首页</li>     返回的是指定选择器的地一个元素对象

		// 3. querySelectorAll('选择器'); 返回指定选择器中的所有元素对象
		// 	等价于方法1 通过类名获取元素
		var allBoxs = document.querySelectorAll('.box');
        console.log(allBoxs);      // NodeList[2]

    </script>
</body>
  • 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

④ 获取 body 元素
document.body;
  • 1
<body>
    <script>
        var bodyEle = document.body;
        console.log(bodyEle);           // <body>...</body>
        console.dir(bodyEle);           // body
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

⑤ 获取 html 元素
document.documentElement;
  • 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>
    <script>
        // var htmlEle = ;     // undefined
        var htmlEle = document.documentElement;
        console.log(htmlEle);               // 输出了一整个html页面代码内容
    </script>
</body>

</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

获取页面元素方法小结

方法 语法 注意点
①通过id获取 var element = (id); id 必须是字符串,所以要带’',且大小写敏感,不能写错,因为id唯一,所以返回值是一个标签元素
②通过标签名获取 var elements = (name); 返回的是带有标签名的对象集合,以伪数组方式存储
elements=(tagName); element是指被指定的父元素
③通过HTML5新增方法获取(要考虑兼容性) (‘类名’) 返回的也是集合
(‘选择器’) 类选择器:.box;id选择器:#div 返回指定选择器的第一个元素
(‘选择器’) 返回指定选择器的所有元素
④获取特殊元素 ;
; 输出的是一整个html页面代码

2.3 事件基础

事件

例如:鼠标经过了,下拉菜单才会弹出;只有鼠标点击了轮播图才会轮播;想要操作一个元素,在很多情况下,需要一些特殊的情况才能触发它,这就需要事件来帮我们完成

JavaScript使我们有能力创建动态页面,而事件是可以被JavaScript侦测到的行为

事件:是触发响应的一种机制

网页中每个元素都可以产生某些可以触发JavaScript的事件,例如点击一个按钮弹出对话框

事件三要素

① 事件源

事件被触发的对象,是谁被触发了呢?例如点击一个按钮会弹出对话框,那么被触发的是按钮→通过获取对象的方法获取事件源

② 事件类型

怎么触发的?什么事件?比如说:是鼠标点击触发呢?还是鼠标经过触发呢?还是键盘按下触发?

鼠标点击(onclick)

③ 事件处理程序

要做什么事情?通过一个函数赋值的方式完成,比如:弹出对话框

<body>
    <button id="btn">唐伯虎</button>
    <script>
        var btn = document.getElementById('btn');
        btn.onclick = function () {
            alert('点秋香');
        }
    </script>
</body>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

执行事件的步骤

1、获取事件源:通过2.2获取元素对象的方法来获取事件源(盒子div、按钮button等等)

2、注册事件(绑定事件)

3、添加事件处理程序(采取函数赋值的形式)(盒子显示或隐藏等等)

常见的鼠标事件

鼠标事件 触发条件
onclick 鼠标点击左键触发
onmouseover 鼠标经过触发
onmouseout 鼠标离开触发
onfocus 获得鼠标焦点触发
onblur 失去鼠标焦点触发
onmousemove 鼠标移动触发
onmouseup 鼠标弹起触发
onmousedown 鼠标按下触发

分析事件三要素

(1)鼠标点击按钮弹出对话框的三要素:按钮、点击、弹出对话框

(2)下拉菜单显示菜单栏三要素:放菜单栏的那个盒子、鼠标经过、显示菜单栏

(3)关闭广告三要素:×号盒子、鼠标点击、广告那个盒子隐藏起来

2.4 操作元素

JavaScript的DOM操作可以改变网页内容、结构和样式,我们可以利用DOM操作元素来改变元素里面的内容、属性等。

注意:以下都是属性

改变元素内容

① 从起始位置到终止位置的内容,但它去除HTML标签,同属空格和换行也会去掉

element.innerText;
// element 表示的是那个元素/标签里面的内容发生了变化
// 是属性,所以采取赋值的方法
  • 1
  • 2
  • 3

② 起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行

element.innerHTML;
  • 1

小总结: 常用 innerHTML

innerText innerHTML
无法识别html标签,会将标签也当做文字直接输出 可以识别html标签
非标准,由IE发起,老版本火狐不支持 W3C标准
空格换行都会去掉 保留了空格和换行
读取出来的是代码运行出来的内容 读取出来的是标签里面的代码

*注意:*这两个属性是可读写的

// 可以赋值,也可以获取元素里面的内容
<body>
    <div>下面会换行吗?</div>
    <p>
        这是文字
        <span>123</span>
        <span>456</span>
    </p>
    <script>
        var div = document.querySelector('div');
        //  = '<u>今天</u>10号';
        div.innerHTML = '<b>今天</b>10号';

        // 这两个属性是可读写的  可以获取元素内容
        var p = document.querySelector('p');
        console.log(p);                // <p>...</p>
        console.log(p.innerText);      // 这是文字 123 456
        console.log(p.innerHTML);      //     这是文字
        							   //     <span>123</span>
        							   //     <span>456</span>

        var span = document.querySelector('span');
        console.log(span);        // <span>123</span>
    </script>
</body>
  • 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

在这里插入图片描述

<!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,
        p {
            width: 300px;
            height: 30px;
            line-height: 30px;
            color: brown;
            background-color: burlywood;
        }
    </style>
</head>

<body>
    <!-- 当我们点击按钮,div里面的文字会发生变化 -->
    <button>显示系统当前的时间</button>
    <div>某个时间</div>
    <p>小段落</p>
    <script>
        // 1.获取事件源
        var btn = document.querySelector('button');
        var div = document.querySelector('div')
        // 2.注册事件
        // 3.添加事件处理程序
        btn.onclick = function () {
            //  = '2022-3-10'
            div.innerHTML = getDate();      // 动态时间

        }

        function getDate() {
            var date = new Date();
            // var date = new Date();     要记得创建日期对象
            var year = date.getFullYear();
            var month = date.getMonth() + 1;
            var dates = date.getDate();
            var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']       // 从周日开始计算,要习惯把周日放在一周的第一天
            var day = date.getDay();
            // ('今天是:' + year + '年' + month + '月' + dates + '日' + '星期' + day);    
            // ('今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day]);       // 通过遍历数组的方法将星期5改为星期五
            return '今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day];       // 需要用return返回

        }


        // 元素也可以不用添加事件,直接使用
        // 1.获取元素
        var p = document.querySelector('p');
        p.innerHTML = getDate();


    </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

常用元素的属性操作

  1. innerTextinnerHTML 改变元素内容
  2. src (图片)、href (网址) 修改元素:换图片、换网页链接
  3. idalttitle (鼠标经过时显示其内容)
<body>
    <button id="evan">林彦俊</button>
    <button id="yeol">朴灿烈</button>
    <img src="images/" height="300px" alt="" title="林彦俊">
    <script>
        // 1.获取元素
        var evan = document.getElementById('evan');
        var yeol = document.getElementById('yeol');
        var img = document.querySelector('img');

        // 2.注册事件,处理程序
        yeol.onclick = function () {
            img.src = "images/";    // 赋值操作:元素.属性 = '';
            img.title = '朴灿烈';
        }

        evan.onclick = function () {
            img.src = "images/";
            img.title = '林彦俊';
        }

    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

表单元素的属性操作

  • type (类型属性)

  • value(值属性) : input表单里面的文字内容不能通过innerHTNL来修改,而是通过value

  • checked(选择)

  • selected

  • disabled (表单是否被使用) :设置某个表单被禁用,不能再点击了

显示/隐藏密码案例

算法思想

按钮可以点击多次:利用一个flag变量,来判断flag的值,如果是0就切换为文本框,flag设置为1,如果是1就切换位密码框,flag设置为0

<script>
        // 1.获取元素
        // var input = ('input');
        // var img = ('img');
        var pwd = document.getElementById('pwd');
        var eye = document.getElementById('eye');

        // 2.注册事件 处理程序

        // 按钮点多次的算法:利用一个flag变量,来判断flag的值,如果是0就切换为文本框,flag设置为1,如果是1就切换位密码框,flag设置为0
        var flag = 0;
        eye.onclick = function () {
            if (flag == 0) {
                pwd.type = 'text';
                eye.src = 'images/';
                flag = 1;
            } else {
                pwd.type = 'password';
                eye.src = 'images/';
                flag = 0;
            }
        }
    </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
<body>
    <input type="text" name="" id="" value="请输入内容">
    <button>确认</button>
    <script>
        // 1. 获取元素
        var input = document.querySelector('input');
        var btn = document.querySelector('button');

        // 2. 注册事件 处理程序
        btn.onclick = function () {
            input.value = '被点击了';     // 修改input表单里面的内容
            //  = true;         // 表单被禁用
            this.disabled = true;        // this指向的是事件函数的调用者(btn)
        }

    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

样式属性操作

可以通过JS修改元素的大小、颜色、位置等样式

行内样式操作 样式比较少/ 功能比较简单的情况下使用
类名样式操作

注意:(1) JS里面的样式采取驼峰命名法

​ (2)JS修改style样式操作,会在行内样式中生成css,css权重比较高

<div>底色green文字burlywood,这样颜色还挺好看</div>
    <script>
        var test = document.querySelector('div');
        test.onclick = function () {
            //  = 'purple';
            
            // 当前元素的类名改为了change
            this.className = 'change';
        }
    </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
案例1 :仿淘宝关闭二维码

在这里插入图片描述

案例2:循环精灵图

在这里插入图片描述

案例3:显示隐藏文本框内容(挺常用)

在这里插入图片描述

案例4:密码框验证信息

在这里插入图片描述

操作元素总结

在这里插入图片描述

排他思想★★★★★

案例:轮播图下的小圆点、按钮切换

如果由同一组元素,我们想要某一个元素实现某种样式,需要用到循环的排他思想算法:

  1. 所有元素全部清除样式(干掉其他人)
  2. 给当前元素设置样式(留下自己)
  3. 注意顺序不能颠倒,首先干掉其他人,再设置自己的样式
<body>
    <button>按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>

    <script>
        // 获取所有按钮元素
        var btns = document.getElementsByTagName('button');
        for (var i = 0; i < btns.length; i++) {
            btns[i].onclick = function () {
                // 先把所有按钮背景颜色全部去掉
                for (var i = 0; i < btns.length; i++) {
                    btns[i].style.backgroundColor = '';
                }
                // 然后才让当前元素的背景颜色变成绿色
                this.style.backgroundColor = 'green';
            }
        }
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

获取和设置属性

获取自定义属性值 (1)element.属性 获得内置属性值(元素本身自带的属性)
(2)(‘属性’)
设置自定义属性 (1)element.属性=‘值’ 设置内置属性值
(2)(‘属性’,‘值’) 主要设置自定义的属性值,class比较特殊,这儿写class而不是className
移除自定义属性 (‘属性’)

●Tab栏切换案例★★★★★

 <script>
        //栏有2个大模块
        //2.上面的选项卡,点击某一个,某一个就变为红色(排他思想)→点击某一个,点击的那个的类名就为'current'
        //获取元素
        var tab_list = document.querySelector('.tab_list');
        var lis = tab_list.querySelectorAll('li');
        //5.当我们点击tab_list里面的某个li,让tab_con里面对应序号的内容显示,其余隐藏(排他思想)
        var items = document.querySelectorAll('.item');
        //for循环绑定点击事件
        for (var i = 0; i < lis.length; i++) {
            //4.核心思路:给tab_list里面的每个li设置自定义属性:索引号
            lis[i].setAttribute('index', i);
            lis[i].onclick = function () {
                //先干掉所有人  其他li清除class这个类
                for (var i = 0; i < lis.length; i++) {
                    lis[i].className = '';
                }
                //然后留下我自己,让当前选中的类名变为current
                this.className = 'current';

                //console显示内容
                var index = this.getAttribute('index');
                console.log(index);
				//3.下面的模块内容会跟随上面选项卡变化,所以下面模块变化写到点击事件里面
                //第二次使用排他思想
                //干掉所有人 让其他item这些div隐藏
                for (var i = 0; i < items.length; i++) {
                    items[i].style.display = 'none';
                }
                //留下我自己 让对应的item内容显示出来
                items[index].style.display = 'block';
            }
        }
    </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

H5自定义属性

自定义属性的目的:是为了保存并使用数据,有些数据可以保存到页面中而不用保存到数据库中

1.设置H5自定义属性

★H5规定自定义属性data-开头作为属性名并且赋值,如果自定义属性名是由多个 - 连接的单词,获取属性时采取 驼峰命名法

(1)<div data-index='1'></div>

(2)使用JS设置

('data-index',2);

2.获取H5自定义属性

(1)('data-index')

(2)H5新增 ['index'] IE11才开始支持

2.5 节点操作

获取元素通常使用两种方式:

1.利用DOM提供的方法获取元素 2.利用节点层级关系获取元素
() 利用父子兄节点关系获取元素
() 逻辑性强,但是兼容性差
逻辑性不强,繁琐

节点概述

网页中的所有内容都是节点(标签、属性、文本、注释等)DOM中,节点使用node表示

一般,节点至少拥有nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)这三个基本属性

  • 元素节点 nodeType 为 1
  • 属性节点 nodeType 为 2
  • 文本节点 nodeType 为 3 (文本节点包含文字、空格、换行等)

在实际开发中,节点操作主要操作的是元素节点

节点层级

1. 父级节点

★★★

  • parentNode属性可返回某节点的父节点,注意是最近的一个父节点(亲爸爸)
  • 如果指定的节点没有父节点则返回null
<body>
    <div>我是div</div>
    <span>这是span</span>
    <ul>
        <li>这是li</li>
        <li>这是li</li>
        <li>这是li</li>
        <li>这是li</li>
    </ul>
    <div class="box">
        <span class="erweima">×</span>
    </div>
    <script>
        var erweima = document.querySelector('.erweima');
		// var box = ('.box');
        // (box);
        console.log(erweima.parentNode);
 		//得到的是离元素最近的父级节点,如果找不到父节点就返回null
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
2. 子节点

(标准)

  • 注意:返回值里面包含了所有的子节点,包括元素节点,文本节点,所以一般不提倡使用

(非标准)★★★

这是一个只读属性,返回所有的子元素节点,它只返回子元素节点,其他节点不返回

<script>
        //DOM提供的方法(API)获取
        var ul = document.querySelector('ul');
        // var lis = ('li');
        // (lis);
        //1.子节点()
        console.log(ul.childNodes);
        //处理办法,太麻烦了。所以一般不使用这种方法
        for (var i = 0; i < ul.childNodes.length; i++) {
            if (ul.childNodes[i].nodeType == 1) {
                console.log(ul.childNodes[i]);
            }
        }
        // 获取所有的子元素节点
        console.log(ul.children);                //HTMLCollection(4)
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

返回第一个子节点,不论是文本节点还是元素节点找不到则返回null,也是包含所有的节点

返回最后一个子节点,包含所有的节点,找不到则返回null

返回第一个子元素节点

返回最后一个子元素节点


总结如下:

(标准) 返回所有的子元素节点 返回值里面包含了所有的子节点,包括元素节点,文本节点,所以一般不提倡使用
★★★ (非标准) 这是一个只读属性,返回所有的子元素节点 它只返回子元素节点,其他节点不返回
返回第一个子节点,不论是文本节点还是元素节点找不到则返回null 包含所有的节点
返回最后一个子节点,不论是文本节点还是元素节点找不到则返回null 包含所有的节点
返回第一个子元素节点 有兼容性问题,IE 9以上才支持
返回最后一个子元素节点 有兼容性问题,IE 9以上才支持
<body>
    <ol>
        <li>这是li1</li>
        <li>这是li2</li>
        <li>这是li3</li>
        <li>这是li4</li>
    </ol>
    <script>
        var ol = document.querySelector('ol');
        console.log(ol.firstChild);               //#test
        console.log(ol.lastChild);                //#test
        console.log(ol.firstElementChild);        //<li>...</li>
        console.log(ol.lastElementChild);         //<li>...</li>
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

解决方案

 //3.实际开发中的写法,既没有兼容性问题又能返回第一个子元素
        console.log(ol.children[0]);
        console.log(ol.children[ol.children.length - 1]);
  • 1
  • 2
  • 3
3. 兄弟节点
返回当前元素的下一个兄弟节点,找不到则返回null 包含所有节点
返回当前元素的上一个兄弟节点,找不到则返回null 包含所有节点
返回当前元素的下一个兄弟元素节点,找不到则返回null 可以得到元素节点,但是有兼容性问题
返回当前元素的上一个兄弟元素节点,找不到则返回null 可以得到元素节点,但是有兼容性问题
<body>
    <div>这是div</div>
    <span>这是span</span>
    <script>
        var div = document.querySelector('div');
        console.log(div.nextSibling);             //#text
        console.log(div.previousSibling);         //#text
        console.log(div.nextElementSibling);      //<span>这是span</span>
        console.log(div.previousElementSibling);  //null
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

—如何解决兼容性问题?

—自己封装一个兼容性的函数

function getNextElementSibling(element){
    var el = element;
    while(el = el.nextSibling){
        if(el.bodeType === 1){
           return el
           }
    }
    return null;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
'
运行

创建节点

('tagName') 动态创建元素节点,只创建是不够的,因为没有添加进去,所以不会显示出来

添加节点

方法 作用
(child) 后面追加元素,类似于数组中的push 将一个节点添加到指定父节点的子节点列表字尾,类似CSS的 after 伪元素,node 是父级,child 是子级
(child,指定元素) 前面追加元素,类似于数组中的push
<body>
    <ul>
        <li>123</li>
    </ul>
    <script>
        //1.先创建节点
        var li = document.createElement('li');       // 没显示
        //2.然后从后面添加节点
        var ul = document.querySelector('ul');       
        ul.appendChild(li);                          // ●123
													 // ●
        //或 往前面添加节点
        var lili = document.createElement('li');
        ul.insertBefore(lili, ul.children[0]);       // ●
													 // ●123
													 // ●   
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

简单版发布留言案例 ✔

1.核心思路:点击发布按钮之后,就动态创建一个li,添加到ul里面

2.创建li的同时,把文本域里面的值通过赋值给li

3.如果想要新的留言后面显示就用appendChild,如果想在前面显示就用insertBefore

<body>
    <textarea name="" id="" cols="30" rows="10"></textarea>
    <button>发布</button>
    <ul></ul>

    <script>
        // 1.获取元素
        var text = document.querySelector('textarea');
        var btn = document.querySelector('button');
        var ul = document.querySelector('ul');
        // 2.注册事件
        btn.onclick = function () {
            if (text.value == '') {           // 必须是==,如果是=的话,既不弹出提示,也无法显示发布的内容
                alter('您没有输入内容');
                return false;
            } else {
                //(1)创建元素
                var li = document.createElement('li');
                // 先有li才能赋值
                li.innerHTML = text.value;
                //(2)往后面追加元素
                // (li);
                //从前面添加元素
                ul.insertBefore(li, ul.children[0])
            }

        }
    </script>
</body>
  • 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

删除节点

(child) node 是父亲,后面要删除的节点孩子的父亲


<body>
    <button>删除</button>
    <ul>
        <li>熊大</li>
        <li>熊二</li>
        <li>光头强</li>
    </ul>
    <script>
        //1.获取元素
        var ul = document.querySelector('ul');
        var btn = document.querySelector('button');
        //2.删除元素
        // ([0]);
        //3.点击删除按钮后依次删除ul的孩子
        btn.onclick = function () {
            if (ul.children.length == 0) {
                this.disabled = true;
            } else {
                ul.removeChild(ul.children[0]);
            }
        }
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

复制节点-浅拷贝/深拷贝★★★★★

() 返回调用该方法的节点的一个副本,也称为克隆节点/拷贝节点

浅拷贝 () 当括号里面为 空 或 false,只复制标签(节点本身)而不复制里面的内容(子节点)
深拷贝 (true) 括号内为 true,则复制标签以及里面的所有内容
<body>
    <ul>
        <li>125242</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
//1.浅拷贝
		var lili = ul.children[0].cloneNode();
        ul.appendChild(lili);                                          // ●125242
																	   // ●2
																	   // ●3
																	   // ●
                                       
//2.深拷贝
		var lili = ul.children[0].cloneNode(true);
        ul.appendChild(lili);                                          
																	   // ●125242
																	   // ●2
																	   // ●3
																	   // ●125242
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

阻止链接跳转的方法

"<a href='javascript:;'>删除</a>"

重点案例:动态生成表格★★★ ✔

案例分析:

① 因为里面的学生数据是动态的,我们需要JS动态生成,这里我们模拟数据,自己定义好数据,数据采用对象形式存储

② 所有的数据都是放到 tbody 的行里面

③ 因为行很多,所以需要循环创建多个行(对应的人数 数组的长度)

④ 每个行里面又有很多单元格(对应里面的数据),我们还是继续使用循环创建多个单元格,并且把数据存入里面(双重for循环)

⑤ 最后一列单元格是删除,需要单独创建单元格

复习:遍历对象
<script>

        var obj = {
            uname: 'pink老师',
            age: '18',
            sex: '男'
        }

        for (var k in obj) {
            console.log(obj[k]);
        }                                             //pink老师
												      //18
												      //男
        // k      得到的是属性名
        // obj[k] 得到的是属性值

</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

三种动态创建元素区别(面试可能问)

  • ()
  • ()

区别

三种动态创建元素的方法 特点
() 直接将内容写入页面的内容流,但是文档流执行完毕,再调用这句话,则会导致页面全部重绘,原来的内容全部没有了(一般很少使用) = function(){();} 整个页面加载完毕才开始执行JS,结果和上面一样
innerHTML 将内容写入某个DOM节点,不会导致页面全部重绘
innerHTML 与 createElement()哪个效率更高些?
innerHTML 创建多个元素效率更高(不是拼接字符串,而是采取数组形式拼接时),结构稍微复杂
createElement() 创建多个元素效率稍微低一点点,但是结构更加清晰

总结:不同浏览器下,innerHTML效率要比createElement高

2.6 DOM重点核心

什么是DOM?

DOM是文档对象模型,是W3C组织推荐的处理可扩展标记语言(HTML或XML)的标准编程接口

W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容,结构和样式。

  1. 对于JavaScript,为了能够使JavaScript操作HTML,JavaScript就有了一套自己的dom编程接口
  2. 对于HTML,dom使得html形成了一个dom树,包含文档,元素,节点(属性节点,文本节点)
  3. 我们通过DOM获取过来的DOM元素都是对象(Object),所以称为文档对象模型

关于dom操作,我们主要针对于元素的操作,主要有 创建、增、删、改、查、属性操作、事件操作

2.6.1 创建元素(三种方法)

  • innerHTML
  • createElement()

2.6.2 增 (两种方法)

  • appendChild 从后面增加
  • insertBefore 从前面增加

2.6.3 删(一种方法)

  • removeChild

2.6.4 改(很多方法)

主要是修改dom的元素属性,dom元素的内容、属性、表单的值等

  • 修改元素属性:srchreftitle
  • 修改普通元素内容:innerHTMLinnerText
  • 修改表单元素:valuetypedisabled
  • 修改元素样式:styleclassName

2.6.5 查

主要获取查询dom的元素

  • DOM提供的API方法:getElementByIdgetElementByTagName 古老用法不太推荐
  • H5提供的新方法:querySelectorquerySelectorAll 提倡用这种方法
  • 利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSiblingnextElementSibling) 提倡

2.6.6 属性操作

主要针对自定义属性

  • setAttribute :设置dom的属性值
  • getAttribute:得到dom的属性值
  • removeAttribute:移除属性

2.6.7 事件操作

给元素注册事件,采取 事件源.事件类型 = 事件处理程序

鼠标事件 触发条件
onclick 鼠标点击左键触发
onmouseover 鼠标经过触发
onmouseout 鼠标离开触发
onfocus 获得鼠标焦点触发
onblur 失去鼠标焦点触发
onmousemove 鼠标移动触发
onmouseup 鼠标弹起触发
onmousedown 鼠标按下触发

3. 事件高级

学习目标:

  • 能够写出元素注册事件的两种方式
  • 能够说出删除事件的两种方式
  • 能够说出DOM事件流的三个过程
  • 能够利用事件对象完成跟随鼠标案例
  • 能够封装阻止冒泡的兼容性函数
  • 能够说出事件委托的原理
  • 能够说出常用的鼠标和键盘事件

3.1 注册事件(绑定事件)

给元素添加事件称为注册事件或者绑定事件

有两种方式:

  • 传统注册方式
  • 方法监听注册方式

3.1.1 传统注册方式 / 方法监听注册方式

传统注册方式 方法监听注册方式
利用 on 开头的事件,例如 onclick W3C标准 推荐方式
<button onclick = "alert('hi~')"></button> **addEventListener() **它是一个方法,移动端使用很多
= function(){} 因为浏览器兼容性问题,也可以用attachEvent() 替换
特点: 特点:
注册事件的唯一性 同一个元素同一个事件可以注册多个监听器
同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数 按注册顺序依次执行

3.1.2 addEventListener 事件监听方式

(type,listener[,useCapture]) 将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数

该方法接收三个参数:
type 事件类型字符串,比如 click,mouseover 注意:不带on
listener 事件处理函数,事件发生时,会调用该监听函数
useCapture 可选参数,是一个布尔值默认是false,学完DOM事件流后,再进一步学习-> 事件冒泡
<body>
    <button>传统注册事件</button>
    <button>方法监听注册事件</button>
    <script>
        var btns = document.querySelectorAll('button');
        //一、传统方式 onclick
        btn[0].onclick = function () {
            alert('hi');
        }
        btn[0].onclick = function () {
            alert('how are you?');                  //唯一性,所以后一个会覆盖前一个,只能留一个
        }
        //二、addEventListener事件监听方式
        btns[1].addEventListener('click', function () {               //function(){}: 监听器/侦听器
            alert('要加引号且不加on');
        }) 
 		btns[1].addEventListener('click', function () {               //function(){}: 监听器/侦听器
            alert('可以添加多个监听器(事件处理程序)不会覆盖');
        })   
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

3.2 删除事件(解绑事件)

  • = null;

  • (type,fn)

<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <script>
        var divs = document.querySelectorAll('div');
        divs[0].onclick = function () {
            alert('哈哈');
            // 1.传统方式删除事件 
            divs[0].onclick = null;              // 解绑后不会再弹出alert了
        }

        divs[1].addEventListener('click', function () {             
            // 事件监听的方式绑定事件,但是要解除绑定的话就不能这么写了,得把function移出去
            alert('芜湖~');
        })

        // 2. removeEventListener 删除事件
        divs[2].addEventListener('click', fn)
        function fn() {
            alert('fn不需要调用加小括号');
            divs[2].removeEventListener('click', fn)
        }
    </script>
</body>
  • 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

3.3 DOM事件流

3.3.1 概念

  • 事件流描述的是从页面中接收事件的顺序

  • 事件发生时会在元素节点之间按照特定顺序传播,这个传播过程DOM事件流

3.3.2 代码验证

注意:

  • JS代码中只能执行捕获或者冒泡其中一个阶段
  • onclick 和 attachEvent(ie) 等传统事件只能得到冒泡阶段
  • 实际开发中更关注的是事件冒泡
  • 有些事件是没有冒泡的,比如 onblur , onfocus , onmouseenter , onmouseleave
  • 事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件

addEventListener(type,listener[,Capture])

  • 如果addEventListener 第三个参数是 true 那么则处于 捕获阶段 document -> html -> body -> father -> son
  • 如果addEventListener 第三个参数是 false 或 省略不写 那么则处于 冒泡阶段 son -> father -> body -> html -> document
<body>
    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
            			// 1.捕获阶段
        var son = document.querySelector('.son');
        son.addEventListener('click', function () {
            alert('再是son');
        }, true);

        var father = document.querySelector('.father');
        father.addEventListener('click', function () {
            alert('先是father');
        }, true);                       // 点击father区域,只弹出'是father'
										// 如果点击son盒子区域,先弹出'是father',点击确定后再弹出'是son'
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
<body>
    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
						// 2.冒泡阶段
        var son = document.querySelector('.son');
        son.addEventListener('click', function () {
            alert('先是son');
        });             // 第三个元素 false 或是 省略

        var father = document.querySelector('.father');
        father.addEventListener('click', function () {
            alert('再是father');
        });
        document.addEventListener('click', function () {
            alert('然后是document');
        })                       
						// 点击father区域,弹出'再是father',点击确定后弹出'然后是document'
						// 如果点击son盒子区域,弹出'先是son',点击确定后再弹出'再是father',最后弹出'然后是document'
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

3.4 事件对象★★★★★

3.4.1 什么是事件对象?

  • = function(event) {}
  • ('click',function(event) {})
  1. event 就是一个事件对象 写到我们侦听函数的 小括号里面 当形参来看
  2. 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数
  3. 事件对象 是 我们事件的一系列相关数据的集合 跟事件相关的 比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标啊,如果是键盘事件里面就包含的键盘事件的信息 比如 判断用户按下了那个键
  4. 这个事件对象我们可以自己命名 比如 event 、 evt、 e
  5. 事件对象也有兼容性问题 ie678 通过 兼容性的写法 e = e || ;
<body>
    <div>12345</div>
    <script>
        var div = document.querySelector('div');
        div.onclick = function (e) {
            console.log(e);                       // PointerEvent
            // ();
            // e = e || ;          // 考虑了兼容性
        }

        // ('click', function (e) {
        //     (e);
        // })                                      // PointerEvent
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

3.4.2 事件对象的常见属性和方法✔

事件对象属性方法 说明
1、 返回触发事件的对象 标准
返回触发事件的对象 非标准ie 6-8 使用
2、 返回事件的类型 比如 click mouseover 不带on
3、() 方法阻止默认事件(默认行为) dom标准
该属性阻止默认事件(默认行为) 非标准 ie6-8 比如不让链接跳转
4、() 方法阻止冒泡 标准
该属性阻止冒泡 非标准
1、 和 this 的区别
  • 返回触发事件的对象。点了什么返回什么

  • this 则是返回绑定事件的对象。哪个元素绑定了这个点击事件,就返回那个元素 curentTarget 约等于 this,有兼容性问题,不用

2、 返回事件类型
<script>
var div = document.querySelector('div');
        div.addEventListener('click', fn);
        // ('mouseover', fn);
        // ('mouseout', fn);
        function fn(e) {
            console.log(e.type);               // click
        }
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
3、阻止默认行为(事件)
  • () dom标记写法

只限于传统注册方式

  • 低版本浏览器适用
  • 在function(e) {return false;} 中使用 return false 也能阻止默认行为且没有兼容性问题

小结

方法/属性 适用的注册事件的方式 兼容性 说明
() 传统/监听注册都适用 不适用于低版本浏览器 是方法
只限于传统注册方式 ie6-8 是属性
function(e) {return false;} 只限于传统注册方式 没有兼容性问题 return后面的代码无法执行

3.5 阻止事件冒泡★★★★(面试常问)

事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点 div -> body -> html -> document

  • (); 方法

注意:如果点击son区域,弹出alert后点击确认,不再弹出其他内容;如果点击father区域,则仍然会继续冒泡

  • ; 适用于低版本浏览器
<body>
    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
        var son = document.querySelector('.son');
        son.addEventListener('click', function (e) {
            alert('son');
            e.stopPropagation();                              // 点击son区域,弹出alert后点击确认,不再弹出其他内容
        })
        var father = document.querySelector('.father');
        father.addEventListener('click', function () {
            alert('father');                                  // 如果点击father区域,则仍然会继续冒泡
        })
        document.addEventListener('click', function () {
            alert('document');
        })
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

3.6 事件委托(代理、委派)

3.6.1 事件委托的原理★★★★(面试常问✔)

要可以口述出来哦!

  • 不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点

案例:ul 下的很多 li

  • 给 ul 注册点击事件,然后利用事件对象的 target 来找到当前点击的 li ,因为点击 li ,事件会冒泡到 ul 上, ul 有注册事件,就会触发事件监听器

3.6.2 事件委托的作用

只操作一次DOM,提高了程序的性能

<body>
    <ul>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        // ('click', function (e) {
        //     // alert('知否知否,点我应有弹框在手!');
        //      = 'pink';
        // })

        for (var i = 0; i < ul.children.length; i++) {
            ul.addEventListener('click', function (e) {
                for (var i = 0; i < ul.children.length; i++) {
                    ul.children[i].style.backgroundColor = '';
                }
                e.target.style.backgroundColor = 'pink';
            })
        }

        // 排他思想(算法)
        
        // // 1. 获取所有按钮元素
        //     var btns = ('button');
        //     // btns得到的是伪数组  里面的每一个元素 btns[i]
        //     for (var i = 0; i < ; i++) {
        //         btns[i].onclick = function () {
        //             // (1) 我们先把所有的按钮背景颜色去掉  干掉所有人
        //             for (var i = 0; i < ; i++) {
        //                 btns[i]. = '';
        //             }
        //             // (2) 然后才让当前的元素背景颜色为pink 留下我自己
        //              = 'pink';

        //         }
        //     }
        // //2. 首先先排除其他人,然后才设置自己的样式 这种排除其他人的思想我们成为排他思想
    </script>
</body>
  • 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

3.7 常用的鼠标事件

1. 鼠标事件

  • 禁言鼠标右键菜单 addEventListener('contextmenu',)
  • 禁止鼠标选中文字 addEventListener('selectstart',)

2. 鼠标事件对象

鼠标事件对象 说明
返回鼠标相对于浏览器窗口可视区的X坐标
返回鼠标相对于浏览器窗口可视区的Y坐标
返回鼠标相对于文档页面的 X 坐标 IE9+ 支持 (用得较多)
返回鼠标相对于文档页面的 Y 坐标 IE9+ 支持(用得较多)
返回鼠标相对于电脑屏幕的 X 坐标
返回鼠标相对于电脑屏幕的 Y 坐标

3.8 常用的键盘事件

1. 键盘事件

键盘事件 触发条件:其实只要按下了键盘都能触发,如果一直按着非功能键不松开,keydown、 keypress事件一直被触发最后松开键盘触发keyup事件
某个键盘按键被松开时触发
某个键盘按键被按下时触发
某个键盘按键被按下时触发,但是它不识别功能键 比如:Ctrl shift 左右箭头等
  • 三个事件的执行顺序:keydown > keypress > keyup

2. 键盘事件对象

pink老师讲解的是keyCode,但是MDN已经将这个属性废弃了

现在直接使用key属性,按哪个键直接显示,以前keyCode返回的是ASCII值

keydown 和 keyup 不区分大小写, keypress区分大小写,实际开发中使用前两者较多

document.addEventListener('keyup', function (e) {
            // (e);
            console.log('up:' + e.key);
            if (e.key == 'a') {
                alert('按下了a')
            } 
        })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3. 模拟京东按键输入内容案例

<body>
    <input type="text">
    <script>
        var input = document.querySelector('input');
        document.addEventListener('keyup', function (e) {        // 这里最好是使用 keyup,因为它是键盘弹起时才触发
            										// 而 keydown 是按下键盘就触发事件,键盘输入的内容会显示在表单中
            if (e.key == 's') {
                input.focus();
            }
        })
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4. 模拟京东快递单号查询案例

案例分析

  • 快递单号输入内容时,上面的大号字体盒子(con)显示(里面的字体更大)
  • 表单检测用户输入:给表单添加键盘事件
  • 同时把快递单号里面的值(value)获取过来赋值给con盒子(innerText)作为内容
  • 如果快递单号里面的内容为空,则隐藏大号字体盒子(con)
  • 当我们失去焦点,就隐藏con盒子
  • 当我们获得焦点,并且文本框内容不为空,就显示这个con盒子

2. 键盘事件对象

pink老师讲解的是keyCode,但是MDN已经将这个属性废弃了

现在直接使用key属性,按哪个键直接显示,以前keyCode返回的是ASCII值

keydown 和 keyup 不区分大小写, keypress区分大小写,实际开发中使用前两者较多

document.addEventListener('keyup', function (e) {
            // (e);
            console.log('up:' + e.key);
            if (e.key == 'a') {
                alert('按下了a')
            } 
        })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3. 模拟京东按键输入内容案例

<body>
    <input type="text">
    <script>
        var input = document.querySelector('input');
        document.addEventListener('keyup', function (e) {        // 这里最好是使用 keyup,因为它是键盘弹起时才触发
            										// 而 keydown 是按下键盘就触发事件,键盘输入的内容会显示在表单中
            if (e.key == 's') {
                input.focus();
            }
        })
    </script>
</body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4. 模拟京东快递单号查询案例

案例分析

  • 快递单号输入内容时,上面的大号字体盒子(con)显示(里面的字体更大)
  • 表单检测用户输入:给表单添加键盘事件
  • 同时把快递单号里面的值(value)获取过来赋值给con盒子(innerText)作为内容
  • 如果快递单号里面的内容为空,则隐藏大号字体盒子(con)
  • 当我们失去焦点,就隐藏con盒子
  • 当我们获得焦点,并且文本框内容不为空,就显示这个con盒子

注意:keydown和keypress在文本框里面的特点:他们两个事件触发的时候,文字还没有落入文本框中,也就是说“慢半拍”