BOM 和 DOM 对象


基础知识

JavaScript分为 ECMAScript,DOM,BOM。

  • BOM (Browser Object Model)是指浏览器对象模型,它使 JavaScript 有能力与浏览器进行“对话”。
  • DOM (Document Object Model)是指文档对象模型,通过它,可以访问HTML文档的所有元素(标签)。

BOM 对象

BOM(Browser Object Mode)浏览器对象模型,是Javascript的重要组成部分。
它提供了一系列对象用于与浏览器窗口进行交互,这些对象通常统称为BOM。

window 对象 – BOM核心

1、它表示整个浏览器窗口,主要用来操作浏览器窗口
2、所有 JavaScript 全局对象、函数以及变量均自动成为 window 对象的成员。
3、全局变量是 window 对象的属性。全局函数是 window 对象的方法。
4、Window对象是客户端JavaScript最高层对象之一,由于window对象是其它大部分对象的共同祖先,在调用window对象的方法和属性时,可以省略window对象的引用。
例如:window.document.write()可以简写成:document.write()。

  • 所有浏览器都支持 window 对象。
  • 概念上讲.一个html文档对应一个window对象。
  • 功能上讲: 控制浏览器窗口的。
  • 使用上讲: window对象不需要创建对象,直接使用即可。
1
2
3
4
5
// 一些常用的Window方法:
window.innerHeight - 浏览器窗口的内部高度
window.innerWidth - 浏览器窗口的内部宽度
window.open() - 打开新窗口
window.close() - 关闭当前窗口

window 的子对象

1
2
3
4
5
// 浏览器对象,通过这个对象可以判定用户所使用的浏览器,包含了浏览器相关信息。
navigator.appName   // Web浏览器全称
navigator.appVersion  // Web浏览器厂商和版本的详细字符串
navigator.userAgent   // 客户端绝大部分信息
navigator.platform   // 浏览器运行所在的操作系统

screen对象(了解即可)

1
2
3
// 屏幕对象,不常用。
screen.availWidth - 可用的屏幕宽度
screen.availHeight - 可用的屏幕高度

history对象(了解即可)

1
2
3
// 浏览历史对象,包含了用户对当前页面的浏览历史,但我们无法查看具体的地址,可以简单的用来前进或后退一个页面。
history.forward()
history.back()

location对象

1
2
3
4
5
6
7
8
9
10
// 用于获得当前页面的地址 (URL),并把浏览器重定向到新的页面。
location.herf = 'url地址'
location.hostname // 返回 web 主机的域名
location.pathname // 返回当前页面的路径和文件名
location.port // 返回 web 主机的端口 (80 或 443)
location.portocol // 返回页面使用的web协议。 http:或https:

location.href // 获取当前的URL
location.href = 'http://www.baidu.com' // 跳转到指定的URL
location.reload() // 重新加载当前页面

弹出框

1
2
3
4
// JavaScript 中创建三种消息框:警告框、确认框、提示框。
alert('提示信息'); // 警告框
confirm("确认信息"); // 确认框
prompt("请在下方输入","你的答案"); // 提示框

定时器

  • setTimeout() 和 clearTimeout() 在指定时间之后执行一次相应函数。
  • setInterval() 和 clearInterval() 在指定的周期(以毫秒计)来调用函数或计算表达式。
1
2
3
4
5
6
7
8
9
10
11
12
// 一定时间间隔之后执行
// 语法: var t=setTimeout("JS语句",毫秒)
var t = setTimeout("alert('发送成功')",3000)

// 函数定时执行
function func(){
alert('发送成功')
}
var t = setTimeout(func,3000)

// 取消setTimeout设置
clearTimeout(t)
1
2
3
4
5
6
7
8
9
// 每隔多少秒执行一次
// 语法:var t = setInterval("JS语句",时间间隔)
function foo(){
console.log(1)
};
var t = setInterval(foo,1000)

// 取消setInterval设置
clearInterval(t);

DOM 对象

  • DOM(Document Object Model)是一套对文档的内容进行抽象和概念化的方法。
  • 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。
  • HTML DOM 模型被构造为对象的树。

HTML DOM 树

  • dom树是为了展示文档中各个对象之间的关系,用于对象的导航。

