Bootstrap

速通JavaScript难点——DOM

DOM 这是核心部分

文档对象模型(DOM) 可以将 web 页面脚本或编程语言 连接起来

初识DOM
  1. web页面

这里的 web 页面,也就是之前我们用 HTML 和 CSS 绘制的页面,也称作为文档

  1. 脚本或编程语言 为什么这里不直接说将 Web 页面和 Javascript 语言连接起来,而要绕一下说脚本或编程语言呢?

因为 DOM 是一种规范,或者是一种约定,只要遵循这个规范,那么无论是 Javascript ,还是python ,或者 java 都可以被连接起来。

➤DOM映射:像HTML和xml文档都是树状结构,web网页最终会映射为一颗DOM树,DOM树连接js语言

DOM 树特性:(树)

  1. 树根是 DOCUMENT,也可以称为整个页面文档
  2. 每个 HTML 标签我们称之为 DOM 节点,英文为Node或者Element
  3. 每个 HTML 标签包裹的子标签,在树上体现为分支,称为儿子节点。比如上图,pH1 都是 div 的儿子节点。 div 同样也是 Body 的儿子节点。
  4. 儿子节点类推可以得知P,H1 是 Body 的孙子节点
  5. 所有PH1 的长辈,我们称为PH1 的祖先节点,
  6. PH1 是亲兄弟,我们称为兄弟节点。

Google插件可以帮助初学者理清网页中的DOM树
在这里插入图片描述

在这里插入图片描述

访问

DOCUMENT 元素会存在全局变量 window 下面

console.log(window.document);
//或者
document+敲回车

在这里插入图片描述

选择器查询 querySelector

document.querySelector(div);//从上往下第一个
document.querySelector('main .core .subtitle');

迭代查询

let subtitle = document.querySelector('main .core .subtitle');
let a = subtitle.querySelector("a");
console.log(a);

选择器全量查询 querySelectorAll()

document.querySelectorAll('input');

在浏览器的console里也可以通过get来查看当前页面的dom内容(用得不多)

document
document.getElementById
document.getElementByName
document.getElementByClassName
document.getElementByTagName
DOM属性
<!-- HTMLDocument 根文档 -->
<html>
  ……
</html>

<!-- HTMLDivElement DIV类型 -->
<div class="subtitle">
  ……
</div>

<!-- HTMLAnchorElement 超链接类型 -->
<a class="free-bright">免费靓号</a>

<!-- HTMLInputElement Input类型 -->
<input class="password" type="pasworkd" placeholder="请输入密码" />

每一种HTML标签都有一种DOM类型对应

对应MDN

  1. 元素节点
  2. 特性节点
  3. 文本节点
<!DOCTYPE html>
<head>
  <meta charset="UTF-8" />
  <title>标题</title>
</head>
<body>
  <div id="test"></div>
  <script src="./index.js"></script>
