DOM(基础操作)(作为学习笔记)

1. 目标

  1. 能够说出什么是DOM
  2. 能够获取页面元素
  3. 能够给元素注册事件
  4. 能够操作DOM元素的属性
  5. 能够创建元素
  6. 能够操作DOM节点

2. DOM简介

2.1 什么是DOM呢?

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

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

2. DOM树

html 上面的标签时 document。document代表整个文档

在这里插入图片描述

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

DOM 把以上的内容都看作是对象

3. 获取元素

在实际开发中主要用来操作元素。

3.1 获取页面元素
3.1.1 根据 ID 获取
- 返回一个匹配特点 ID 的元素
- id是大小写敏感的字符串

栗子:

<body>
    <div id="time">2020-4-8</div>
    <script>
        // 1. 因为文档页面从上往下加载,所以得先有标签,所以我们script写到标签的下面
        // 2. 获得 元素 通过 id(翻译)驼峰命名法
        // 3. 参数 id 是大小写敏感的字符串,所以加引号。
        // 4. 返回的是一个元素对象
        div = document.getElementById("time");
        console.log(time);
        console.log(typeof(time));
        // 5. console.dir 打印我们返回的元素对象 更好的查看里面的属性与方法
        console.dir(time);
    </script>
</body>
3.1.2 根据标签名获取

使用 getElementByTagName() 方法可以返回带有指定标签名的对象集合。
栗子:

<body>
    <ul>
        <li>帅哥是我 我是帅哥1</li>
        <li>帅哥是我 我是帅哥2</li>
        <li>帅哥是我 我是帅哥3</li>
        <li>帅哥是我 我是帅哥4</li>
        <li>帅哥是我 我是帅哥5</li>
    </ul>
    <ul id="nav">
        <li>嘘!~ 禁止想象 1</li>
        <li>嘘!~ 禁止想象 2</li>
        <li>嘘!~ 禁止想象 3</li>
        <li>嘘!~ 禁止想象 4</li>
        <li>嘘!~ 禁止想象 5</li>
    </ul>
    <script>
        // 返回的是 获取过来元素对象的集合 以伪数组的形式存储
        var list = document.getElementsByTagName('li');
        console.dir(list);
        console.log(list[0]);

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

        // 3. element.getElementsByTagName() 可以得到这个元素里面的某个标签
        var nav = document.getElementById('nav'); //可以获得 nav 元素
        var navList = nav.getElementsByTagName('li');
        console.dir(navList);
    </script>
</body>
3. 通过 HTML5 新增的方法获取
  1. getElementsByClassName(‘类名’)
  2. querySelctor( )
  3. querySelctorAll( )
    栗子:
<body>
    <div class="box">盒子1</div>
    <div class="box">盒子2</div>
    <div id="nav">
        <ul>
            <li>首页</li>
            <li>产品</li>
        </ul>
    </div>
    <script>
        // 1. getElementsByClassName('类名') 根据类名返回元素对象集合
        var box = document.getElementsByClassName('box');
        console.log(box);
        // 2. querySelctor 返回选择器的第一个元素对象
        var firstBox = document.querySelector('.box');
        console.log(firstBox);

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

        var li = document.querySelector('li');
        console.log(li);

        // 3. querySelctorAll() 返回指定选择器的所有对象集合
        var allBox = document.querySelectorAll('.box');
        console.log(allBox);

        var lis = document.querySelectorAll('li');
        console.log((lis));
    </script>
</body>
4. 特殊元素获取
<body>
    <script>
        /* 获取body */
        var bodyEle = document.body;
        console.log(bodyEle);
        /* 获取html */
        var htmlEle = document.documentElement;
        console.log(htmlEle);
    </script>
</body>

4. 事件基础

JavaScript使我们有能力创建动态页面事件是可以被JavaScript侦测到的行为。
简单理解:触发—响应机制。

网页中的每个元素都可以产生某些可以触发 JavaScript的事件,例如,我们可以在用户点击某按钮是产生一个事件,然后去执行某些操作。
在这里插入图片描述

栗子:唐伯虎点秋香

<body>
    <button id="btn">唐伯虎</button>
    <script>
        // 点击一个按钮,弹出对话框
        // 1. 事件是有三部分组成 事件源 事件类型 事件处理程序 我们也称为事件三要素
        //  (1) 事件源 事件被触发的对象 谁 按钮
        var btn = document.getElementById('btn');
        //  (2) 事件类型 如何触发 什么事件 比如鼠标点击(onclick) 还是鼠标经过 还是键盘按下
        //  (3) 事件处理程序 通过一个函数赋值的方式 完成
        btn.onclick = function() {
            alert('点秋香');
        }
    </script>
