DOM/BOM 及事件处理机制
开始总结这一部分之前,我们需要了解Web API阶段与JavaScript语法阶段的关联性
知道什么是API,什么是Web API
JS的组成: ECMAScript DOM BOM
API:是给程序员提供的一种工具,以便能轻松实现想要完成的功能,eg手机充电接口就是一个API
Web API
是浏览器
提供一套操作浏览器功能
和页面元素
的API
(BOM和DOM)
比如我们想要浏览器弹出一个警示框,直接使用alert('弹出')
一 DOM/BOM核心操作
DOM
-
什么是DOM
1. 什么是window? window:是一个全局对象, 代表浏览器中一个打开的窗口, 每个窗口都是一个window对象 2. 什么是document? document是window的一个属性, 这个属性是一个对象 document: 代表当前窗口中的整个网页, document对象保存了网页上所有的内容, 通过document对象就可以操作网页上的内容 3. 什么是DOM? DOM 定义了访问和操作 HTML文档(网页)的标准方法 DOM全称: `Document Object Model`, 即文档模型对象 所以学习DOM就是学习如何通过document对象操作网页上的内容
-
如何获取页面元素
- 通过id获取指定元素
由于id不可以重复, 所以找到了就会将找到的标签包装成一个对象返回给我们, 找不到就返回Null
注意点: DOM操作返回的是一个对象, 这个对象是宿主类型对象(浏览器提供的对象)
let oDiv = document.getElementById("box");
console.log(oDiv);
console.log(typeof oDiv); //Object对象类型
- class名称获取
由于class可以重复, 所以找到了就返回一个存储了标签对象的数组,
找不到就返回一个空数组
<div class="father"></div>
<div class="father" id="box">我是div</div>
let oDivs = document.getElementsByClassName("father");
console.log(oDivs); //伪数组
- 通过name名称获取
由于name可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组
注意点: getElementsByName 在不同的浏览器其中工作方式不同。在IE和Opera中, getElementsByName() 方法还会返回那些 id 为指 定值的元素。表单提交时name为key name为值
<form>
<input type="text" name="test">
<input type="password" name="test">
</form>
let oDivs = document.getElementsByName("test");
console.log(oDivs);//伪数组
- 通过标签名称获取 《div input p等等》
由于标签名称可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组
let oDivs = document.getElementsByTagName("div");
console.log(oDivs);//伪数组
通过选择器获取
querySelector只会返回根据指定选择器找到的第一个元素
let oDiv = document.querySelector("#box");
let oDiv = document.querySelector(".father");
let oDiv = document.querySelector("div>form");
console.log(oDiv);
通过选择器获取
querySelectorAll会返回指定选择器找到的所有元素
let oDivs = document.querySelectorAll(".father");
console.log(oDivs);//伪数组
- getElementXXX和querSelector的区别
- 得到的元素不是需要很麻烦的多次getElementBy…的话,尽量使用getElementBy…,因为他快些。
- 得到的元素需要很麻烦的多次getElementBy…组合才能得到的话使用querySelector,方便。
- 看实际情况,你决定方便优先还是性能优先,
query选择符
选出来的元素及元素数组是静态的
,而getElement
这种方法选出的元素是动态的
。静态的就是说选出的所有元素的数组,不 会随着文档操作而改变.在使用的时候getElement这种方法性能比较好,query选择符则比较方便.
- 获取指定元素的所有子元素
用children
来获取
<div>
<h1>1</h1>
<h2>2</h2>
<p class="item">3</p>
<p>4</p>
<span>5</span>
</div>
- 获取的两种方式
1.1 children(获取的只有标签)
1.2 childNodes (标签+文本节点)
let oDiv = document.querySelector("div");
// children属性获取到的是指定元素中所有的子元素
console.log(oDiv.children);
// childNodes属性获取到的是指定元素中所有的节点
console.log(oDiv.childNodes);
- 什么是节点?
DOM对象(document), 这个对象以树的形式保存了界面上所有的内容 HTML页面每一部分都是由节点(标签(元素),文本,属性)
- 获取指定节点中的第一个子节点,第一个子元素,最后一个子节点,最后一个子元素
注意:元素一般为标签,节点可以为text herf
let oDiv = document.querySelector("div");
console.log(oDiv.firstChild);
// 获取指定元素中的第一个子元素
console.log(oDiv.firstElementChild);
// 4.获取指定节点中最后一个子节点
console.log(oDiv.lastChild);
// 4.获取指定元素中最后一个子元素
console.log(oDiv.lastElementChild);
*/
- 通过子元素获取父元素/父节点
let item = document.querySelector(".item");
console.log(item.parentElement);
console.log(item.parentNode);
let parentEle = item.parentElement || item.parentNode; //Firefox 兼容的写法
console.log(parentEle);
- 获取相邻上一个节点
//获取上一个节点
console.log(item.previousSibling); //#text
// 获取相邻上一个元素
console.log(item.previousElementSibling); //<h2> 2<h2>
- 获取相邻下一个节点
//获取下一个节点
console.log(item.nextSibling);
// 获取相邻下一个元素
console.log(item.nextElementSibling);
- 节点的增删改查
<h1>我是标题</h1>
<p>我是段落</p>
// 1.创建节点
let oSpan = document.createElement("span");
console.log(oSpan);
console.log(typeof oSpan);
//2.添加节点
//注意点: appendChild方法会将指定的元素添加到最后
let oDiv = document.querySelector("div");
oDiv.appendChild(oSpan)
let oA = document.createElement("a");
oDiv.appendChild(oA);
// 3.插入节点
let oSpan = document.createElement("span");
let oDiv = document.querySelector("div");
let oH1 = document.querySelector("h1");
let oP = docume nt.querySelector("p");
oDiv.insertBefore(oSpan, oH1);
oDiv.insertBefore(oSpan, oP);
// 5.删除节点
// 注意点: 在js中如果想要删除某一个元素, 只能通过对应的父元素来删除
// 元素是不能够自杀的
console.log(oSpan.parentNode);
oSpan.parentNode.removeChild(oSpan);
oDiv.parentNode.removeChild(oDiv);
// 5.克隆节点
// 注意点: cloneNode方法默认不会克隆子元素, 如果想克隆子元素需要传递一个true
let oDiv = document.querySelector("div");
let newDiv = oDiv.cloneNode();
let newDiv = oDiv.cloneNode(true);
console.log(newDiv);
- 操作DOM的元素属性
无论是通过document创建还是查询出来的标签,系统都会将元素包装成一个对象返回给我们,系统在包装这个对象的时候会自动将元素的属性都包装到这个对象中,所以只要拿到这个对象就可以拿到标签属性,操作标签属性。
<img src="images/1.jpg" alt="我是alt222" title="我是title" nj="666">
- 如何获取元素属性
let oImg = document.querySelector("img");
console.log(oImg.alt);
console.log(oImg.getAttribute("alt"));
// 注意点: 通过对象.属性名称的方式无法获取到自定义属性的取值
// 通过getAttribute方法可以获取到自定义属性的取值
console.log(oImg.nj);
console.log(oImg.getAttribute("nj"));
- 如何修改元素属性
let oImg = document.querySelector("img");
oImg.title = "新的title";
oImg.setAttribute("title", "新的title222");
// 注意点和获取元素属性一样
// oImg.nj = "123";
oImg.setAttribute("nj", "123");
- 如何新增元素属性
let oImg = document.querySelector("img");
// oImg.it666 = "itzb";
// 注意点: setAttribute方法如果属性不存在就是新增, 如果属性存在就是修改
oImg.setAttribute("it666", "itzb");
- 如何删除元素属性
let oImg = document.querySelector("img");
oImg.alt = "";
oImg.removeAttribute("alt");
// 注意点和获取元素属性一样
// oImg.nj = "";
oImg.removeAttribute("nj");
- 元素内容操作和元素样式操作
- 元素内容的操作
cript>
// 1.获取元素内容
/*
1.innerHTML获取的内容包含标签, innerText/textContent获取的内容不包含标签
2.innerHTML/textContent获取的内容不会去除两端的空格, innerText获取的内容会去除两端的空格
*/
let oDiv = document.querySelector("div");
console.log(oDiv.innerHTML);
console.log(oDiv.innerText);
console.log(oDiv.textContent);
// 2.设置元素内容
/*
特点:
无论通过innerHTML/innerText/textContent设置内容, 新的内容都会覆盖原有的内容
区别:
如果通过innerHTML设置数据, 数据中包含标签, 会转换成标签之后再添加
如果通过innerText/textContent设置数据, 数据中包含标签, 不会转换成标签, 会当做一个字符串直接设置
*/
let oDiv = document.querySelector("div");
// oDiv.innerHTML = "123";
// oDiv.innerText = "456";
// oDiv.textContent = "789";
// oDiv.innerHTML = "<span>我是span</span>";
// oDiv.innerText = "<span>我是span</span>";
// oDiv.textContent = "<span>我是span</span>";
setText(oDiv, "www.it666.com");
function setText(obj, text) {
if("textContent" in obj){
obj.textContent = text;
}else{
obj.innerText = text;
}
}
- 元素样式的操作
// 1.设置元素样式
let oDiv = document.querySelector("div");
// 第一种方式
// 注意点: 由于class在JS中是一个关键字, 所以叫做className
oDiv.className = "box";
// 第二种方式
// 注意点: 过去CSS中通过-连接的样式, 在JS中都是驼峰命名
// 注意点: 通过JS添加的样式都是行内样式, 会覆盖掉同名的CSS样式
oDiv.style.width = "300px";
oDiv.style.height = "300px";
oDiv.style.backgroundColor = "blue";
*/
// 2.获取元素样式
let oDiv = document.querySelector("div");
// oDiv.style.width = "300px";
// 注意点: 通过style属性只能过去到行内样式的属性值, 获取不到CSS设置的属性值
// console.log(oDiv.style.width);
// 注意点: 如果想获取到CSS设置的属性值, 必须通过getComputedStyle方法来获取
// getComputedStyle方法接收一个参数, 这个参数就是要获取的元素对象
// getComputedStyle方法返回一个对象, 这个对象中就保存了CSS设置的样式和属性值
let style = window.getComputedStyle(oDiv);
console.log(style.width);
-
给元素注册事件
-
什么是事件?
用户和浏览器之间的交互行为我们就称之为事件, 比如:点击,移入/移出 -
如何给元素绑定事件?
在JavaScript中所有的HTML标签都可以添加事件
元素.事件名称 = function(){};
当对应事件被触发时候就会自动执行function中的代码
-
let oBtn = document.querySelector("button");
oBtn.onclick = function () {
alert("按钮被点击了");
}
// 注意点: 如果给元素添加了和系统同名的事件, 我们添加的事件不会覆盖系统添加的事件
let oA = document.querySelector("a");
oA.onclick = function () {
alert("a标签被点击了");
// 以下代码的含义: 用我们添加的事件覆盖掉系统同名的事件
return false;
}
BOM
-
什么是BOM?
DOM就是一套操作HTML标签的API(接口/方法/属性)
BOM就是一套操作浏览器的API(接口/方法/属性) -
BOM中常见的对象
window: 代表整个浏览器窗口
注意: window是BOM中的一个对象, 并且是一个顶级的对象(全局)
Navigator
: 代表当前浏览器的信息, 通过Navigator我们就能判断用户当前是什么浏览器
Location
: 代表浏览器地址栏的信息, 通过Location我们就能设置或者获取当前地址信息
History
: 代表浏览器的历史信息, 通过History来实现刷新/上一步/下一步
注意点: 出于隐私考虑, 我们并不能拿到用户所有的历史记录, 只能拿到当前的历史记录
Screen
: 代表用户的屏幕信息
- Nacigator 代表当前浏览器的信息, 通过Navigator我们就能判断用户当前是什么浏览器
// Navigator: 代表当前浏览器的信息, 通过Navigator我们就能判断用户当前是什么浏览器
// console.log(window.navigator);
var agent = window.navigator.userAgent;
if(/chrome/i.test(agent)){
alert("当前是谷歌浏览器");
}else if(/firefox/i.test(agent)){
alert("当前是火狐浏览器");
}else if(/msie/i.test(agent)){
alert("当前是低级IE浏览器");
}else if("ActiveXObject" in window){
alert("当前是高级IE浏览器");
}
- Location: 代表浏览器地址栏的信息, 通过Location我们就能设置或者获取当前地址信息
// Location: 代表浏览器地址栏的信息, 通过Location我们就能设置或者获取当前地址信息
let oBtn1 = document.querySelector("#btn1");
let oBtn2 = document.querySelector("#btn2");
let oBtn3 = document.querySelector("#btn3");
let oBtn4 = document.querySelector("#btn4");
// 获取当前地址栏的地址
oBtn1.onclick = function(){
console.log(window.location.href);
}
// 设置当前地址栏的地址
oBtn2.onclick = function(){
window.location.href = "http://www.it666.com";
}
// 重新加载界面
oBtn3.onclick = function(){
window.location.reload();
}
oBtn4.onclick = function(){
window.location.reload(true);
}
- History
// History: 代表浏览器的历史信息, 通过History来实现刷新/前进/后退
// 注意点: 出于隐私考虑, 我们并不能拿到用户所有的历史记录, 只能拿到当前的历史记录
let oBtn1 = document.querySelector("#btn1");
let oBtn2 = document.querySelector("#btn2");
// 前进
/*
注意点:
只有当前访问过其它的界面, 才能通过forward/go方法前进
如果给go方法传递1, 就代表前进1个界面, 传递2就代表进行2个界面
*/
oBtn1.onclick = function () {
// window.history.forward();
window.history.go(1);
}
// 刷新
// 如果给go方法传递0, 就代表刷新
oBtn2.onclick = function () {
window.history.go(0);
}
// History: 代表浏览器的历史信息, 通过History来实现刷新/上一步/下一步
let oBtn1 = document.querySelector("#btn1");
// 后退
/*
注意点:
只有当前访问过其它的界面, back/go方法后退
如果给go方法传递-1, 就代表后退1个界面, 传递-2就代表后退2个界面
*/
oBtn1.onclick = function () {
// window.history.back();
window.history.go(-1);
}
获取元素宽高及位置
- offsetWidth/offsetHeight
- offsetLeft/offsetTop
- clientWidth/cilentHeight
注意点:
- offsetWidth = 宽度 + 内边距 + 边框
offsetHeight = 高度 + 内边距 + 边框 - clientWidth = 宽度 + 内边距
clientHeight = 高度 + 内边距 - offsetLeft/offsetTop: 距离第一个定位祖先元素偏移位 || body
clientLeft/clientTop: 左边框 和 顶部边框
注意点:
-
getComputedStyle/currentStyle/style
获取的宽高不包括 边框和内边距 -
offsetWidth/offsetHeight
获取的宽高包括 边框和内边距 -
getComputedStyle/currentStyle/offsetXXX
只支持获取, 不支持设置 -
style
可以获取, 也可以设置 -
getComputedStyle/currentStyle/offsetXXX
即可以获取行内,也可以获取外链和内联样式 -
style
只能获取行内样式
二 DOM2级事件的核心运行机制
三 事件对象
四 浏览器底层渲染机和DOM的回流和重绘
五 事件传播机制和事件代理
六 发布订阅者模式
持续更新中