DOM都有哪一些内容

  • HTML 文档中的每个成分都是一个节点。
    DOM标准规定HTML文档中的每个成分都是一个节点(node):
    • 文档节点(document对象):代表整个文档
    • 元素节点(element 对象):代表一个元素(标签)
    • 文本节点(text对象):代表元素(标签)中的文本
    • 属性节点(attribute对象):代表一个属性,元素(标签)才有属性
    • 注释是注释节点(comment对象) 

JS 操作DOM

  1. JavaScript 可以通过DOM创建动态的 HTML
  2. JavaScript 能够改变页面中的所有 HTML 元素
  3. JavaScript 能够改变页面中的所有 HTML 属性
  4. JavaScript 能够改变页面中的所有 CSS 样式
  5. JavaScript 能够对页面中的所有事件做出反应

查找标签

直接查找

1
2
// 通过id查找标签
document.getElementById("d1")
1
2
// 根据class属性获取所有标签
document.getElementsByClassName("p1")
1
2
// 根据标签名获取标签合集
document.getElementsByTagName("div")

间接查找

1
2
3
4
5
6
parentElement            // 父节点标签元素
children // 所有子标签
firstElementChild // 第一个子标签元素
lastElementChild // 最后一个子标签元素
nextElementSibling // 下一个兄弟标签元素
previousElementSibling // 上一个兄弟标签元素
1
2
3
4
5
6
7
// 查找父节点
// 子节点.parentElement
var d3Ele = document.getElementById("d3")
d3Ele.parentElement
// <div id=​"d2">​…​</div>​
d3Ele.parentElement.parentElement
// <body>​…​</body>​
1
2
3
4
5
// 查找所有子标签
// 父节点.children
var d2Ele = document.getElementById("d2")
d2Ele.children
d2Ele.childNodes
1
2
3
4
5
6
// 第一个子标签元素 和 最后一个
var d2Ele = document.getElementById("d2")
d2Ele.firstElementChild
// <div id=​"d3">​d2里面的d3​</div>​
d2Ele.lastElementChild
// <div id=​"d5">​d2里面的d5​</div>​
1
2
3
4
5
6
// 下一个兄弟标签元素 和 上一个
var d4Ele = document.getElementById("d4")
d4Ele.previousElementSibling
// <div id=​"d3">​d2里面的d3​</div>​
d4Ele.nextElementSibling
// <div id=​"d5">​d2里面的d5​</div>​

节点操作

创建节点

1
2
// 语法:createElement(标签名)
var divEle = document.createElement("div");

添加节点

1
2
3
4
// 追加一个子节点(作为最后的子节点)
// somenode.appendChild(newnode);
// 把增加的节点放到某个节点的前边。
// somenode.insertBefore(newnode,某个节点);
1
2
3
4
5
6
7
var imgEle = document.createElement("img")    // 创建img节点
// 给igm节点添加一个src属性
imgEle.src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1560341306312&di=67d00a7580c18d13000ced0c9df87e35&imgtype=0&src=http%3A%2F%2Fpic.rmb.bdstatic.com%2Fd487c4c496b952e7463a9ac2a041643a.jpeg"

// 添加img节点到d1标签中
var d1Ele = document.getElementById("d1")
d1Ele.appendChild(imgEle) // 把创建好的imgEle添加到id=d1的标签内部
1
2
3
4
5
6
7
8
9
// 在某个标签前面添加   insertBefore(要插入的新标签,哪个标签之前)
var divEle = document.createElement("div") // 创建新的div标签
divEle.innerText = "大家好" // 添加文本
"大家好"
var d4Ele = document.getElementById("d4") // 找到要加入的父标签
var d2Ele = document.getElementById("d2") // 找到要加入到前面的子标签

d2.insertBefore(divEle,d4Ele) // 在d4标签之前加入新div标签
<div>​大家好​</div>​

删除节点

1
2
3
4
5
6
7
// 语法:somenode.removeChild(要删除的节点)
// 获得要删除的元素,通过父元素调用该方法删除。
var d2Ele = document.getElementById("d2")
d2Ele.firstElementChild
// <div id=​"d3">​d2里面的d3​</div>​
var sonEle = d2Ele.firstElementChild;
d2Ele.removeChild(sonEle)

替换节点

1
2
3
4
5
6
7
8
9
// 语法:somenode.replaceChild(newnode, 某个节点);
var d2Ele = document.getElementById("d2")
var sonEle = d2Ele.firstElementChild;
var aEle = document.createElement("a")
aEle.innerText="点我"
"点我"
aEle.href="http://www.baidu.com"
"http://www.baidu.com"
d2Ele.replaceChild(aEle,sonEle)

