JavaScript基础知识之DOM和BOM

330 阅读6分钟

这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战

1、DOM操作

在一个html页面中,会使用很多标签来规划制作页面。

每个标签都有它存在的意义,如果我们想要动态的修改某个标签的值。那我们就需要在页面中查找 到这个标签元素。

如何查找到这个元素是个难题,W3C组织的工程师们,突然看到了一棵大树。我要是想找到某一 片叶子,应该怎么做?

“顺藤摸瓜”,主树干有分支,每个分支还有许多小分支,只要把这个分支的结构整理清楚,任何一 片叶子都不是难事了,叶子和大树的一些启发,工程师们开会讨论就定了这个理论“文档对象模型”。

文档对象模型,就是将页面中所有的标签元素都看成是一个对象(一片叶子),主树干定义为根节 点(根元素),所有的标签都是从根元素延伸出去的,摸清结构,找到某个标签就不再困难了 在节点树中,顶端节点就是根节点(root),每个节点都有父节点(除了根节点) 任何一个节点都可以拥有任意数量的子节点,同胞是拥有相同父节点的节点

<html>
<head>
<meta	charset="utf-8">
<title>DOM教程</title>
</head>
<body>
<h1>第一节:HTML	DOM</h1>
<p>Hello	world!</p>
</body>
</html>
从上面的HTML中:
<html>节点没有父节点;它是根节点
<head><body>的父节点是	<html>节点
文本节点	"Helloworld!"的父节点是	<p>节点
并且:
<html>节点拥有两个子节点:<head><body>
<head>节点拥有两个子节点:<meta><title>节点
<title>节点也拥有一个子节点:文本节点	"DOM教程"<h1><p>节点是同胞节点,同时也是
<body>的子节点
并且:
<head>元素是	<html>元素的首个子节点
<body>元素是	<html>元素的最后一个子节点
<h1>元素是	<body>元素的首个子节点
<p>元素是	<body>元素的最后一个子节点

js为我们提供了很多种方法来实现在页面找查找某个元素节点

4.1、DOM访问

  • getElementById:通过id属性获得元素节点对象

案例:当帐号为空时,阻止表单提交

<body>
<formaction="xxx" onsubmit="return login()">
<p>帐号:<input id="username"/></p>
<p>电话:<input id="phone"/></p>
<p><button>登录</button></p>
</form>

<script>
function login()	{
var name=document.getElementById("username").value;
if(name	== ""){
alert("帐号不能为空!");
return	false;	//	阻止表单的提交
}
return	true;	//	放行,让表单提交
}
</script>
</body>
  • getElementsByName:通过name属性获得元素节点对象集

案例:购物车全选效果

<body>
<h2>我的购物车</h2>
<table	border="1" cellspacing="0">
<tr>
<td><input type="checkbox" onchange="quan(this)" />全选</td>
<td>名称</td>
<td>单价</td>
</tr>
<tr>
<td><input type="checkbox" name="one" />1</td>
<td>功能性饮料-尖叫</td>
<td>4.0</td>
</tr>
<tr>
<td><input type="checkbox" name="one"/>2</td>
<td>火腿肠</td>
<td>2.0</td>
</tr>
<tr>
<td><input type="checkbox" name="one" />3</td>
<td>包子</td>
<td>1.5</td>
</tr>
</table>

<p>
<button>提交订单</button>
</p>

<script>
function quan(all){
var arr =document.getElementsByName("one");
for(var i =0;i<arr.length;i++){
arr[i].checked=all.checked;//	将全选框的状态,赋值给每一个复选框
}
}
</script>
</body>
  • getElementsByTagName:通过标签名称获得元素节点对象集

案例:表格隔行变色

<body>
<table border="1" cellspacing="0">
<tr>
<td><input type="checkbox" onchange="quan(this)" />全选</td>
<td>名称</td>
<td>单价</td>
</tr>
<tr>
<td><input type="checkbox" name="one" />1</td>
<td>功能性饮料-尖叫</td>
<td>4.0</td>

</tr>
<tr>
<td><input type="checkbox" name="one"/>2</td>
<td>火腿肠</td>
<td>2.0</td>
</tr>
<tr>
<td><input type="checkbox" name="one" />3</td>
<td>包子</td>
<td>1.5</td>
</table>


<script>
var rows=document.getElementsByTagName("tr");	//通过标签名获得元素对象集合
for(var i=0;i<rows.length;i++)	{
if(i%2==1){//	奇数
rows[i].style.backgroundColor="pink";
    }
}
</script>
</body>

4.2、DOM修改

修改HTMLDOM意味着许多不同的方面:

  • 改变HTML内容
  • 改变CSS样式
  • 改变HTML属性
  • 创建新的HTML元素
  • 删除已有的HTML元素
  • 改变事件(处理程序)
  • 1.改变一个h2元素的HTML内容