</body>
执行事件的步骤
  1. 获取事件源
  2. 注册事件(绑定事件)
  3. 添加事件处理程序(采取函数赋值的形式)

常见鼠标事件

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

栗子:

<body>
    <div>123</div>
    <script>
        //执行事件步骤
        //点击 div 控制台输出 我被选中了
        // 1. 获取事件源
        var div = document.querySelector('div');
        // 2. 绑定事件 注册事件
        // div.onclick
        // 3. 添加事件处理程序
        div.onclick = function() {
            console.log('我被选中了');
        }
    </script>
</body>

5. 操作元素

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

5.1 改变元素内容
	element.innerText

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

	element.innerHtml
  1. 栗子一:显示当前时间

  2. 栗子二:
    二者区别:

<body>
    <div></div>
    <p>
        我是文字
        <span>123</span>
    </p>
    <script>
        // innerText 和 innerHTML 的区别
        // 1. innerText 不识别 html标签 非标准
        // var div = document.querySelector('div');
        // div.innerText = "<strong>最帅</strong>是我";

        // 2. innerHTML 识别 html 标签 W3C 标准
        // div.innerHTML = "<strong>最帅</strong>是我";

        // 这两个属性是可读写的 可以获取元素里面的内容
        // var p = document.querySelector('p');
        // console.log(p.innerText);
        // console.log(p.innerHTML);
    </script>
</body>

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

5.2 改变元素属性

再来个栗子:
通过不同时间得到不同的问候语

<body>
    <img src="" alt="">
    <div>上午好</div>
    <script>
        // 1. 获取元素
        var img = document.querySelector('img');
        var div = document.querySelector('div');
        // 2. 获取当前小时数
        var date = new Date();
        var h = date.getHours();
        console.log(h);

        // 3. 判断小时数
        switch (true) {
            case h < 12:
                img.src = "morning.jpg"
                div.innerHTML = '亲!早上好';
                break;
            case h > 12 && h < 17:
                img.src = "afternoon.jpg"
                div.innerHTML = '亲!下午好';
                break;
            default:
                img.src = "night.jpg"
                div.innerHTML = '亲!晚上好';
                break;
        }
    </script>
</body>
5.3 表单元素的属性操作

type, value, checked, selected, disabled(禁用按钮)

表单里面的值是通过value来变化的

  1. 三个栗子(important!!!):1. 点击 input 的 value 变化 2. 点击按钮禁用 3. 密码的明文和暗码
5.4 样式属性操作

我们可以通过 js 修改元素的大小,颜色,位置等样式

