JavaScript高级程序设计(4)
第15章 DOM 扩展
### 5.1 Selectors API 445 ##### 15.1.1 **querySelector()** >querySelector()方法接收 CSS 选择符参数,返回匹配该模式的第一个后代元素,如果没有匹配项则返回 null。 ```javascript // 取得<body>元素 let body = document.querySelector("body"); // 取得 ID 为"myDiv"的元素 let myDiv = document.querySelector("#myDiv"); // 取得类名为"selected"的第一个元素 let selected = document.querySelector(".selected"); // 取得类名为"button"的图片 let img = document.body.querySelector("img.button"); ``` ##### 15.1.2 **querySelectorAll()** >法跟 querySelector()一样,也接收一个用于查询的参数,但它会返回所有匹配的节点,而不止一个。这个方法返回的是一个 NodeList 的静态实例。 ```javascript // 取得 ID 为"myDiv"的<div>元素中的所有<em>元素 let ems = document.getElementById("myDiv").querySelectorAll("em"); // 取得所有类名中包含"selected"的元素 let selecteds = document.querySelectorAll(".selected"); // 取得所有是<p>元素子元素的<strong>元素 let strongs = document.querySelectorAll("p strong"); //返回的 NodeList 对象可以通过 for-of 循环、item()方法或中括号语法取得个别元素。比如: let strongElements = document.querySelectorAll("p strong"); // 以下 3 个循环的效果一样 for (let strong of strongElements) { strong.className = "important"; } for (let i = 0; i < strongElements.length; ++i) { strongElements.item(i).className = "important"; } for (let i = 0; i < strongElements.length; ++i) { strongElements[i].className = "important"; } ``` ##### 15.1.3 **matches()** > matches()方法(在规范草案中称为 matchesSelector())接收一个 CSS 选择符参数,如果元素匹配则该选择符返回 true,否则返回 false。使用这个方法可以方便地检测某个元素会不会被 querySelector()或 querySelectorAll()方法返回。 ```javascript if (document.body.matches("body.page1")){ // true } ``` ### 15.2 元素遍历 447 ```javascript let parentElement = document.getElementById('parent'); let currentChildElement = parentElement.firstElementChild; // 没有子元素,firstElementChild 返回 null,跳过循环 while (currentChildElement) { // 这就是元素节点,做相应处理 processChild(currentChildElement); if (currentChildElement === parentElement.lastElementChild) { break; } currentChildElement = currentChildElement.nextElementSibling; } ``` ### 15.3 HTML5 448 ##### 15.3.1 CSS 类扩展 >**getElementsByClassName()** > >**classList** 属性 > >```javascript >// 取得所有类名中包含"username"和"current"元素 >let allCurrentUsernames = document.getElementsByClassName("username current"); > >// 取得 ID 为"myDiv"的元素子树中所有包含"selected"类的元素 >let selected = document.getElementById("myDiv").getElementsByClassName("selected"); > >// 删除"disabled"类 >div.classList.remove("disabled"); > >// 添加"current"类 >div.classList.add("current"); > >// 切换"user"类 >div.classList.toggle("user"); > >// 检测类名 >if (div.classList.contains("bd") && !div.classList.contains("disabled")){ >// 执行操作 >) > >// 迭代类名 >for (let class of div.classList){ >doStuff(class); >} >``` ##### 15.3.2 焦点管理 >- document.activeElement,始终包含当前拥有焦点的 DOM 元素。 > >- document.hasFocus()方法,该方法返回布尔值,表示文档是否拥有焦点. > >```javascript >let button = document.getElementById("myButton"); >button.focus(); >console.log(document.activeElement === button); // true >console.log(document.hasFocus()); // true >``` ##### 15.3.3 **HTMLDocument** 扩展 1. **readyState** 属性: 判断文档是否加载完毕。 >```javascript >if (document.readyState == "complete"){ >// 执行操作 >} >``` 2. **compatMode** 属性:判断浏览器当前处于什么渲染模式。标准模式"CSS1Compat",混杂模式 "BackCompat"。 >```javascript >if (document.compatMode == "CSS1Compat"){ >console.log("Standards mode"); >} else { >console.log("Quirks mode"); >} >``` 3. **head** 属性:指向文档的<head>元素。 >```javascript >let head = document.head; >``` ##### 15.3.4 字符集属性 >```javascript >console.log(document.characterSet); // "UTF-16" >document.characterSet = "UTF-8"; >``` ##### 15.3.5 自定义数据属性 >HTML5 允许给元素指定非标准的属性,但要使用前缀 data-以便告诉浏览器,这些属性既不包含与渲染有关的信息,也不包含元素的语义信息。 > >元素的每个 data-name 属性在 dataset 中都可以通过 data-后面的字符串作为键来访问。 > >```javascript ><div id="myDiv" data-appId="12345" data-myname="Nicholas"></div> > >// 有"myname"吗? >if (div.dataset.myname){ >console.log(`Hello, ${div.dataset.myname}`); >} >``` ##### 15.3.6 插入标记 1. **innerHTML** 属性 >```javascript >div.innerHTML = "Hello world!"; >div.innerHTML = "Hello & welcome, <b>\"reader\"!</b>"; >``` 2. **outerHTML** 属性 >```javascript >//新的<p>元素会取代 DOM 树中原来的<div>元素 >div.outerHTML = "<p>This is a paragraph.</p>"; >//到与执行以下脚本相同的结果: >let p = document.createElement("p"); >p.appendChild(document.createTextNode("This is a paragraph.")); >div.parentNode.replaceChild(p, div); >``` 3. **insertAdjacentHTML()**与 **insertAdjacentText()** > 这两个方法最早源自 IE,它们都接收两个参数:要插入标记的位置和要插入的 HTML 或文本。第一个参数必须是下列值中的一个: > > - "beforebegin",插入当前元素前面,作为前一个同胞节点; > - "afterbegin",插入当前元素内部,作为新的子节点或放在第一个子节点前面; > - "beforeend",插入当前元素内部,作为新的子节点或放在最后一个子节点后面; > - "afterend",插入当前元素后面,作为下一个同胞节点 > > ```javascript > // 作为前一个同胞节点插入 > element.insertAdjacentHTML("beforebegin", "<p>Hello world!</p>"); > element.insertAdjacentText("beforebegin", "Hello world!"); > > // 作为第一个子节点插入 > element.insertAdjacentHTML("afterbegin", "<p>Hello world!</p>"); > element.insertAdjacentText("afterbegin", "Hello world!"); > > // 作为最后一个子节点插入 > element.insertAdjacentHTML("beforeend", "<p>Hello world!</p>"); > element.insertAdjacentText("beforeend", "Hello world!"); > > // 作为下一个同胞节点插入 > element.insertAdjacentHTML("afterend", "<p>Hello world!</p>"); element. > insertAdjacentText("afterend", "Hello world!"); > ``` 4. 内存与性能问题 >一般来讲,插入大量的新 HTML 使用innerHTML 比使用多次 DOM 操作创建节点再插入来得更便捷。这是因为 HTML 解析器会解析设置给innerHTML(或 outerHTML)的值。解析器在浏览器中是底层代码(通常是 C++代码),比 JavaScript快得多。 5. 跨站点脚本 >如果页面中要使用用户提供的信息,则不建议使用 innerHTML。与使用 innerHTML 获得的方便相比,防止 XSS 攻击更让人头疼。此时一定要隔离要插入的数据,在插入页面前必须毫不犹豫地使用相关的库对它们进行转义。 ##### 15.3.7 **scrollIntoView()** >scrollIntoView()方法存在于所有 HTML 元素上,可以滚动浏览器窗口或容器元素以便包含元素进入视口。这个方法的参数如下: > >- alignToTop:true窗口滚动后元素的顶部与视口顶部对齐,false窗口滚动后元素的底部与视口底部对齐。 > >- scrollIntoViewOptions 是一个选项对象 > >- behavior:定义过渡动画,可取的值为"smooth"和"auto",默认为"auto"。 > >- block:定义垂直方向的对齐,可取的值为"start"、"center"、"end"和"nearest",默认为 "start"。 > >- inline:定义水平方 > >- 不传参数等同于 alignToTop 为 true。 > > ```javascript > // 确保元素可见 > document.forms[0].scrollIntoView(); > // 同上 > document.forms[0].scrollIntoView(true); > > document.forms[0].scrollIntoView({block: 'start'}); > // 尝试将元素平滑地滚入视口 > document.forms[0].scrollIntoView({behavior: 'smooth', block: 'start'}); > ``` ### 15.4 专有扩展 456 ##### 15.4.1 **children** 属性 >```javascript >let childCount = element.children.length; >let firstChild = element.children[0]; >``` ##### 15.4.2 **contains()**方法 >contains()方法应该在要搜索的祖先元素上调用,参数是待确定的目标节点。如果目标节点是被搜索节点的后代,contains()返回 true,否则返回 false。 > >```javascript >console.log(document.documentElement.contains(document.body)); // true >``` ##### 15.4.3 插入标记 > HTML5 将 IE 发明的 innerHTML 和 outerHTML 纳入了标准,但还有两个属性没有入选。这两个剩下的属性是 innerText 和 outerText。
顶部
收展
底部
[TOC]
目录
第1章 JavaScript简介
第2章 在 HTML中使用JavaScript
第3章 语言基础(1)语法变量
第3章 语言基础(2)数据类型
第3章 语言基础(3)操作符
第3章 语言基础(4)语句
第4章 变量、作用域与内存
第5章 基本引用类型
第6章 集合引用类型
第7章 迭代器与生成器
第8 章对象、类与面向对象编程
第9章 代理与反射
第10章 函数
第11章 期约与异步函数
第12章 BOM
第13章 客户端检测
第14章 DOM
第15章 DOM 扩展
第16章 DOM2 和 DOM3
第17章 事件
第18章 动画与 Canvas 图形
第19章 表单脚本
第20章 JavaScript API
第21章 错误处理与调试
第22章 处理 XML
第23章 JSON
第24章 网络请求与远程资源
第25章 客户端存储
第26章 模块
第27章 工作者线程
第28章 最佳实践
相关推荐
WebSocket