<body>
<button	onclick="test()">点我试试</button>

<script>
function test(){
document.getElementById("hello").innerHTML="走哇,喝点去~!";
}
</script>

<h2 id="hello">你好!</h2>
</body>
  • 2.改变一个h2的HTML样式
<body>
<button	onclick="chou()">你瞅啥</button>
<script>
function chou(){
document.getElementById("hello").style.color="red";
document.getElementById("hello").style.fontFamily="华文彩云";
}
</script>
<h2 id="hello">你好!</h2>
</body>

4.2.1、添加节点

点击按钮,在页面中创建一张图片

<body>
<button	onclick="add()">添加</button>
<div></div>

<script>
function add(){
var	img=document.createElement("img");//	<img>	
img.setAttribute("src","../111-html/img/cat.gif");//<img src="../111-html/img/cat.gif">

img.setAttribute("title","小猫咪");	//	<img src="../111-html/img/cat.gif" title="小猫咪">

img.setAttribute("id","cat");	//	<img	src="../111-html/img/cat.gif" title="小猫咪" id="cat">

var	divs=document.getElementsByTagName("div");
divs[0].appendChild(img);
}
</script>
</body>

4.2.2、删除节点

点击按钮,把上面刚创建的图片从页面上删除

<body>
<button	onclick="add()">添加</button>
<button	onclick="del()">删除</button>
<div>
</div>

<script>
function add(){
。。。略。。。
}

function del(){
var	img=document.getElementById("cat");
img.parentNode.removeChild(img);//	必须通过父节点,才能删除子节点
}
</script>
</body>

4.2.3、替换节点

点击按钮,把上面刚创建的图片替换成另一张

<body>
<button	onclick="add()">添加</button>
<button	onclick="del()">删除</button>
<button	onclick="rep()">替换</button>
<div>
</div>

<script>
function	add(){
。。。略。。。
}

function	del(){
。。。略。。。
}

function	rep(){
var	imgold=document.getElementById("cat");
//	通过修改元素的属性,做的替换
//	img.setAttribute("src","../lagou-html/img/2.jpg");

var	imgnew=document.createElement("img");
imgnew.setAttribute("src","../lagou-html/img/1.jpg");

imgold.parentNode.replaceChild(	imgnew,	imgold	);
}
</script>
</body>

4.3、事件

js捕获某个动作而做出的反馈

  • HTML事件的例子:
  • 当用户点击鼠标时
  • 当网页已加载时
  • 当图片已加载时
  • 当鼠标移动到元素上时
  • 当输入字段被改变时
  • 当 HTML表单被提交时
  • 当用户触发按键时

4.3.1、窗口事件(WindowEvents)

仅在body和 frameset元素中有效。 onload当文档被载入时执行脚本

<body	onload="test()">
<script>
function	test()	{
document.write("哈哈哈哈");
}
</script>
</body>

4.3.2、表单元素事件(Form Element Events)

仅在表单元素中有效。

  • onblur 当元素失去焦点时执行脚本
  • onfocus 当元素获得焦点时执行脚本
<body>
<script>
function a(){
console.log("获得焦点==被激活");
}
function b(){
console.log("失去焦点");
}
</script>

<formaction="">
<p>帐号:<input onfocus="a()" onblur="b()"/></p>
<p>密码:<input/></p>
</form>
</body>

4.3.3、鼠标事件(MouseEvents)

  • onclick 当鼠标被单击时执行脚本
  • ondblclick 当鼠标被双击时执行脚本
  • onmouseout 当鼠标指针移出某元素时执行脚本
  • onmouseover 当鼠标指针悬停于某元素之上时执行脚本
<style>
img{
width:	30%;
border:	5px solid white;
}
</style>

<body>
<img	src="img/logo.png"	onmouseover="shang(this)" onmouseout="xia(this)" onclick="dan()">
<img	src="img/logo.png"	onmouseover="shang(this)" onmouseout="xia(this)" ondblclick="shuang()">
<img	src="img/logo.png"	onmouseover="shang(this)" onmouseout="xia(this)">

<script>
function	dan(){
alert("点了一下");
}

function	shuang(){
alert("连续快读点两下");
}

function shang(img){
img.style.border="5px	solid	red";
}
function xia(img){
img.style.border="5px	solid	white";
}
</script>
</body>

4.3.4、键盘事件

  • onkeydown按下去
  • onkeyup弹上来
<script>
window.onkeydown=function(){
//	event:事件源(按键)
//	console.log(	"按键编码:"+event.keyCode	);
if(event.keyCode=="13"){	//	回车键
alert("登录成功!");
}
}