方法作用
element.style行内样式操作如果说样式比较少 或者 功能简单的情况下使用
element.className类名样式操作 如果说样式比较多或者功能比较复杂那么就用这个(更好的分离样式与行为

注:

  • js里面的样式采用驼峰命名法 比如 fontSize, backgroundColor
  • js 修改 style 样式操作,产生的是行内样式, 权重高。
  1. 栗子1( element.style ):隐藏文本框的内容
    当鼠标点击文本框的时候,里面的默认文字隐藏,当鼠标离开文本框时,里面的文字显示。

  2. 栗子2( element.className ):改变class名

    • 如果样式修改较多,可以采取操作类名方式更改元素样式
    • class是个保留字,因此使用className来操作元素类名属性
    • className会直接更改元素的类名,会覆盖原先的类名 所以要加新的类名要把原先的写上
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div {
            width: 200px;
            height: 200px;
            color: saddlebrown;
            background-color: red;
        }
        
        .change {
            margin: 20px;
            color: silver;
            background-color: royalblue;
        }
    </style>
</head>

<body>
    <div>我是帅哥</div>
    <script>
        var div = document.getElementsByTagName('div');
        div[0].onclick = function() {
            this.className = 'change';
        }
    </script>
</body>

</html>
  1. 栗子3:密码较短提示信息
5.5 排他思想

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

  • 所有元素清空样式(干掉其他人)
  • 给当前元素设置样式(留下我自己)
  • 注意顺序不能颠倒,首先干掉其他人,在设置自己
  1. 栗子1:按钮点击变色

  2. 栗子2:换皮肤

    • 给一组元素注册事件
    • 点击后页面背景变化
  3. 栗子3:鼠标经过变色

  4. 栗子4:全选和取消全选

5.5 自定义属性的操作
获取方法不同点
element.属性只能获得内置的属性(元素本身自带的)
element.getAttribute(‘属性’)主要获得自定义的属性(标准)
5.5 设置属性值
设置方法不同点
element.属性 = ‘属性值’内置的属性
element.setAttribute(‘属性’, ‘属性值’)自定义属性

注:class比较特殊element.setAttribute('class', '啥啥啥')记住不是className。

5.6 移除属性

element.removeAttribute('属性');

5.7 H5自定义属性
一:
  1. 自定义属性的目的:是为了保存并使用数据,有些数据可以保存到页面中而不用保存到数据库
  1. 自定义属性是通过getAttribute(‘属性’)获取。
  1. 但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性

注: 为了解决上述问题我们在设置自定义属性的时候以 data- 开头作为属性名并赋值
例:<div data-index = "1"><div>

二:
  1. js 添加自定义属性及属性值:

    • element.setAttribute('属性', '啥啥啥') = ‘啥啥啥’
  2. js 获取自定义属性值:

    • element.getAttribute('属性')(兼容性获取方法)
    • element.dataset.自定义属性名(H5新增方法)
    • element.dataset['自定义属性名'](H5新增方法)
    • 注:如果自定义属性中有多个 "- " 链接的单词, 我们获取的时候采取的是 驼峰命名法

栗子(important):

<body>
    <div getTime='20' data-index='2' data-list-name="andy"> </div>
    <script>
        var div = document.querySelector('div');
        console.log(div.getAttribute('getTime')); /* 传统获取方法 */
        div.setAttribute('data-time', 20); /* 传统添加方式 */

        console.log(div.getAttribute('data-index')); /* H5新增命名方法 */
        console.log(div.getAttribute('data-list-name'));

        /* h5新增的获取自定义属性的方法, 只能获取 data- 开头的自定义属性 ie 11才开始识别*/
        /* dataset是一个集合里面存放了所有以data开头的自定义属性 */
        console.log(div.dataset); /* 所有的自定义属性都存放在里面 */
        console.log(div.dataset.index); /* 和对象的用法一样,直接提取即可 */
        console.log(div.dataset['index']); /* 第二种方法提取 */

        /*  如果自定义属性中有多个 " - " 链接的单词, 我们获取的时候采取的是 驼峰命名法*/
        console.log(div.dataset.listName);
        console.log(div.dataset['listName']);
    </script>
</body>

6. 节点操作

6.1 为啥学习节点操作
利用DOM提供的方法获取元素利用节点的层级关系获取元素
document.getElementById()1. 利用利用 父 子 兄 节点关系获取元素
document.getElementByTagName()
document.querySelector等
逻辑性不强,繁琐逻辑性强,操作简单,但是兼容性差,

在这里插入图片描述

6.2 节点概述

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

  • 元素节点 nodeType 为1
  • 属性节点 nodeType 为2
  • 文本节点 nodeType 为3(文本节点包含文字,空格,换行等)
  • 注:我们在实际开发中,节点操作的是元素节点
6.3 节点层级

利用 DOM 树可以把节点划分为不同的层级关系,常见的是 父 子 兄 的层级关系间 DOM 树

6.3.1 父节点获取(element.parentNode)

栗子(important):

<body>
    <div class="box">
        <span class="erweima"></span>
    </div>
    <script>
        /* 1. 父节点 parentNode */
        var erweima = document.querySelector('.erweima');
        /* 2. 得到的是离元素最近的父节点,如果找不到就返回空 */
        console.log(erweima.parentNode);
    </script>
</body>
6.3.2 子节点获取(element.childNodes)
  1. parentNode.childNodes (标准)

parentNode.childNodes返回包含指定节点的子元素的集合,该集合为即时更新的集合
注意:

  1. 返回值里面包含了所有的子节点,包括元素节点,文本节点等
  2. 如果只想要获得里面的元素节点,则需要专门处理,所以我们一般不提倡使用childNodes
  3. 如果非要用那么要加一个条件判断(利用 元素节点 nodeType 为1这一性质)
<body>
    <ul>
        <li>我很帅</li>
        <li>我很帅</li>
        <li>我很帅</li>
        <li>我很帅</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        for (var i = 0; i < ul.childNodes.length; i++) {
            if (ul.childNodes[i].nodeType == 1) {
                    // ul.childNodes[i] 是元素节点
                    console.log(ul.childNodes[i]);
            }
        }
    </script>
</body>
  1. parentNode.children (非标准) (庶出)但是却被广泛的应用(各个浏览器都支持)
<body>
    <ul>
        <li>我很帅</li>
        <li>我很帅</li>
        <li>我很帅</li>
        <li>我很帅</li>
    </ul>
    <script>
        /* DOM提供的方法 (API) 获取 */
            var ul = document.querySelector('ul');
            var lis = ul.querySelectorAll('li');
        /* 1. 子节点 childNodes 所有的子节点 包含 元素节点 文本节点等等 */
            console.log(ul.childNodes);
            console.log(ul.childNodes[0].nodeType);
            console.log(ul.childNodes[1].nodeType);
        /* 2. children 获取所有的子元素节点 也是实际开发中常用的 */
            console.log(ul.children);
    </script>
</body>
6.3.3 第一个和最后一个子节点的获取
  1. element.firstChild :第一个子节点 不管是文本节点还是元素节点
  1. element.lastChild:同理
  1. element.firstElementChild :返回第一个子元素节点,找不到返回null
  1. element.lastElementChild : 同理

注:3 4 种方法有兼容性问题,IE9 以上才支持

实际开发的写法 既没有兼容性问题又返回第一个子元素 : console.log(ul.children[0]);

实际开发的写法 既没有兼容性问题又返回最后一个子元素 : console.log(ul.children[ul.children.length -1]);

栗子:

<body>
    <ul>
        <li>我很帅1</li>
        <li>我很帅2</li>
        <li>我很帅3</li>
        <li>我很帅4</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        /* firstChild 第一个子节点 不管是文本节点还是元素节点 */
        console.log(ul.firstChild);
        /* 同上 */
        console.log(ul.lastChild);

        /* firstElementChild 返回第一个子元素节点,找不到返回null*/
        console.log(ul.firstElementChild);
        /* lastElementChild 返回最后一个子元素节点,找不到返回null*/
        console.log(ul.lastElementChild);

        /* 实际开发的写法 既没有兼容性问题又返回第一个子元素 */
        console.log(ul.children[0]);
        /* 实际开发的写法 既没有兼容性问题又返回最后一个子元素 */
        console.log(ul.children[ul.children.length - 1]);
    </script>
</body>
6.3.4兄弟节点
  1. node.nextSibling : 返回下一个兄弟节点,找不到返回null,包含所有的节点
  1. node.previousSibling : 返回上一个兄弟节点,找不到返回null,包含所有的节点
  1. node.nextElementSibling : 返回当前元素下一个兄弟节点(元素节点),找不到则返回null
  1. node.previousElementSibling : 返回当前元素上一个兄弟节点(元素节点),找不到则返回null

注:3 4 种方法有兼容性问题,IE9 以上才支持

栗子:

<body>
    <div>我是div</div>
    <span>我是span</span>
    <script>
        var div = document.querySelector('div');
        /* 得到了文本节点,下一个兄弟节点 包含元素节点或者文本节点等等*/
        console.log(div.nextSibling);
        /* 得到了文本节点,上一个兄弟节点 包含元素节点或者文本节点等等*/
        console.log(div.previousSibling);
        console.log(div.nextElementSibling);
        console.log(div.previousElementSibling);
    </script>
</body>
6.4 创建节点,添加节点
  1. document.createElement(‘element’) : 创建一个元素
  1. 父级.appendChild(变量); : 添加在后面
  1. 父级.insertBefore(变量, 父级.children[0]) : 传入变量,和要插入的位置
<body>
    <ul>
        <li>123</li>
    </ul>
    <script>
        /* 1. 创建节点元素 */
        var li = document.createElement('li');
        /* 2. 添加节点 node.appendChild(child) node 父级 child 子级 后面追加元素  类似于数组中的push */
        var ul = document.querySelector('ul');
        ul.appendChild(li);
        /* 3. 添加节点 node.insertBefore(child, 指定元素); */
        var lili = document.createElement('li');
        ul.insertBefore(lili, ul.children[0]);
        /* 4. 我们想要页面添加一个新的元素: 1. 创建元素  2. 添加元素 */
    </script>
</body>

栗子

  1. 模拟留言板(js小案例)
6.5 删除节点

node.removeChild(child):DOM 中删除一个子节点,删除一个子节点,返回删除的节点

<body>
    <button>delate</button>
    <ul>
        <li>熊大</li>
        <li>熊二</li>
        <li>光头强</li>
    </ul>
    <script>
        // 1. 获取元素
        var ul = document.querySelector('ul');
        var btn = document.querySelector('button');
        // 2. 删除元素

        // 3. 点击依次删除
        btn.onclick = function() {
            // if(ul.children.length == 0){
            //     this.disabled = true;
            // }
            for (var i = 0; i < ul.children.length; i++) {
                ul.removeChild(ul.children[0]);
            }
        }
    </script>
</body>

阻止链接跳转添加javascript:void(0);或者javascript:;

栗子

  1. 动态生成表格(js小案例)
6.6 复制节点(克隆节点)

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

注意:

  1. 如果括号参数为空或者为false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        var lili = ul.children[0].cloneNode(true);
        ul.insertBefore(lili, ul.children[0]);
    </script>
</body>
6.7 三种动态创建元素的区别
  1. https://blog.csdn.net/weixin_45773503/article/details/105945722

总结

  1. DOM核心总结
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值