1. 一、初识 DOM<br />文档对象模型,Document Object Model <br />1.1 web 页面<br />这里的web 页面,也就是之前我们用HTML CSS 绘制的页面,也称为文档

    1.2 脚本或编程语言
    因为 DOM 是一种规范,或者是一种约定,只要遵循这个规范,无论是Javascript,还是python,或者java 都可以被连接起来。

    1.3 DOM 映射
    我们总结一下DOM 树特性
    1、树根是DOCUMENT,也可以称为整个页面文档
    2、每个 HTML 标签我们称之为DOM 节点,英文为Node 或者 Element
    3、每个HTML 标签包裹的自标签,在树上体现为分支,称为儿子节点。
    4、儿子节点类推可以得知p, H1 是 BODY 的孙子节点
    5、所以p 、H1 的长辈,我们称为 P 和 H1 的祖先节点
    6、P、H1 是亲兄弟,我们称为兄弟节点。
    图片.png
    二、访问DOM
    2.1 获取 DOCUMENT
    web 网页最终会映射为一棵DOM 树,DOM 树连接网页和Javascript 语言。
    我们如何获取DOM 数的根部元素呢?
    DOCUMENT 元素会存在全局变量window 下面,我们可以通过如下代码来访问:
    window.document

    window.document 得到的是一个HTMLDocument 对象,这个对象内容有点多,大家不需要全部了解,只需要看几个属性即可,比如document 内容 key 为 documentElement;

    2.2 选择器查询

    选择器查询方法 —- querySelector()

    完整的代码为:document.querySelector(‘main .core .subtitle’);

    2.3 迭代查询
    当我们得到subtitle 元素后,我们还可以利用这个元素,继续筛选器内部元素,比如我们想筛选器内部的a 标签,我们可以继续完善代码:
    let subtitle = document.querySelector(‘main .core .subtitle’);
    console.log(subtitle.querySelector(‘a’));

    2.4 选择器全量查询
    querySelectorAll()

    document.querySelectorAll(‘input’);

    2.5 其他筛选方法
    querySelector 和 querySelectorAll 是最新提出的方法

    getElementById():根据id 查询某个节点
    getElementsByClassName():根据class 查询多个节点
    getElementsByTagName():根据标签名查询多个节点

    两者的区别:querySelector 查询出来的元素是拷贝的原始数据,不会再随着页面 DOM 节点的改变而变化get 系列方法查询出来的元素就是原始数据,所以会随着页面的DOM 节点的改变而变化。

    大部分都是用querySelector(All)

    三、DOM 属性
    3.1 DOM 种类
    https://developer.mozilla.org/zh-CN/docs/Web/API
    在页面中搜索 Element
    3.2 DOM 属性
    DOM 类型
    在上面我们看到很多DOM 种类,但可以归纳为几个类别:
    1、元素节点
    2、特性节点
    3、文本节点
    4、…… 其他类别不重要,忽略
    图片.png
    let divDom = document.querySelector(‘div#test’);
    console.log(divDom.nodeType, divDom.nodeName, divDom.nodeValue); // 获取DIV节点的第一个儿子节点,代表 ‘优课达’ 这个字符串
    let txtDom = divDom.firstChild;
    console.log(txtDom.nodeType, txtDom.nodeName, txtDom.nodeValue); // 获取DIV节点的id属性 let attDom = divDom.attributes.id;
    console.log(attDom.nodeType, attDom.nodeName, attDom.nodeValue);
    图片.png
    图片.png
    3.3 DOM 内容
    图片.png
    let divDom = document.querySelector(‘div#test’);
    console.log(divDom.outerHTML, divDom.innerHTML, divDom.innerText);
    图片.png

    3.4 DOM 亲属
    在上面我们知道可以利用firstChild 属性获取到元素的第一个儿子节点。那么还能获取哪些其他亲属呢?
    let divDom = document.querySelector(‘div#test’);
    console.log(divDom.firstChild, divDom.lastChild);
    console.log(‘—————-‘);
    console.log(divDom.childNodes);
    console.log(‘—————-‘);
    console.log(divDom.parentNode);

    图片.png
    3.5 DOM 样式
    通过DOM,我们同样可以访问到其CSS 特性
    <!DOCTYPE html>





    优课达



    图片.png
    图片.png

    3.6 DOM 数据属性
    网页设计的初衷是数据和特定的HTML 标签相关联。
    HTML 提供一种数据属性的标准,利用data- 允许我们在标准内于HTML 元素中存储额外的信息。
    <!DOCTYPE html>










    对文章而言,除了文章内容,我们还有其他额外数据,例如:段落、字数、分类,etc… 那这些额外数据我们就可以利用data-
    来存储。

    那我们该怎么通过JS 来获取呢? 按上面的推理,肯定也存在 DOM 的某个属性中
    const article = documment.querySelector(‘article’);
    console.log(article.dataset);

    从结果可以看出,dataset 是个 Map 对象,它是data- 这个 的 Key-Value 集合。

    3.7 总结
    记住大概意思

    四、DOM 操作(一)
    4.1 DOM 样式修改
    思考以下问题:
    1、如何使用 Javascript 创建节点?(在这里创建 img 节点)
    2、如何设置节点的样式、属性?(img 节点设置 src 属性)
    3、如何在已存在节点内部添加子节点?(img 节点需要添加到 select 中)
    4、如何清空节点内部子节点?(再次点击时清空 select 的子节点)

    // 保存当前是否选中的状态
    let isSelected = false;
    // 获取整个元素的节点
    const box = document.querySelector(‘.box’);
    // 获取select框节点
    const select = document.querySelector(‘.select’);
    // 给整个元素添加点击事件【大家可以先忽略这部分】
    box.addEventListener(‘click’, function () {
    // 点击以后触发这个函数
    // 修改当前选中状态,取反即可
    isSelected = !isSelected;
    // 如果当前是选中状态、则添加img到select中
    if (isSelected) {
    // 创建一个img标签节点
    const img = document.createElement(‘img’);
    // 设置img的src属性和样式,让其撑满select框
    img.src = ‘https://style.youkeda.com/img/sandwich/check.png‘; img.setAttribute(‘style’, ‘width: 100%; height: 100%;’); // 将这个节点添加到select框中 select.appendChild(img);
    } else {
    // 如果不是选择状态,则清空内部子元素
    select.innerHTML = ‘’;
    }
    });

    1、创建标签节点
    document.createElement(tagName)
    此方法用于创建一个由标签名称tagName 指定的 HTML 元素,也就是上节课提到的元素(标签)节点。

    如果想创建一个div 标签,我们可以使用:
    const div = document.createElement(‘div’);

    document.createTextNode(string)
    如果想继续在这个div 标签内部,添加纯文本,可以继续使用创建文本方法document.createTextNode(),代码如下:
    const div = document.createElement(‘div’);
    const txt = document.createTextNode(‘优课达-学的比别人好一点’);

    我们继续把txt 添加到div 中,把div 添加到body 中,代码如下:
    const div = document.createElement(‘div’);
    const txt = document.createTextNode(‘优课达-学的比别人好一点’);
    div.appendChild(txt);
    document.body.appendChild(div);

    2、添加新节点
    appendChild(newNode)
    在上面的案例中,我们多次用到appendChild(),此方法可以往该节点中插入儿子节点。

    insertBefore(newNode, referenceNode)
    此方法和 appendChild() 刚好相反,appendChild 是在所有儿子节点之后添加,insertBefore 是在某个目标儿子节点之前添加。

    insertBefore(newNode , referenceNode),需要两个参数,newNode 表示新节点, referenceNode 表示目标节点,也就是新节点插入到目标节点之前。

    我们来看一个例子:
    图片.png
    图片.png
    图片.png
    那如果我们想添加100 个疾病节点,那么该怎么办呢?
    我们来修改这下这个代码
    图片.png
    3、设置样式、属性
    在上面,我们通过如下代码设置CSS 样式,这个和直接在HTML 代码中写style 语法一样。
    img.setAttribute(‘style’ , ‘width: 100% ; height: 100%’);

    上节课我们知道dom.style 是一个Map 对象,因此如果我们不想全量替换样式,我们还可以单独设置某些属性,如下代码:
    dom.style.color = ‘xxxx’;
    setAttribute()不仅仅可以设置style 之外,所有HTML 属性都能用他设置,比如 id, src, type, disabled, etc…….

    classList 参考文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Element/classList

    4、innerHTML
    在案例中,我们使用 innerHTML = ‘ ‘ 清空 select 节点所有的后代内容。

    图片.png
    五、DOM 操作(二)
    5.1 我们先来看个例子
    简单的百度搜索
    分解下页面开发步骤:
    1、首先,我们在不考虑鼠标交互的情况下,完成静态HTML 页面
    2、监听搜索框 Input 输入事件(这部分代码内置)
    3、当输入内容是肺炎时,显示模糊搜索结果
    4、当输入内容不是肺炎时,显示登录查看历史

    开发静态 HTML 页面
    图片.png
    监听Input 输入事件,处理区域显示隐藏
    图片.png

    监听输入肺炎时,显示肺炎查询结果
    首先我们修改CSS 将登录查看历史设置可见,将搜索结果设置不可见
    main .search-result {
    padding : 0;
    display: none;
    }

    接着修改Javascript 代码,动态控制显示和隐藏如下:
    图片.png
    肺炎搜索结果动态显示
    这部分数据是由 Javascript 发起网络请求返回数据,然后利用动态生成节点的方法插入页面。
    图片.png
    我们封装一个函数,用于生成这个 li DOM 节点,代码如下:
    function createSearchItem(txt) {
    const item = document.createElement(‘li’);
    item.innerHTML = <i class="search"></i><p>${txt}</p><i class="edit"></i>; return item;
    }
    在这里我们使用 innerHTML 和 模板字符串 快速创建 li 内容。
    最后我们需要遍历搜索结果数据数组,依次创建 li ,并插入到页面中,代码如下:
    let data = [
    肺炎实时疫情动态’,
    肺炎的症状有哪些症状’,
    肺炎武汉’,
    肺炎症状’,
    肺炎最新’,
    肺炎是怎么引起的’,
    肺炎最新消息’,
    肺炎实时’,
    肺炎症状及表现’,
    肺炎最新情况’
    ];
    function createSearchItem(txt) {
    const item = document.createElement(‘li’);
    item.innerHTML = <i class="search"></i><p>${txt}</p><i class="edit"></i>; return item;
    }
    const input = document.querySelector(‘input’);

    const login = document.querySelector(‘.login’);
    const searchResult = document.querySelector(‘.search-result’); // 监听键盘事件 input.addEventListener(‘keyup’, function() {
    // this 是DOM节点,this.value可以获取input内输入的值
    if (this.value === ‘肺炎’) {
    // 先把原始内容清空
    searchResult.innerHTML = ‘’;
    for (let i = 0; i < data.length; i++) { searchResult.appendChild(createSearchItem(data[i]));
    }
    login.style.display = ‘none’;
    searchResult.style.display = ‘block’;
    } else {
    login.style.display = ‘block’;
    searchResult.style.display = ‘none’;
    }
    });

    总结
    我们总结下本节课的解决思路:
    首先我们在不考虑动态效果情况下,把页面中涉及到的所有元素都用静态页面的形式写出来
    其次利用Javascript 控制区域的显示和隐藏,达到动态效果。
    最后根据写好的静态页面模板和数据,动态创建哎DOM 节点。