window.onkeyup=function(){
console.log(event.keyCode);	//	按住按键不松手是不会触发的。当松手时,按键回弹则触发
}
</script>

4.3.5、事件冒泡

创建两个div,一个大一些,一个小一些

<style>
#father	{
width:	200px;
height:	200px;
background:	black;
padding:	10px;
}


#child	{
width:	100px;
height:	100px;
background:	greenyellow;
}
</style>

<body>
<div	id="father">
<div	id="child"></div>
</div>

<script>
//	代码不重要,重要是知道这个事件发生,是正常现象

document.getElementById("father").addEventListener("click",	function()	{
alert("父级元素的事件被触发:"+this.id);
});

document.getElementById("child").addEventListener("click",	function(e)	{
e.stopPropagation()	//取消事件的冒泡机制
alert("子级元素的事件被触发:"+this.id);
});
</script>
</body>

先子,后父。事件的触发顺序* *,这就是事件冒泡;

4.3.6、事件捕获

还是刚才创建两个div,一个大一些,一个小一些

<style>
#father	{
width:	200px;
height:	200px;
background:	black;
padding:	10px;
}

#child	{
width:	100px;
height:	100px;
background:	greenyellow;
}
</style>

<body>
<div	id="father">
<div	id="child"></div>
</div>
<script>
document.getElementById("father").addEventListener("click",function(){
alert("父级:"+this.id);
},true);
document.getElementById("child").addEventListener("click",function(){
alert("子级:"+this.id);
},true);
</script>
</body>

先父,后子。事件触发顺序变更为,这就是事件捕获;

4.4、面向对象OOP

使用Object创建通用对象


var	user=new	Object();
user.name="吕布";
user.age=21;
user.say=function(){
console.log("大家好,我叫:"+this.name+",我今年"+this.age+"岁了!");
}
user.say();
var	dog=new	Object();
dog.nickname="屎尿多";
dog.wang=function(){
console.log("我饿了,我要拆家了!");
}

dog.wang();

使用构造函数

function userinfo(name,age){
this.name=name;
this.age=age;
this.say=function(){
console.log("大家好,我叫:"+this.name+",我今年"+this.age+"岁了!");
}
}

var user=new userinfo("詹姆斯",35);
user.say();

使用直接量

var user={
username:"孙悟空",
age:527,
say:function(){
console.log("大家好,我叫:"+this.username+",我今年"+this.age+"岁了!");
}
};

user.say();

4.5、JSON

大家在互联网上来回传递数据,如果没有一个统一的格式,解析起来的难度很大(每个人的编码喜好不一样)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。

易于人阅读和编写,同时也易于机器解析和生成

{ 属性1:值1, 属性2:值2, 。。。。 }

<script>
var	json1={username:"吕布",age:31	};
console.log("姓名:"+json1.username+",年龄:"+json1.age+"岁");
//	json数组
var	josnarr	=[{name:"貂蝉",age:18},{name:	"小乔",age:17}];
console.log("貂蝉"+josnarr[0].age+"岁了");
console.log("小乔"+josnarr[1].age+"岁了");
//	复杂的json对象
var	long={
name:"赵云",
sex:"男",
hobby:["玉兰白龙驹","龙胆亮银枪","青釭剑"]
};
console.log(long.name+"的主攻武器:"+long.hobby[1]);
</script>

2、BOM操作

就是javascript对浏览器的一些常规操作的方法

2.1、window对象

<button	onclick="kai()">极速入职</button>

<script>
function	kai(){
window.open("http://lagou.com"	,"111",
"width=500,height=300,left=400");
//	window.open("http://lagou.com"	,"111",	"fullscreen=yes");	//	IE才
生效
}
</script>

5.1.1、screen屏幕对象

我想知道我的电脑屏幕多大?实际上,得到的就是分辨率

<body>
<button	onclick="kai()">求大小</button>
</body>
<script>
function	kai()	{
alert(window.screen.width+"|"+window.screen.height);
}
</script>

5.1.2、location定位

包含有关当前 URL的信息,通常用来做页面跳转

<button	onclick="test()">测试</button>
<script>
function	test(){
console.log(	"当前页面的URL路径地址:"+	location.href	);
location.reload();	//	重新加载当前页面(刷新)
location.href	="http://lagou.com";	//	跳转页面
}
</script>

5.1.3、history浏览器历史

history对象会记录浏览器的痕迹

a.html

<ahref="b.html">去b页面</a>

b.html

<button	onclick="hui()">返回</button>

<script>
function	hui(){
//history.go(-1);	//上一级页面
history.back();	//	与go(-1)是等价的
}
</script>

5.1.4、navigator导航

