文章目录
HTML DOM(文档对象模型)
什么是 DOM?
DOM 是一项 W3C (World Wide Web Consortium) 标准。
DOM 定义了访问文档的标准:
“W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问、更新文档的内容、结构和样式。”
W3C DOM 标准被分为 3 个不同的部分:
Core DOM - 所有文档类型的标准模型
XML DOM - XML 文档的标准模型
HTML DOM - HTML 文档的标准模型
DOM可以把HTML和XML文档解析为一个文档树,树上每一个分支都可以视为一个对象,通过DOM可以动态操作该文档
DOM的作用:
- 获取页面中的元素
- 获取/设置元素的属性
- 获取/设置元素的样式
- 添加/删除元素
- 绑定事件-触发响应
HTML 文档的树状结构
当需要对HTML中的内容进行动态改变时,就要使用DOM操作
HTML的DOM树
Window对象
常用属性
- screen:有关客户端的屏幕和显示性能信息
- history:有关客户访问过的URL的信息
- location:有关当前URL的信息
- document:表示浏览器窗口中的HTML文档
当然包含了子级对象(history,location,document)以及screen等。
常用方法
- alert() 显示带有一段消息和一个确认按钮的警告框。
- blur() 把键盘焦点从顶层窗口移开。
- clearInterval() 取消由setInterval() 设置的 timeout。
- clearTimeout() 取消由 setTimeout() 方法设置的 timeout。
- close() 关闭浏览器窗口。
- confirm() 显示带有一段消息以及确认按钮和取消按钮的对话框。
- createPopup() 创建一个 pop-up 窗口。
- focus() 把键盘焦点给予一个窗口。
- moveBy() 可相对窗口的当前坐标把它移动指定的像素。
- moveTo() 把窗口的左上角移动到一个指定的坐标。
- open() 打开一个新的浏览器窗口或查找一个已命名的窗口。
- prompt() 显示可提示用户输入的对话框。
- resizeBy() 按照指定的像素调整窗口的大小。
- resizeTo() 把窗口的大小调整到指定的宽度和高度。
- scrollBy() 按照指定的像素值来滚动内容。
- scrollTo() 把内容滚动到指定的坐标。
- setInterval() 按照指定的周期(以毫秒计)来调用函数或计算表达式。
- setTimeout() 在指定的毫秒数后调用函数或计算表达式。
- showModalDialog()在一个模态窗口中显示指定的HTML文档
计时器
setTimeout()方法(延时调用)和setInterval()方法(循环定时调用)
- setTimeout(test,1000) -1000毫秒后调用test
- setInterval(test,1000) -每隔1000毫秒调用一次test
如果在test方法中在家一个setTimeout,接口实现和setInterval相同的循环调用功能。
同时在创建定时器的时候,声明一个名称,这样方便取消和操作
var timer=SetTimeout(test,1000);
那么使用cleanTimeout来清除定时器
clearTimeout(timer);
常用事件
- onload 一个页面或者一幅图像完成加载
- onmouseover 鼠标移到某元素上
- onmouseout 鼠标移开某元素时
- onclick 当用户单机某个对象时调用的事件句柄
- onkeydown 某个按键按下
- onscroll 窗口滚动条滑动时
*因为window是DOM的根元素,所使用以上常用属性,方法,事件时可以胜率对象名window
测试:
window.onload=function(){//匿名函数,回调函数
alert('页面加载完成!');
};
window.onmouseover=function(){
console.log('鼠标在窗体上!');
};
window.onmouseout=function(){
console.log('鼠标离开窗体!');
};
window.onclick=function(){
console.log('窗体被点击了!');
};
window.onkeydown=function(){
console.log('按下了某个按键!');
};
window.onscroll=function(){
console.log('窗口滚动条滚动了!');
};
history对象
常用方法
- back() 加载history列表中的上一个URL
- forward() 加载history列表中的下一个URL
- go(‘url’ or number) 加载history列表中的一个URL,或要求浏览器移动指定的页面数
back()方法相当于后退按钮,
forward()方法相当于前进按钮,
go(1)代表前进1页,等价于forward()方法,
go(-1)代表后退1页,等价与back()方法。
练习:
首先我们在HTML中创建3个按钮并绑定事件:
<input type="button" value="后退" onclick="doBack()" />
<input type="button" value="前进" onclick="doForward()" />
<input type="button" value="后退两页" onclick="doGO()" />
再为这些事件,创建动作:
function doBack(){
history.back();
};
function doForward(){
history.forward();
};
function doGo(){
history.go(-2);
};
function doGo2(){
history.go(0);//相当于刷新
};
location对象
href 属性,设置或检索完整的URL字符串
reload() 方法,重新加载当前页
练习
首先在HTML中写好基础页面并绑定事件:
<input type="button" value="获取地址" onclick="getLoaction()" />
<input type="button" value="更改地址,跳转页面" onclick="setLoaction()" />
<input type="button" value="刷新" onclick="doReload()" />
再为这些事件,创建动作:
function getLoaction(){
console.log(location.href);
};
function setLoaction(){
location.href='http://wwww.baidu.com';
};
function doReload(){
location.reload;
};
练习2:下拉列表直接跳转至该项网页
HTML部分代码:
<select onchange='doChange(this)'> <!-- this表示出发事件的元素,也称为事件源 -->
<option value="http://www.baidu.com">百度</option>
<option value="http://wwww.sina.com">新浪</option>
<option value="http://www.qq.com">腾讯</option>
</select>
JS中创建动作:
function doChange(option){
location.href=option.value;
};
document对象
常用属性
bgcolor 设置或检索document对象的背景色
document表示整个HTML文档
常用方法
- write() 在当前页面中输入指定内容
- getElementById() 返回指定id的第一个对象的引用
- getElementsByName() 返回带有指定名称的对象集合
- getElementsByTagName() 返回带有指定标签名的对象集合
document可以分为两类:读操作、更新操作
练习
练习1.更改页面颜色、获取title和body:
HTML代码:
<input type="button" value="设置页面背景" onclick="changeBackgroundColor()" />
<input type="button" value="获取Title" onclick="getTitle()" />
<input type="button" value="获取body" onclick="getBody()" />
对应JS代码:
function changeBackgroundColor(){
document.bgColor='red';
};
function getTitle(){
console.log(document.title);
};
function getBody(){
console.log(document.body);
};
练习2.页面内添加文字
HTML代码:
<input type="button" value="write" onclick="doWrite()">
JS部分:
function doWrite(){
document.write('my name is jackson');
};
练习3.根据条件查找
HTML代码:
<input type="button" value="获取ID" onclick="getById()">
<input type="button" value="获取NAME" onclick="getByName()">
<input type="button" value="获取标签" onclick="getByTagName()">
<div id='myId'>这是第一个DIV</div>
<div id='myId'>这是第二个DIV</div>
<p>爱好:</p>
<input type="checkbox" name="hobby" id="eat" value="eat"><label for="eat">吃饭</label>
<input type="checkbox" name="hobby" id="sleep" value="sleep"><label for="sleep">睡觉</label>
<input type="checkbox" name="hobby" id="doudou" value="doudou"><label for="doudou">打豆豆</label>
JS部分:
function getById(){
var getId=document.getElementById('myId');
console.log(getId);
};
function getByName(){
var getNames=document.getElementsByName('hobby');
console.log(getNames);
};
function getByTagName(){
var getTagNames=document.getElementByTagName('input');
console.log(getTagNames.length);
console.log(getTagNames);
};
DOM对象的属性
DOM对象的属性和HTML标签的属性几乎是一样的,用法为:DOM对象.属性 。
- src、name、id、href、title等。
- type、value、checked、selected、disabled等
获取/设置标签中的内容的属性:
- innerHTML 会直接把内容解析到DOM树上
- innerText内容会被认为是纯文本. 即:只获取文本,忽略标签
练习
题目:如图所示,在搜索框输入内容,在选择按钮选择搜索引擎,点击按钮,可以直接把搜索框内容在对应引擎网站进行搜索,并且,在选择引擎时,按钮名称自动变为对应的。
HTML部分:
<form action="http://www.baidu.com/s" id='myFrm'>
<input type="radio" name="search" id="baidu" onclick="doChange()" checked/>
<label for="baidu">百度</label>
<input type="radio" name="search" id="google" onclick="doChange()"/>
<label for="baidu">谷歌</label>
<input type="radio" name="search" id="bing" onclick="doChange()"/>
<label for="baidu">必应</label>
<br />
<input type="text" name="wd" id="txtSearch" placeholder="请输入搜索关键字">
<input type="submit" value="百度搜索" id="btnSearch">
</form>
JS部分:
function doChange(){
var baidu=document.getElementById('baidu');
var google=document.getElementById('google');
var bing=document.getElementById('bing');
if(baidu.checked){
document.getElementById('myFrm').action='http://wwww.baidu.com/s';
document.getElementById('btnSearch').value='百度搜索';
}else if(google.checked){
document.getElementById('myFrm').action='http://wwww.google.cn';
document.getElementById('btnSearch').value='谷歌搜索';
}else{
document.getElementById('myFrm').action='http://cn.bing.com/search';
document.getElementById('txtSearch').name='q';
document.getElementById('btnSearch').value='必应搜索';
}
}
解析:
以上并没有什么特殊的难度,主要问题在于,搜索引擎直接用连接方式搜索,会有些前缀,找到规则更改name即可.
document写操作的步骤
document表示DOM树的最顶层节点,对英语HTML文档。
节点常用属性
- childNodes:子节点列表
- documentElement:获取文档的根元素
节点常用方法:
- createElement(元素名):创建元素节点
- createTextNode(文本内容):创建文本节点
- appendChild(子节点):添加子节点,主要添加根元素
- createNode(类型,名称):根据条件创建一个新节点,
节点类型:1表示元素节点,2表示属性节点,3表示文本节点
练习1.操作列表:
HTML部分:
<ul id="myUl">
<li id="first">Jackson1</li>
<li>Jackson2</li>
<li>Jackson3</li>
</ul>
<hr />
<input type="button" value="添加一行" onclick="goAdd()" />
<input type="button" value="获取元素" onclick="goElement()" />
<input type="button" value="获取元素内部标签" onclick="goLi()" />
<br />
<hr />
JS部分:
增加一行:
function goAdd(){
//1.创建新元素
var newLi=document.createElement('li');
// 2.设置文本内容
var newText=document.createTextNode('Jackson4');
newLi.appendChild(newText);
// 3.设置属性
newLi.setAttribute('id','fourth');
//4.找到父元素
var myUl=document.getElementById('myUl');
// 5.追加
myUl.appendChild(newLi);
};
获取:
function goElement(){
var th=document.getElementById('th');
console.log('节点名称:'+th.nodeName);
console.log('节点类型:'+th.ndoeType);//1表示元素节点,2表示属性节点,3表示文本节点
//获取子节点的集合
/*var childs=th.childNodes;//不仅包括子元素,还包括其他类型的子节点(如文本、注释等),可以通过节点类型(nodeTpye)来判断
console.log(childs);
for(var i = 0 ; i<childs.length;i++){
console.log(childs[i]);
};*/
//获取第一个子节点
var first=th.firstChild;
console.log(first);
//获取属性的集合
var tr=document.getElementById('myTr');
var attributes=tr.attributes;
console.log(attributes);//是个集合
for (var i = 0; i < attributes.length; i++) {
console.log(attributes[i]);
};
};
获取内部:
function goLi(){
var myUl2=document.getElementById(myUl2);
var lis=myul2.getElementByTagName('li');
console.log(myUl2.getElementById('first'))
}
练习2.操作表格
HTML:
<table id="myTable" width='300px' border="1px" align="center">
<thead id="th">
<tr id="myTr">
<th id="first">th1</th>
<th id="second">th2</th>
<th>th3</th>
<th>th4</th>
<th>th5</th>
</tr>
</thead>
</table>
<input type="button" value="为表格添加一行" onclick="goAdd2()" />
JS部分:
function goAdd2(){
var tr=document.createElement('tr');
for(var i=1;i<=5;i++){
var td=document.createElement('td');
td.appendChild(document.createTextNode('td'+i));
// td.innerHTML='td'+i; //HTML特有,只能在HTML中使用
tr.appendChild(td);
};
tr.setAttribute('align','center');
// tr.align='right';
var table=document.getElementById('myTable');
table.appendChild(tr);
};
其他元素操作
- 克隆:node.cloneNode(true/false 是否包括内容)
- 插入:parent.insertBefore(新的节点,已经存在的节点)
- 删除:parent.removeChild(要删除的节点)
- 替换:parent.replaceChild(新的节点,被替换的节点)
这部分用实操的方式进行了解。
现在HTML中创建这4个操作的按钮,已经一张表格:
<input type="button" value="插入" onclick="goInsert()" />
<input type="button" value="删除" onclick="goRemove()" />
<input type="button" value="替换" onclick="goReplace()" />
<input type="button" value="克隆" onclick="goClone()" />
<hr />
<!-- table>(thead#th>tr>th{th$}*5)+tboady#tb>(tr>td{td$}*5)*4 -->
<table width="500px" align="center" border="1px">
<thead id="th">
<tr>
<th>th1</th>
<th>th2</th>
<th>th3</th>
<th>th4</th>
<th>th5</th>
</tr>
</thead>
<tbody id="tb">
<tr>
<td>td1</td>
<td>td2</td>
<td>td3</td>
<td>td4</td>
<td>td5</td>
</tr>
<tr>
<td>td1</td>
<td>td2</td>
<td>td3</td>
<td>td4</td>
<td>td5</td>
</tr>
<tr>
<td>td1</td>
<td>td2</td>
<td>td3</td>
<td>td4</td>
<td>td5</td>
</tr>
<tr>
<td>td1</td>
<td>td2</td>
<td>td3</td>
<td>td4</td>
<td>td5</td>
</tr>
</tboady>
</table>
预览图:
可以看到,已经给相应的按钮,绑定了对应的事件,目的是要点击相应的按钮,就可以有对应的操作:
插入操作
我们已经在按钮中,给插入绑定了goInsert(),那么我们在JS中,进行编写一下。
作用是当点击它的时候,可以在表格主体部分第三行,插入一个新行,并且这个新行是跨越5行的。
function goInsert() {
var tr=document.createElement('tr');
var td=document.createElement('td');
td.colSpan='5';//注意区分大小写
td.innerHTML='一个跨越五列的新行';
tr.appendChild(td);
var tb=document.getElementById('tb');
var trs=tb.getElementsByTagName('tr');
tb.insertBefore(tr,trs[2]);
}
点击后的效果:
删除操作
删除事件,定义为,将表格中的第一行进行删除。
function goRemove(){
var tb=document.getElementById('tb');
var trs=tb.getElementsByTagName('tr');
tb.removeChild(trs[0]);
}
替换操作
替换操作,使他可以将表格中的第四行,替换为一个类似插入操作中的跨越5列的行。
function goReplace(){
var tb=document.getElementById('tb');
var trs=tb.getElementsByTagName('tr');
var tr=document.createElement('tr');
var td=document.createElement('td');
td.colSpan='5';//注意区分大小写
td.innerHTML='用于替换第四行跨越五列的新行';
tr.appendChild(td);
tb.replaceChild(tr,trs[3]);
}
效果:
插入操作
这部分为了可以直观的看到,我们先点击插入功能,插入一个第三行。
然后将表格主体中的第三行克隆一份,添加到最后。
function goClone(){
var tb=document.getElementById('tb');
var trs=tb.getElementsByTagName('tr');
var cloneTr=trs[2].cloneNode(true);
tb.appendChild(cloneTr);
}
cloneNode()括号中的参数,如果是true包含它的所有内容,如果是false不包含子节点,但是属性会克隆
效果:
JavaScript访问CSS样式
现在HTML中写一个带属性的div:
<div id="mydiv" style="width: 150px;height: 100px;background-color: #ccc;font-size: 14px;">My Name is Jackson!</div>
如果要访问到它,那么要在窗体加载完后,通过他的ID来获取它,然后在控制台输出它的宽高
window.onload=function(){
var myDiv=document.getElementById('mydiv');
console.log(myDiv.style.width);//150px
console.log(myDiv.style.fontSize);//14px
};
又或者,在窗体加载时,直接为它加粗字体,并且加一个上边框:
window.onload=function(){
var myDiv=document.getElementById('mydiv');
console.log(myDiv.style.width);//150px
console.log(myDiv.style.fontSize);//14px
myDiv.style.fontWeight='700';
myDiv.style.borderTopSize='2px';
myDiv.style.borderTopColor='red';
myDiv.style.borderTopStyle='solid';
};
可以看到,JS在访问css属性的时候是通过.style.样式名,来访问的,而且,它的样式名并不是和CSS完全相同的,有着一定的规则:
- 单一单词的CSS样式属性,直接使用‘’对象名.style.样式名“来访问,如上面的"myDiv.style.width";
- 复合词,将复合符号”-“去掉,并将其后的单词首字母给成大写,也就是改为驼峰命名的规则,也是JS常用的命名规则,如上面的:“myDiv.style.fontWeight”
练习
练习1:输入框焦点
当输入框获得焦点时,更改它的颜色(其实部分浏览器默认就有这个效果),当失去焦点后还原。
先写好默认框,并且绑定好获得焦点和失去焦点的事件:
用户名: <input type="text" id="username" onfocus="getFocus()" onblur="onBlur(this)"><br />
获得焦点的操作:
function getFocus(){
var txt=document.getElementById('username');
txt.style.border='1px solid red';
}
失去焦点后,还原:
function onBlur(obj){
obj.style.border='';
}
可以看到,在失去焦点的操作中传入了参数,绑定事件的时候也为它添加了this,顾名思义为了让函数能够对对应的传入点进行操作。
练习2:
制作一个菜单,当鼠标经过时改变菜单的背景色和文字颜色:
先构造好html和css
HTML:
<ul>
<li>资讯动态</li>
<li>产品世界</li>
<li>市场营销</li>
</ul>
CSS:
li{
margin: 2px;
float: left;
list-style: none;
font-size: 12px;
width:105px;
height: 33px;
text-align: center;;
line-height: 33px;
background-color: #ddd;
}
.over{
background-color:#bbb;
color: red;
}
.out{
background-color: #ddd;
color:;
}
课件中是直接更改属性的,但是我这里通过了样式表,切换样式的方式来实现。
className属性:当修改样式比较多时,可以借助于样式表,为不同表下的样式分别定义一个类选择器,在脚本中使用”对象名.className"来访问
看下实际的操作:
window.onload=function(){
var lis=document.getElementsByTagName('li');
for(var i=0;i<lis.length;i++){
lis[i].onmouseover=function(){
/*this.style.backgroundColor='#bbb';//this表示事件源,即发生事件的元素
this.style.color='red';*/
this.className='over';
};
lis[i].onmouseout=function(){
/*this.style.backgroundColor='';
this.style.color=''*/
// this.className='out';
this.classList.remove('over');
};
}
};
因为li有很多个,或者不确定数量,所以我们用数组来获取它,然后使用循环进行绑定事件。
DOM练习
要点内容差不多掌握了后,我们对这些操作进行一个综合的练习。
练习1、将表单的数据添加到表格中
可以看到上图,需要实现的是当我们输入完信息后,点击add可以把数据添加到表格中:
reset按钮其实很简单,只要定一个input的type为reset即可。
那么HTML部分,我们需要绑定事件的地方是add按钮:
<p align="center">Pls Input Info</p>
<form action="" align="center" id="formInfo">
<span>Name:</span><input type="text" id="name" /><br />
<span>Age:</span><input type="text" id="age" /><br />
<span>Gender:</span>
<input type="radio" name="gender" id="male" checked="checked" />
<label for="male">Male</label>
<input type="radio" name="gender" id="female"/>
<label for="male">Female</label>
<br />
<span>Email:</span><input type="text" id="email" /><br />
<input type="button" value="Add" onclick="addInfo()">
<input type="reset" value="Reset" >
</form>
JS操作部分:
function addInfo(){
var form=document.getElementById('formInfo');
var tr=document.createElement('tr');
var table=document.getElementById('myTb');
var name=document.getElementById('name');
var age=document.getElementById('age');
var male=document.getElementById('male');
var female=document.getElementById('female');
var mail=document.getElementById('email');
var tds=[];
for(var i=0;i<4;i++){
tds[tds.length]=document.createElement('td');
tr.appendChild(tds[i]);
};
tds[0].innerHTML=name.value;
tds[1].innerHTML=age.value;
if(male.checked){
tds[2].innerHTML='male';
}else if(female.checked){
tds[2].innerHTML='female';
};
tds[3].innerHTML=mail.value;
myTb.appendChild(tr);
}
可以看到,这里我直接用循环创建了4个td,并且存储在数组里,然后,因为类型是固定的,那么我们在添加时只用对应的标号进行添加即可,当然,这里也可以使用switch来进行选择添加。
练习2、TAB切换效果
实现的目标实际就是 当鼠标经过方两个选项的时候,下方显示对页面
这个其实就是早期类似淘宝充值的页面中切换的效果,
教学中使用的是切换图片,这里使用切换颜色以便更好的练习对CSS的操作
构造html:
<table border="1px" cellpadding="0" cellspacing="0" width="250px" align="center">
<tr>
<td id="left" class="mobile" onmouseover="show('left')">手机充值</td>
<td id="right" class="game" onmouseover="show('right')">游戏充值</td>
</tr>
<tr>
<td colspan="2">
<div id="item1" class="item mobile">手机充值页面</div>
<div id="item2" class="item game hidden">游戏充值页面</div>
</td>
</tr>
</table>
CSS
.item{
width: 250px;
height: 250px;
}
.mobile{
background-color: #bbb;
}
.game{
background-color: #158;
}
.hidden{
display: none;
}
JS功能实现部分:
function show(flag){
var left=document.getElementById('left');
var right=document.getElementById('right');
var item1=document.getElementById('item1');
var item2=document.getElementById('item2');
if(flag=='right'){
left.style.backgroundColor='#999';
right.style.backgroundColor='#bbb';
item1.classList.add('hidden');
item2.classList.remove('hidden');
}else{
left.style.backgroundColor='#bbb';
right.style.backgroundColor='#158';
item1.classList.remove('hidden');
item2.classList.add('hidden');
};
}
通过函数传入不同的标记,来进行判断操作。
练习3、全选和取消全选
这个是类似购物车的操作,当勾选最上方用于全选的选项时,下面的选项全选,当然,当下面的选项,全部选择后,自动勾上全选按钮,当取消其中任意数量选项后,自动取消全选按钮。
先构造好HTML:
<table border="1px" align="center" width="600px">
<thead>
<tr>
<th><input type="checkbox" id='all'></th>
<th>商品样式</th>
<th>商品信息</th>
<th>商品价格</th>
</tr>
</thead>
<tr>
<td><input type="checkbox" name='item'></td>
<td>杜比音箱</td>
<td>杜比环绕音箱,出售者XXXXX</td>
<td>一口价:88888</td>
</tr>
<tr>
<td><input type="checkbox" name='item'></td>
<td>老黄显卡</td>
<td>老黄显卡RTX 8080TI</td>
<td>一口价:88888</td>
</tr>
<tr>
<td><input type="checkbox" name='item'></td>
<td>AMDCPU</td>
<td>AMD RYZEN 9950X</td>
<td>一口价:88888</td>
</tr>
<tr>
<td><input type="checkbox" name='item'></td>
<td>华硕显示器</td>
<td>华硕100寸显示器</td>
<td>一口价:88888</td>
</tr>
</table>
那么,这个选过必定是要在窗体加载的时候运行的所以,需要写在onload中
JS实现功能部分:
window.onload=function(){
var all=document.getElementById('all');
var items=document.getElementsByName('item');
all.onclick=function(){
if(all.checked){
for(i=0;i<items.length;i++){
items[i].checked=true;
};
}else{
for (var i = 0; i <items.length; i++) {
items[i].checked=false;
};
};
};
// 实现当选中下面所有复选框时自动选中全选
for(i=0;i<items.length;i++){
items[i].onclick=function(){
//统计数量
var count=0;
for(j=0;j<items.length;j++){
if(items[j].checked){
count++;
};
};
//判定全选
if (count==items.length){
all.checked=true;
}else{
all.checked=false;
};
};
};
};
练习4、带按钮的轮播图
这个练习我之前写在了另一篇文章里:
JavaScript-最基础的带按钮轮播图
注:此为个人学习笔记,如有补充可以选择在评论区留言或者无视。