属性操作

获取属性

1
2
3
// 获取元素节点中指定属性的属性值
var d2Ele = document.getElementById("d2")
d2Ele.getAttribute("id")

设置属性

1
2
3
4
5
6
7
8
9
// 默认属性都可以修改 
d2Ele.setAttribute("age",18)
d2.getAttribute("age")
"18"

// 自带的属性还可以直接.属性名来获取和设置
imgEle.src="..."
aEle.innerText="点我"
aEle.href="http://www.baidu.com"

删除属性

1
2
3
d2.removeAttribute("age")
d2.getAttribute("age")
null

文本操作

innerHTML 和 innerText的区别:

* innerHTML:子标签和子标签的内容都取出来,主要记这个:快速添加简单的标签
* innerText:只取标签之间的内容 

获取标签文本

1
2
3
4
5
6
7
8
9
10
// 获取标签内的文本信息
var d2Ele = document.getElementById("d2")
d2Ele.innerText
// "d2里面的d3
// d2里面的d4
// d2里面的d5"

var d4Ele = document.getElementById("d4")
d4Ele.innerText
// "d2里面的d4"

替换标签文本

1
d2Ele.innerText = "全部修改"   // 修改文本内容 连子标签都没了,只剩下了文本

获取标签和文本

1
2
3
4
5
6
7
8
// 获取d2下面所有html内容,包括标签和文本
var d2Ele = document.getElementById("d2")
d2Ele.innerHTML
//"
// <div id="d3">d2里面的d3</div>
// <div id="d4">d2里面的d4</div>
// <div id="d5">d2里面的d5</div>
//"

快速添加简单的标签

1
2
// 原先的标签会被替换
d2Ele.innerHTML = "<p>我是新的p标签</p>"

获取值操作

1
2
3
// 语法:elementNode.value
// 适用于以下标签:
// input、select、textarea
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var textEle = document.getElementById("i1")
textEle.value
"leo"

var selectEle = document.getElementById("s1")
selectEle.value
"010"

var tEle = document.getElementById("t1")
tEle.value
"哈哈哈"
```

### class 操作
```javascript
className // 获取所有样式类名(字符串)
classList.remove(cls) // 删除指定类
classList.add(cls) // 添加类
classList.contains(cls) // 存在返回true,否则返回false
classList.toggle(cls) // 存在就删除,否则添加
1
<div class="c1 c2 c3">div</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var divEles = document.getElementsByTagName("div")
divEles[0].className
"c1 c2 c3"

// 删除其中一个class样式 c3
divEles[0].classList.remove("c3")
divEles[0].className
"c1 c2"

// 添加一个class样式 c99
divEles[0].classList.add("c99")
divEles[0].className
"c1 c2 c99"

// 测试是否存在c3 和 c99
divEles[0].classList.contains("c3")
false
divEles[0].classList.contains("c99")
true

// 测试存在删除,不存在则添加
divEles[0].classList.toggle("c3")
true
divEles[0].className
"c1 c2 c99 c3"
divEles[0].classList.toggle("c3")
false
divEles[0].className
"c1 c2 c99"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 切换颜色实例
<style>
.c1{
height: 200px;
width: 200px;
border-radius: 50%;
background-color: gray;
}

.c2 {
background-color: yellow;
}
</style>

<div class="c1 c2 c3" onclick="change(this);">div</div>

<script>
function change(ths) {
ths.classList.toggle("c2") // 点一下 有c2就去掉,没c2就加上,相当于来回切换
}
</script>

指定CSS操作

1
2
3
// dom 直接修改样式
var divEles = document.getElementsByTagName("div")
divEles[0].style.backgroundColor="blue" // 原先带_改成了驼峰

JS操作CSS属性的规律:

1
2
3
4
5
6
// 1.对于没有中横线的CSS属性一般直接使用style.属性名即可。如:

obj.style.margin
obj.style.width
obj.style.left
obj.style.position
1
2
3
4
5
6
// 2.对含有中横线的CSS属性,将中横线后面的第一个字母换成大写即可。如:

obj.style.marginTop
obj.style.borderLeftWidth
obj.style.zIndex
obj.style.fontFamily

事件