window.navigator对象包含有关访问者浏览器的信息;

<script>
var	str="";
str+="<p>浏览器的代号:"+	navigator.appCodeName	+"</p>";
str+="<p>浏览器的名称:"+	navigator.appName+"</p>";
str	+="<p>浏览器的版本:"+	navigator.appVersion+"</p>";
str+="<p>硬件平台:"+	navigator.platform+"</p>";
str+="<p>用户代理:"+	navigator.userAgent	+"</p>";
str+="<p>启用Cookies:"+navigator.cookieEnabled+"</p>";

document.write(str);
</script>

5.1.5、存储对象

用起来和我们在java中map很相似,都是键值对的方式存数据

5.1.5.1、本地存储localStorage

在关闭窗口或标签页之后将会删除这些数据

保存数据

localStorage.setItem("name","curry");

提取数据

localStorage.getItem("name");

删除数据

localStorage.removeItem("name");

多样化操作

//	三种方式保存数据
localStorage["a"]=1;
localStorage.b=2;
localStorage.setItem("c",3);

//	查看数据类型
console.log(typeof	localStorage["a"])
console.log(typeof	localStorage["b"])
console.log(typeof	localStorage["c"])

//	第一种方式读取
var	a=localStorage.a;
console.log(a);

//	第二种方式读取
var	b=localStorage["b"];
console.log(b);

//	第三种方式读取
var	c=localStorage.getItem("c");
console.log(c);

5.1.5.2、会话存储sessionStorage

会话,就是保持浏览器别关闭。

关闭浏览就等于结束了一次会话。

开启浏览器就意味着创建了一次会话。

保存数据

sessionStorage.setItem("name",	"klay");

提取数据

var	lastname=sessionStorage.getItem("name");

删除指定键的数据

sessionStorage.removeItem("name");

删除所有数据

sessionStorage.clear();

案例:记录点击了几下按钮

<button	onclick="dian()">点我</button>
<h3	id="result"></h3>
<script>
function	dian(){
if(	sessionStorage.getItem("clickCount")){
sessionStorage.setItem("clickCount",
Number(sessionStorage.getItem("clickCount"))+1);
}else{
sessionStorage.setItem("clickCount",1);
}
document.getElementById("result").innerHTML="已经点击了"+
sessionStorage.getItem("clickCount")+"次!"
}
</script>

5.2、计时操作

5.2.1、周期性定时器setInterval

setInterval(1,2):周期性触发代码exp

  • 1:执行语句
  • 2:时间周期,单位为毫秒

案例:闪烁的字体 (1秒1变色)

<body>
<h1	id="title">拉勾网:极速入职</h1>

<script>
var	colors=["red","blue","yellow","pink","orange","black"];
var	i=0;
function	bian(){
document.getElementById("title").style.color=colors[i++];
if(i==colors.length){
i=0;//	颜色重新开始
}
}

setInterval(bian,100);	//	每隔0.1秒,执行一次bian函数
</script>
</body>

案例:在闪烁字体的基础上扩展,闪烁的电子时钟

<body>
<h1	id="title"></h1>
<script>
var	colors=["red","blue","yellow","pink","orange","black"];
var	i=0;
function bian(){
document.getElementById("title").style.color=colors[i++];
if(i==colors.length){
i=0;//	颜色重新开始
}
}

function time(){
var	d=new	Date();
var	str=d.getFullYear()+"年"+(d.getMonth()+1)+"月"+d.getDate()+"号
"+d.getHours()+"点"+d.getMinutes()+"分"+d.getSeconds()+"秒";
document.getElementById("title").innerHTML=str;
}

setInterval(bian,100);	//	每隔1秒,执行一次变色函数bian
setInterval(time,1000);	//	每隔1秒,执行一次时间函数time
</script>
</body>

5.2.2、停止定时器clearInterval

案例:模拟年会抽奖

<body>
<img	id="tu"	src="../lagou-html/img/1.jpg"	width="50%"	/>
<br	/>
<button	onclick="begin()">开始</button>
<button	onclick="stop()">停止</button>

<script>
var	arr=["1.jpg","2.jpg","3.jpg",	"4.jpg","5.jpg"];
function begin()	{
timer	=setInterval(bian,100);//	没有使用var,所以timer是全局变量
}

functionstop()	{
clearInterval(timer);//	停止定时器
}

function bian()	{
var	i=Math.floor(Math.random()*	arr.length);//	0-4
document.getElementById("tu").src="../111-html/img/"+arr[i];
}
</script>
</body>

5.2.3、一次性定时器setTimeout

相当于延迟的效果,只执行一次

<script>
functionbian(){
document.body.style.backgroundColor="red";
}


//3秒之后调用
setTimeout(bian,3000);
</script>