</body>
let divDom = document.querySelector('#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);
节点nodeTypenodeNamenodeValue类型
divDom1DIVnull元素节点
txtDom2#text标题文本节点
attDom3idtest特性节点
  1. 整个 HTML 中,无论是标签,标签属性,还是纯文本字符串都是 Element,不同的地方在于 nodeType 分别为 1,2,3
  2. HTML 标签都是元素节点,可以用nodeName 获取标签名称
  3. 纯文本都是文本节点,可以用 nodevalue 获取文本内容
  4. 标签的每个属性都是特性节点,可以用 nodeName取得属性Key,用 nodevalue 取得属性 Value
  5. attributes 可以获取元素节点的所有属性,得到的结果是一个字典,通过属性 Key 获取对应的特性节点。

DOM内容

<!DOCTYPE html>
<head>
  <meta charset="UTF-8" />
  <title>oageux</title>
</head>
<body>
  <div id="test">
    文本内容
    <p>第一个p标签</p>
    <p>第二个p标签</p>
  </div>
  <script src="./index.js"></script>
</body>
let divDom = document.querySelector('div#test');
console.log(divDom.outerHTML, divDom.innerHTML, divDom.innerText);
属性总结
outerHTML<div id="test">文本内容<p>第一个p标签</p><p>第二个p标签</p></div>整个DOM的HTML代码
innerHTML文本内容<p>第一个p标签</p><p>第二个p标签</p>DOM内部HTML代码
innerText文本内容DOM内部纯文本内容

DOM亲属

属性总结
firstChild文本内容指定节点的第一个子节点
lastChild<p>第二个p标签</p>指定节点的最后一个字节点
childNodes优课达<p>第一个p标签</p><p>第二个p标签</p>指定节点的子节点的集合
parentNode<body><div id="test">文本内容<p>第一个p标签</p><p>第二个p标签</p></div><script src="./index.js"></script></body>指定节点在DOM树中的父节点

DOM样式

<!DOCTYPE html>
<head>
  <meta charset="UTF-8" />
  <title>1234</title>
</head>
<body>
  <h1 class="oageux" style="color: #FF3300; font-size: 24px;">文本内容</h1>
  <script src="./index.js"></script>
</body>
const h1Dom = document.querySelector('h1');
console.log(h1Dom.classList);
console.log(h1Dom.style);
console.log(h1Dom.style.color);
属性类型总结
classListDOMTokenList类数组['test', 'youkeda']classList数组方式存储所有的class名称
styleCSSStyleDeclarationcolor属性为rgb(255, 51, 0)对象或字典的方法存储CSSStyle

也可以更改样式

let a = document.querySelector("title").style.color = "red";
DOM操作

通过前面的学习已经能用js完成网页的内容提取

接下来我们通过实战来理解这部分

大家想象一个图标,右上角有一个圈儿,点击可以选中,并√,再次点击可以取消√

<!DOCTYPE html>
<head>
  <meta charset="utf-8" />
  <link rel="stylesheet" type="text/css" href="./post.css" />
  <title>标题</title>
</head>
<body>
  <section class="box">
    <img
      class="java"
      src="对应图片路径"
    />
    <div class="title">Java</div>
    <div class="select"></div>//圆圈选择框
  </section>

  <script src="./post.js"></script>
</body>

我们可以在点击的时候,向 select 插入一个 img 节点,渲染选中的打钩图片。然后再次点击的时候清除 select 内部节点。

  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 = '√的图片';
    img.setAttribute('style', 'width: 100%; height: 100%;');

    // 将这个节点添加到select框中
    select.appendChild(img);
  } else {
    // 如果不是选择状态,则清空内部子元素
    select.innerHTML = '';
  }
});
  1. 创建标签节点
const div = document.createElement('div');
const txt = document.createTextNode('文本内容');
  1. 添加新节点
const div = document.createElement('div');
const txt = document.createTextNode('文本信息');
div.appendChild(txt);
document.body.appendChild(div);

appendChild(newNode):在所有儿子节点之后添加

inserBefore(newNode, referenceNode):在某个目标儿子节点之前添加

举个例子:在sars,添加H1N1,新型冠状病毒

<!DOCTYPE html>
<head>
  <meta charset="utf-8" />
  <title>标题</title>
</head>
<body>
  <ul class="root">
    <li class="sars">SARS</li>
  </ul>
  <script src="./index.js"></script>
</body>
const root = document.querySelector('ul.root');
const sars = document.querySelector('li.sars');

// 创建 H1N1
const H1N1 = document.createElement('li');
const H1N1Txt = document.createTextNode('H1N1');
H1N1.appendChild(H1N1Txt);
root.appendChild(H1N1);

// 创建 新型冠状病毒
const nCoV = document.createElement('li');
const nCoVTxt = document.createTextNode('新型冠状病毒');
nCoV.appendChild(nCoVTxt);
root.insertBefore(nCoV, sars);

最终顺序就是

<ul class="root">
  <li>新型冠状病毒</li>
  <li>SARS</li>
  <li>H1N1</li>
</ul>

思考:问题是重复的代码太多,如果添加100疾病呢?

答:我们可以使用函数来简化

function createDisease(txt) {
  const dom = document.createElement('li');
  const domTxt = document.createTextNode(txt);
  dom.appendChild(domTxt);
  return dom;
}

const root = document.querySelector('ul.root');
const sars = document.querySelector('li.sars');

// 创建 H1N1
const H1N1 = createDisease('H1N1');
root.appendChild(H1N1);

// 创建 新型冠状病毒
const nCoV = createDisease('新型冠状病毒');
root.insertBefore(nCoV, sars);
  1. 设置样式和属性
img.setAttribute('style', 'width: 100%; height: 100%;');

dom.style是一个Map对象,也可以单独设置属性

dom.style.color = 'xxxx';

classList

可以使用classList获取DOM所有类,进行add,remove,toggle,replace等等

MDN

  1. innerHTML

案例中用innerHTML = ''清空select节点所有的后代内容。

当然也可以给某个元素添加内容

function createDisease(txt) {
  const dom = document.createElement('li');

  // 我们可以直接用innerHTML设置其纯文本
  dom.innerHTML = txt;
    
  return dom;
}

OK,对DOM的认识,访问,属性和简单的操作就是以上部分,下一期我将发布剩下的比较难以理解的DOM操作,会以项目形式学习,敬请期待!

;