九、JavaScript之DOM对象(DHTML)
一、什么是DOM?
DOM 是 W3C(万维网联盟)的标准。DOM 定义了访问 HTML 和 XML 文档的标准:
"W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。"
W3C DOM 标准被分为 3 个不同的部分:
- 核心 DOM - 针对任何结构化文档的标准模型
- XML DOM - 针对 XML 文档的标准模型
- HTML DOM - 针对 HTML 文档的标准模型
什么是 XML DOM? ---->XML DOM 定义了所有 XML 元素的对象和属性,以及访问它们的方法。
什么是 HTML DOM?---->HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。
二、DOM 节点
根据W3C的HTML DOM标准,HTML文档中的所有内容都是节点(NODE):
- 整个文档是一个文档节点(document对象)
- 每个HTML元素是元素节点(element对象)
- HTML元素内的文本是文本节点(text对象)
- 每个HTML属性是属性节点(attribute对象)
- 注释是注释节点(comment对象)
画dom树是为了展示文档中各个对象之间的关系,用于对象的导航。
节点(自身)属性:
- attributes - 节点(元素)的属性节点
- nodeType – 节点类型
- nodeValue – 节点值
- nodeName – 节点名称
- innerHTML - 节点(元素)的文本值
导航属性:
- parentNode - 节点(元素)的父节点 (推荐)
- firstChild – 节点下第一个子元素
- lastChild – 节点下最后一个子元素
- childNodes - 节点(元素)的子节点
注意:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="div1">
<div id="div2"></div>
<p>hello john</p>
</div>
<script>
var div=document.getElementById('div2');
console.log(div.nextElementSibling);
</script>
</body>
</html>
ps: nextSibling属性返回元素节点之后的兄弟节点(包括文本节点、注释节点即回车、换行、空格、文本等等);
推荐导航属性:
-
parentElement // 父节点标签元素
-
children // 所有子标签
-
firstElementChild // 第一个子标签元素
-
lastElementChild // 最后一个子标签元素
-
nextElementtSibling // 下一个兄弟标签元素
-
previousElementSibling // 上一个兄弟标签元素
节点树中的节点彼此拥有层级关系。
父(parent),子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹)。
- 在节点树中,顶端节点被称为根(root)
- 每个节点都有父节点、除了根(它没有父节点)
- 一个节点可拥有任意数量的子
- 同胞是拥有相同父节点的节点
下面的图片展示了节点树的一部分,以及节点之间的关系:
访问 HTML 元素(节点),访问 HTML 元素等同于访问节点,我们能够以不同的方式来访问 HTML 元素:
页面查找:
- 通过使用 getElementById() 方法
- 通过使用 getElementsByTagName() 方法
- 通过使用 getElementsByClassName() 方法
- 通过使用 getElementsByName() 方法
局部查找:
<div id="div1">
<div class="div2">i am div2</div>
<div name="john">i am div2</div>
<div id="div3">i am div2</div>
<p>hello p</p>
</div>
<script>
var div1=document.getElementById("div1");
////支持;
// var ele= div1.getElementsByTagName("p");
// alert(ele.length);
////支持
// var ele2=div1.getElementsByClassName("div2");
// alert(ele2.length);
////不支持
// var ele3=div1.getElementById("div3");
// alert(ele3.length);
////不支持
// var ele4=div1.getElementsByName("john");
// alert(ele4.length)
</script>
三、HTML DOM Event(事件)
HTML 4.0 的新特性之一是有能力使 HTML 事件触发浏览器中的动作(action),比如当用户点击某个 HTML 元素时启动一段 JavaScript。下面是一个属性列表,这些属性可插入 HTML 标签来定义事件动作。
onclick 当用户点击某个对象时调用的事件句柄。
ondblclick 当用户双击某个对象时调用的事件句柄。
onfocus 元素获得焦点。 //练习:输入框
onblur 元素失去焦点。 应用场景:用于表单验证,用户离开某个输入框时,代表已经输入完了,我们可以对它进行验证.
onchange 域的内容被改变。 应用场景:通常用于表单元素,当元素内容被改变时触发.(三级联动)
onkeydown 某个键盘按键被按下。 应用场景: 当用户在最后一个输入框按下回车按键时,表单提交.
onkeypress 某个键盘按键被按下并松开。
onkeyup 某个键盘按键被松开。
onload 一张页面或一幅图像完成加载。
onmousedown 鼠标按钮被按下。
onmousemove 鼠标被移动。
onmouseout 鼠标从某元素移开。
onmouseover 鼠标移到某元素之上。
onmouseleave 鼠标从元素离开
onselect 文本被选中。
onsubmit 确认按钮被点击。
两种为元素附加事件属性的方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>john</title>
</head>
<body>
<div onclick="alter(123)">点我呀</div>
<p id="abc">试一试</p>
<script>
var ele=document.getElementById('abc');
ele.onclick=function () {
alert("hi");
}
</script>
</body>
</html>
注意:
<div id="abc" onclick="func1(this)">事件绑定方式1</div>
<div id="id123">事件绑定方式2</div>
<script>
function func1(self){
console.log(self.id)
}
//jquery下是$(self), 这种方式this参数必须填写;
//------------------------------------------
var ele=document.getElementById("id123").onclick=function(){
console.log(this.id);
//jquery下是$(this), 这种方式不需要this参数;
}
</script>
onload:
onload 属性开发中 只给 body元素加.
这个属性的触发 标志着 页面内容被加载完成.
应用场景: 当有些事情我们希望页面加载完立刻执行,那么可以使用该事件属性.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
// window.onload=function(){
// var ele=document.getElementById("ppp");
// ele.onclick=function(){
// alert(123)
// };
// };
function fun1() {
var ele=document.getElementById("ppp");
ele.onclick=function(){
alert(123)
};
}
</script>
</head>
<body onload="fun1()">
<p id="ppp">hello p</p>
</body>
</html>
onsubmit:
是当表单在提交时触发. 该属性也只能给form元素使用.应用场景: 在表单提交前验证用户输入是否正确.如果验证失败.在该方法中我们应该阻止表单的提交.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>john</title>
</head>
<body>
<form id="form">
<input type="text"/>
<input type="submit" value="点我!"/>
</form>
<script type="text/javascript">
//阻止表单提交方式1()
//onsubmit 命名的事件函数,可以接受返回值. 其中返回false表示拦截表单提交.其他为放行.
var ele=document.getElementById('form');
ele.onsubmit=function (event) {
// alert("验证失败 表单不会提交!");
// return false;
// 阻止表单提交方式2 event.preventDefault(); ==>通知浏览器不要执行与事件关联的默认动作。
alert("验证失败 表单不会提交!");
event.preventDefault();
}
</script>
</body>
</html>
Event 对象
Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件通常与函数结合使用,函数不会在事件发生前被执行!event对象在事件发生时系统已经创建好了,并且会在事件函数被调用时传给事件函数.我们获得仅仅需要接收一下即可.
比如onkeydown,我们想知道哪个键被按下了,需要问下event对象的属性,这里就时KeyCode;
思考:onclick=function(event){};这个方法是谁调用的?
事件传播:
<div id="abc_1" style="border:1px solid red;width:300px;height:300px;">
<div id="abc_2" style="border:1px solid red;width:200px;height:200px;">
</div>
</div>
<script type="text/javascript">
document.getElementById("abc_1").onclick=function(){
alert('111');
}
document.getElementById("abc_2").onclick=function(event){
alert('222');
event.stopPropagation(); //阻止事件向外层div传播.
}
</script>
四、增删改查演示
node的CURD:
# 增
createElement(name)创建元素
appendChild();将元素添加
# 删
获得要删除的元素
获得它的父元素
使用removeChild()方法删除
# 改
第一种方式:
使用上面增和删结合完成修改
第二中方式:
使用setAttribute();方法修改属性
使用innerHTML属性修改元素的内容
# 查
<script type="text/javascript">
//在第一个div中动态增加一个a标签. 该a标签点击之后跳转到百度首页.
function addNode(){
//1.获得 第一个div
var div = document.getElementById("div_1");
//2.创建a标签 createElement==>创建一个a标签 <a></a>
var eleA = document.createElement("a");
//3.为a标签添加属性 <a href="http://www.baidu.com"></a>
eleA.setAttribute("href", "http://www.baidu.com");
//4.为a标签添加内容 <a href="http://www.baidu.com">百度</a>
eleA.innerHTML = "百度";
//5.将a标签添加到div中
div.appendChild(eleA);
}
//点击后 删除div区域2
function deleteNode(){
//1 获得要删除的div区域
var div = document.getElementById("div_2");
//2.获得父亲
var parent = div.parentNode;
//3 由父亲操刀
parent.removeChild(div);
}
//点击后 替换div区域3 为一个美女
function updateNode(){
//1 获得要替换的div区域3
var div = document.getElementById("div_3");
//2创建img标签对象 <img />
var img = document.createElement("img");
//3添加属性 <img src="001.jpg" />
img.setAttribute("src", "001.JPG");
//4.获得父节点
var parent = div.parentNode;
//5.替换
parent.replaceChild(img, div);
}
//点击后 将div区域4 克隆一份 添加到页面底部
function copyNode(){
//1.获取要克隆的div
var div = document.getElementById("div_4");
//2.克隆 参数为true 那么克隆时克隆所有子元素. false 只克隆自己
var div_copy = div.cloneNode(true);
//3.获得父亲
var parent = div.parentNode;
//4.添加
parent.appendChild(div_copy);
}
</script>
修改 HTML DOM
- 改变 HTML 内容
改变元素内容的最简答的方法是使用 innerHTML ,innerText。
- 改变 CSS 样式
<p id="p2">Hello world!</p>
document.getElementById("p2").style.color="blue";<br> .style.fontSize=48px
- 改变 HTML 属性
elementNode.setAttribute(name,value)
elementNode.getAttribute(name)<-------------->elementNode.value(DHTML)
- 创建新的 HTML 元素
createElement(name)
- 删除已有的 HTML 元素
elementNode.removeChild(node)
- 关于class的操作
elementNode.className
elementNode.classList.add
elementNode.classList.remove
八、案例
搜索框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>john</title>
</head>
<body>
<input id="id1" type="text" value="请输入用户名" onblur="Blurs()" onfocus="Focus()">
<script>
function Focus() {
var input=document.getElementById('id1');
if (input.value=="请输入用户名"){
input.value="";
}
}
function Blurs() {
var ele=document.getElementById("ID1");
var val=ele.value;
if(!val.trim()){
ele.value="请输入用户名";
}
}
</script>
</body>
</html>
模态对话框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.back{
background-color: rebeccapurple;
height: 2000px;
}
.shade{
position: fixed;
top: 0;
bottom: 0;
left:0;
right: 0;
background-color: coral;
opacity: 0.4;
}
.hide{
display: none;
}
.models{
position: fixed;
top: 50%;
left: 50%;
margin-left: -100px;
margin-top: -100px;
height: 200px;
width: 200px;
background-color: gold;
}
</style>
</head>
<body>
<div class="back">
<input id="ID1" type="button" value="click" onclick="action('show')">
</div>
<div class="shade hide"></div>
<div class="models hide">
<input id="ID2" type="button" value="cancel" onclick="action('hide')">
</div>
<script>
function action(act){
var ele=document.getElementsByClassName("shade")[0];
var ele2=document.getElementsByClassName("models")[0];
if(act=="show"){
ele.classList.remove("hide");
ele2.classList.remove("hide");
}else {
ele.classList.add("hide");
ele2.classList.add("hide");
}
}
</script>
</body>
</html>
全选反选取消
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button onclick="select('all');">全选</button>
<button onclick="select('cancel');">取消</button>
<button onclick="select('reverse');">反选</button>
<table border="1" id="Table">
<tr>
<td><input type="checkbox"></td>
<td>111</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>222</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>333</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>444</td>
</tr>
</table>
<script>
function select(choice){
var ele=document.getElementById("Table");
var inputs=ele.getElementsByTagName("input");
for (var i=0;i<inputs.length;i=i+1){
var ele2=inputs[i];
if (choice=="all"){
ele2.checked=true;
}else if(choice=="cancel"){
ele2.checked=false;
}
else {
if (ele2.checked){
ele2.checked=false;
}else {
ele2.checked=true;
}
}
}
}
</script>
</body>
</html>
两级联动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>john</title>
</head>
<body>
<select id="province">
<option>选择省:</option>
</select>
<select id="city">
<option>选择城市:</option>
</select>
<script>
data={"河北省":["廊坊","邯郸"],"北京":["朝阳区","海淀区"]};
var p=document.getElementById('province');
var c=document.getElementById('city');
for(var i in data){
var option_pro=document.createElement('option');
option_pro.innerHTML=i;
p.appendChild(option_pro);
}
p.onchange=function(){
pro=(this.options[this.selectedIndex]).innerHTML;
citys=data[pro];
c.options.length=0;
for (var i in citys){
var option_city=document.createElement("option");
option_city.innerHTML=citys[i];
c.appendChild(option_city);
}
}
</script>
</body>
</html>
select左右移
<div id="box1">
<select multiple="multiple" size="10" id="left">
<option>book</option>
<option>book2</option>
<option>book3</option>
<option>book4</option>
<option>book5</option>
<option>book6</option>
</select>
</div>
<div id="choice">
<input class="add" type="button" value="--->" onclick="add()"><br>
<input class="remove" type="button" value="<---" onclick="remove();"><br>
<input class="add-all" type="button" value="====>" onclick="ADDall()"><br>
<input class="remove-all" type="button" value="<===" onclick="remall()">
</div>
<div>
<select multiple="multiple" size="10" id="right">
<option>book9</option>
</select>
</div>
<script>
function add(){
var right=document.getElementById("right");
var options=document.getElementById("left").getElementsByTagName("option");
for (var i=0; i<options.length;i++){
var option=options[i];
if(option.selected==true){
right.appendChild(option);
i--;
}
}
}
function ADDall(){
var right=document.getElementById("right");
var options=document.getElementById("left").getElementsByTagName("option");
for (var i=0; i<options.length;i++){
var option=options[i];
right.appendChild(option);
i--;
}
}
</script>