常用事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
onclick        //当用户点击某个对象时调用的事件句柄。
ondblclick //当用户双击某个对象时调用的事件句柄。

onfocus //元素获得焦点。 练习:输入框
onblur //元素失去焦点。 应用场景:用于表单验证,用户离开某个输入框时,代表已经输入完了,我们可以对它进行验证.
onchange //域的内容被改变。 应用场景:通常用于表单元素,当元素内容被改变时触发.(select联动)

onkeydown //某个键盘按键被按下。 应用场景: 当用户在最后一个输入框按下回车按键时,表单提交.
onkeypress //某个键盘按键被按下并松开。
onkeyup //某个键盘按键被松开。
onload //一张页面或一幅图像完成加载。
onmousedown //鼠标按钮被按下。
onmousemove //鼠标被移动。
onmouseout //鼠标从某元素移开。
onmouseover //鼠标移到某元素之上。

onselect //在文本框中的文本被选中时发生。
onsubmit //确认按钮被点击,使用的对象是form。

绑定方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div class="c1 c2 c3" onclick="change(this);">div</div>
<div class="c1 c2 c3">div</div>
<div class="c1 c2 c3">div</div>
<div class="c1 c2 c3">div</div>

<script>

// 第一种方式 在标签里调用onclick,然后写函数方法
function change(ths) {
ths.classList.toggle("c2") // 点一下 有c2就去掉,没c2就加上,相当于来回切换
}


// 第二种方式 js代码绑定事件 找所有的div,循环每一个去绑定一个事件
var divEles = document.getElementsByTagName("div") // 获得div的数组
for (var i = 0;i<divEles.length;i++){
divEles[i].onclick = function (){
this.classList.toggle("c2") // 哪个标签被点击,this就是谁
}
}
</script>

事件示例

定时器练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<input id="i1" type="text">
<input type="button" id = "start" value="开始">
<input type="button" id = "stop" value="停止">
<script>
// 声明全局的t,保存定时器的ID
var t; // undefind
// 在input框 显示当前时间
// 1.获取当前时间

function get_time() {
var now = new Date();
var nowStr = now.toLocaleString();

// 2.时间字符串填到input框
var i1Ele = document.getElementById("i1");
i1Ele.value = nowStr
}

// 3. 点开始让时间动起来 每隔一秒钟就执行一次获取时间函数 get_time()
// 找到开始按钮,并绑定事件
var startbutton = document.getElementById("start");
startbutton.onclick = function () {
// 先执行一次get_time,就不会有空隙
get_time()
// 每隔一秒执行 定时器
// 如果不等于undefined 说明已经存在定时器
if (t === undefined){
t = setInterval(get_time,1000); // 把定时器的ID 赋值给之前声明的全局变量t
}

}

var stopbutton = document.getElementById("stop");
stopbutton.onclick = function () {
// 停止定时器
clearInterval(t) // 清除T对应的定时器,t的值还在
console.log(t);
t = undefined // 初始化值
}

</script>

搜索框

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!--test框的默认值,在点击test框时消失-->
<input type="text" id="i1" value="对子哈特" >
<input type="button" value="搜索">

<script>
// 找到input框
var i1Ele = document.getElementById("i1")
i1Ele.onfocus = function () {
// 把value青龙
this.value = "";
}

i1Ele.onblur = function () {
// 失去焦点之后,如果值是空叫填写回去
if (!this.value.trim()){
this.value = "对子哈特"
}
}

</script>

select 联动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<select name="" id="s1">
<option value="0">--请选择--</option>
<option value="1">北京</option>
<option value="2">上海</option>
</select>

<select name="" id="s2">
<option value=""></option>
</select>

<script>

var data = {1:["西城区","朝阳区","东城区"],2:["静安区","闵行区","浦东区"]};
// 给第一个select绑定事件,onchange
var s1Ele = document.getElementById("s1");
s1Ele.onchange = function () {

// 取到选择的是哪一个 市
// 把对应市的区 填写到第二个select框里

console.log(this.value);
var areas = data[this.value]; // 获得对应的区
var s2Ele = document.getElementById("s2")

// 清空之前的标签
s2Ele.innerHTML = "";

// 生成option标签
for (var i = 0;i<areas.length;i++){
var opEle = document.createElement("option");
opEle.innerText= areas[i];
s2Ele.appendChild(opEle)
}
// 添加到select内部
}
</script>