第一节:DOM编程概述
1.1 什么是DOM编程
文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言的标准编程接口。在网页上,组织页面(或文档)的对象被组织在一个树形结构中。
1.2 为什么要学习DOM编程
学习DOM操作 就是 操作页面中的节点对象(元素,文本,元素中的属性)。
增删改
新增:新增什么? 各种标签 本来不存在,但是我们又想用, 无中生有!
-
创造标签 此时没有样式 创建
-
美化(设置样式,添加内容) 美化
-
将造好的标签 添加到 该添加的地方!添加
删除:删除标签
修改:1.修改样式 2.内容 3. 替换 4.属性
第二节:节点操作
对节点的操作 增删改查
2.1 节点概述
什么是节点?
-
文档是一个文档节点。(包含页面中的标签,属性,文本,空格符,特殊符号)
-
所有的HTML元素都是元素/标签节点。 **
-
所有 HTML 属性都是属性节点。
-
文本插入到 HTML 元素是文本节点。
2.2 标签节点对象的获取
想操作页面中的某一个标签,要先拿到这个标签。
2.3 节点的操作
-
增加操作
删除操作名称 含义 *document.createElement(标签名) 创建一个节点 insertBefore(新标签,哪个标签之前) 在哪个标签之前插入节点 *父.appendChild(新标签) 在父节点的里边追加子节点 cloneNode() 复制节点,如果参数为true,还会复制当前节点的子孙节点,否则只复制当前节点。 -
名称 含义 父.removeChild(子标签) 删除指定的子标签/子节点 自己.remove() 删除自身 修改操作
名称 含义 parent.replaceChild(新标签, 旧标签); 将父标签中的旧标签用新标签替换掉 2.4 节点具有的属性
元素(Element): 就是html标签。对元素的访问使用的更频繁
节点(Node): 包含了html标签,文本内容
节点对象属性(不加括号) 含义 childNodes 数组 所有直接子节点(包含文本节点和标签元素节点)。返回子节点数组 *children 数组 所有元素子节点——获取所有的子标签(不包含文本节点)。返回子元素数组 *firstElementChild 第一个子元素对象 firstChild 第一个子节点对象 *lastElementChild 最后一个子元素对象 lastChild 最后一个子节点对象 *parentNode 父节点 nextSibling 返回当前元素紧跟的下一个兄弟节点(包含文本/标签等) *nextElementSibling 返回指定元素之后的下一个兄弟元素节点(相同节点树层中的下一个元素节点)。 previousSibling 返回当前元素上一个节点紧挨着的 *previousElementSibling 返回指定元素的前一个兄弟元素(相同节点树层中的前一个元素节点) 节点对象属性 含义 nodeValue 节点值 (文本节点的值)。文本节点和属性节点返回文本内容,元素节点返回null nodeType 节点类型。1标签节点 2 属性节点 3文本节点 nodeName 节点名称。文本节点固定返回: #text 元素节点:返回标签名 注意:所有文本节点的nodeName都是 “#text”。节点值就是文本内容,节点类型就是3
所有元素节点的nodeName就是元素标签名。节点值都是null,节点类型就是1
-
元素对象属性/方法 值 *value 文本框的值 id 标签的id属性值 name 表单元素的name属性值 className class属性值 *innerHTML 标签中的所有HTML内容 outerHTML 包含标签本身以及标签体 innerText 标签中的所有文本内容 getAttribute("属性名") 获取标签属性值方法 setAttribute("属性名","属性值") 为标签设置属性方法 getAttributeNode("属性名") 获取属性节点对象方法 修改本身就有的属性 只要能直接 . 出来 就表示 . 出来的属性都是本身就有的(系统规定的)
2.5 常用查询/获取节点方法
方法 说明 *getElementById 根据编号获取元素 getElementsByTagName 根据标签名获取元素数组 getElementsByClassName 根据类样式名获取元素数组 getElementsByName 根据元素的name属性查找元素数组 *querySelector 根据id选择器或类选择器获取单个元素 *querySelectorAll 根据id选择器或类选择器获取元素数组 第三节:案例练习
3.1 发表说说
分析:
1.首先需要一个div装所有的评论。
2.当点击发表按钮时 将评论添加到div中
3.添加之前 先创建标签 < span>放名字 在创建一个span放内容 在将创建的两个span 添加到一个P标签中
<!DOCTYPE html> <html> <head> <title> new document </title> <style type="text/css"> fieldset{ width:500px; height:300px; border:1px solid red; margin:0px auto; text-align:center } #con{ border:2px dashed gray; height:200px; margin:10px; padding:10px; text-align:left; } </style> <script type="text/javascript"> function send(){ var xm = txtName.value; var nr = txtMsg.value; //var str = xm+"说:"+nr+"<br/>"; //con.innerHTML +=str; var span1 = document.createElement("span"); span1.innerHTML=xm+"说:"; span1.style.backgroundColor="#ffff66"; var span2 = document.createElement("span"); span2.innerHTML=nr; span2.style.backgroundColor="lightblue"; var p = document.createElement("p"); p.style.border="1px solid gray"; p.appendChild(span1); p.appendChild(span2); con.appendChild(p); } // 扩展,添加删除按钮删除说说 </script> </head> <body> <fieldset> <legend>发表说说</legend> <div> 姓名: <input type="text" id="txtName"/> 内容: <input type="text" id="txtMsg"/> <input type="button" value="发表" onclick="send()"/> </div> <div id="con"> </div> </fieldset> </body> </html>
3.2 省市级联
<!DOCTYPE html>
<html>
<head>
<title> new document </title>
<style type="text/css">
</style>
<script type="text/javascript">
var proAry = ["河南","河北","山东"]
window.onload=function(){
var op = document.createElement("option");
op.value="";
op.innerText="请选择";
pro.appendChild(op);
for(var i=0;i<proAry.length;i++){
var op = document.createElement("option");
op.value=proAry[i];
op.innerText = proAry[i];
pro.appendChild(op);
}
}
function selCity(){
// 将下拉框的选项清空
city.options.length=0;
var p = pro.value;
if(p==""){
return;
}
switch(p){
case "河南":
var op1 = document.createElement("option");
op1.value="郑州";
op1.innerText="郑州";
city.appendChild(op1);
break;
case "河北":
var op1 = document.createElement("option");
op1.value="邯郸";
op1.innerText="邯郸";
city.appendChild(op1);
break;
case "山东":
var op1 = document.createElement("option");
op1.value="济南";
op1.innerText="济南";
city.appendChild(op1);
break;
}
}
</script>
</head>
<body>
省:
<select id="pro" onchange="selCity()">
</select>
市:
<select id="city">
</select>
</body>
</html>
3.3 购物车
分析:
1.先搭建ui
2.新增
新增基操:(没有任何限定条件)
添加条件:
1.新增商品时要先判断购物车中是否为空,如果为空直接新增,否则就判断
该商品在购物车中是否存在,如果不存在就新增,如果存在就让数量++;
抛出问题:我要怎么做才能取出 购物车中的每一个商品名称?
可以看出 购物车中的每一个商品名称 都是所属tr的第二个子标签,那么我们可以通过 取出所有的tr,然后在去tr的第二个td子标签。
3.+ - 按钮
4.计算总价,和数量
5.删除一行
6.全选和全不选
7.删除多行
<!DOCTYPE html>
<html>
<head>
<title> new document </title>
<meta charset="gbk"/>
<script type="text/javascript">
// 1.创建购物车UI(user interface)用户界面
// 2.功能实现
/*
a. 添加商品
a1: 直接添加
a2: 如果添加商品存在的时候,进行数量累加
b. 调整数量,计算小计
b1: 通过"+","-"调整数量
b2: 通过文本框输入调整数量(数据校验),通过文本框的onblur(失焦)事件处理
c. 汇总合计(汇总选择商品的总价)
d. 删除(单行删除)
e. 选择部分商品(全选/部分选择/反选)
f. 批量删除多个商品
*/
</script>
</head>
<body>
<div style="width:800px;height:500px;margin:10px auto;border:1px solid black">
<!--商品信息部分-->
<fieldset>
<legend>商品信息</legend>
<form name="frmGoods">
<!--
name属性用于向服务器传值的时候,做数据标识
id属性用于在js中获取元素的查找条件
使用元素名访问元素对象:frmGoods(表单名).goodsName(元素名)
使用元素的id名访问元素对象: goodsName(元素id)
-->
品名:<input type="text" name="goodsName" id="goodsName"/>
单价:<input type="text" name="goodsPrice" id="goodsPrice"/>
数量:<input type="text" name="qty" id="qty"/>
<input type="button" value="添加商品" onclick="addGoods()"/>
</form>
</fieldset>
<fieldset>
<legend>购物车</legend>
<table border="1" width="100%" >
<thead>
<tr>
<th>
全选
<input type="checkbox" name="ckAll" id="ckAll"/>
</th>
<th>品名</th>
<th>单价</th>
<th>数量</th>
<th>小计</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tby">
</tbody>
</table>
合计:<span id="total"></span>
</fieldset>
</div>
<script type="text/javascript">
// 点击按钮添加商品
/*
1.获取商品信息表单填写的数据:品名,单价,数量
2.拼接6个td的字符串,添加tr对象中,最终将tr添加到tbody中
*/
function addGoods(){
//1. 获取商品信息
// goodsName.value:通过id属性直接获取对象,并访问对象的value属性
var gname = goodsName.value;
var gprice = goodsPrice.value;
var gqty = qty.value;
//alert(gname+" "+gprice+" "+gqty);
//2 拼接表格行中的6个td字符串
var str = ""; //定义变量,累加拼接每个td字符串
// 第1个td:复选框
str += "<td><input type='checkbox' name='ckgoods'/></td>";
// 第2个td:品名
str += "<td>" + gname + "</td>";
// 第3个td:单价
str += "<td>"+gprice+"</td>";
// 第4个td:数量(两个按钮和一个文本框)
str += "<td>" +
"<input type='button' value='+' onclick='addQty(this)' />"+
"<input type='text' value='"+gqty+"' onblur='changeQty(this)' /> "+
"<input type='button' value='-' onclick='subQty(this)' />"+
"</td>";
// 第5个td:小计
str += "<td>"+gqty*gprice+"</td>";
// 第6个td
str += "<td><input type='button' value='删除' onclick='del(this)'/></td>";
// 创建tr元素对象
var tr = document.createElement("tr");
// 设置tr的内容为拼接的td字符串
tr.innerHTML=str;
// 将tr添加到tbody中
// append(添加)Child(子元素)
tby.appendChild(tr);
//更新总计
sum();
}
// 点击加号按钮调整数量
function addQty(btnQty){
// 1.通过点击的按钮对象找到数量文本框,获取文本框的数据
var txtQty = btnQty.nextElementSibling;
txtQty.value++; // 文本框的值自增
// 2.数量变化引起小计变化: 获取单价,计算小计
var price = Number(btnQty.parentNode.previousElementSibling.innerText);
alert(price);
var money = price*txtQty.value;
// 设置小计内容
btnQty.parentNode.nextElementSibling.innerText=money;
//更新总计
sum();
}
// 点击减号按钮调整数量
// 点击加号按钮调整数量
function subQty(btnQty){
// 1.通过点击的按钮对象找到数量文本框,获取文本框的数据
var txtQty = btnQty.previousElementSibling;
txtQty.value--; // 文本框的值自增
// 2.数量变化引起小计变化: 获取单价,计算小计
var price = Number(btnQty.parentNode.previousElementSibling.innerText);
//alert(price);
var money = price*txtQty.value;
// 设置小计内容
btnQty.parentNode.nextElementSibling.innerText=money;
//更新总计
sum();
}
// 文本框输入数量之后,光标离开时(失焦),调整数量
// onblur:触发失焦事件 onfoucs:获得焦点
function changeQty(txt){
// 将文本框的内容转为数值
var qty = Number(txt.value);
// 如果转换后不是一个数值
if(isNaN(qty)){
//提示错误
alert("输入的数据不是数值");
// 终止方法执行
return;
}
//如果数值超出范围要提示错误
if(qty<=0 || qty>100){
alert("数值必须是1-100");
return;
}
// 测试文本框的数据
//alert(txt.value);
// 1.获取单价
var price= txt.parentNode.previousElementSibling.innerText;
// 2.计算小计
var money = price*qty; //单价*文本框的数量
// 3.将金额设置到小计单元格中
txt.parentNode.nextElementSibling.innerText=money;
//更新总计
sum();
}
// 删除一行
function del(btnQty){
// 判断是否确定删除
if(confirm('确定删除?')){
//btnQty.parentNode:父级元素td .parentNode td的父级元素tr
btnQty.parentNode.parentNode.remove();
//更新总计
sum();
}
}
// 合计:汇总所有的小计
function sum(){
// 获取所有的tr行
//tby.children :通过tbody元素获取下面的tr数组
var trAry = tby.children;
// 遍历tr,找到tr中的小计td单元格,取出数据
var zongji = 0;
for(var i=0;i<trAry.length;i++){
// 取出当前遍历到的数组中的一个tr
var tr = trAry[i];
// 通过tr,获取tr中下标为4的小计单元格,取出数据
// tr.children: tr这一行的td数组(子元素数组)
// tr.children[4]:取出数组中下标为4的元素:小计单元格元素
var xj = Number(tr.children[4].innerText);
// 累加小计到zongji变量
zongji+=xj;
}
// 将累加后的数据设置到汇总标签上
total.innerText = zongji;
}
</script>
</body>
</html>
3.3 模板法
简化代码,比jQuery的DOM操作还要简单。
1.创建模板
<!--template:模板。模板中都是普通的字符串-->
<script type="text/template" id="tmp">
<h1>TITLE</h1>
<p>姓名:XM</p>
<p>性别:XB</p>
<p>年龄:NL</p>
<p>身高:SG</p>
</script>
2.读取模板,并替换模板中的内容
<script type="text/javascript">
var v = "";
v +="<h1>"+"自我介绍"+"</h1>";
v +="<p>姓名: "+"张三"+"</p>"
//alert(tmp.innerHTML);
// repalce(旧,新) : 替换
var str = tmp.innerHTML.replace("TITLE","个人介绍")
.replace("XM","张三")
.replace("XB","男")
.replace("NL","20")
.replace("SG","1.7");
alert(str);
</script>
3.模板法购物车(新增)
<script type="text/template" id="tmp">
<td>
<input type="checkbox" name='ckgoods'/>
</td>
<td>SPM</td>
<td>DJ</td>
<td>
<input type="button" value="+" onclick="changeQty(this)"/>
<input type="text" value='SL'/>
<input type="button" value='-' onclick="changeQty(this)"/>
</td>
<td>XJ</td>
<td>
<input type="button" value="删除"/>
</td>
</script>
var tds = "";
tds = tmp.innerHTML.replace("SPM",goodsName.value)
.replace("DJ",goodsPrice.value)
.replace("SL",goodsQty.value)
.replace("XJ",
Number(goodsPrice.value)*Number(goodsQty.value))
第四节 js对象 json对象 json字符串
4.1 js对象
js对象: 具有一堆属性和方法的数据,被称为js对象
// 简单数据
var v1 = 123;
var v2 = "张三";
var v3 = 2.34;
// js对象数据: 要存储一个学生数据,包含姓名,性别,年龄,身高
// 一个变量存储了一堆信息
var stu = {name:"张三",sex:"男",tall:1.7,age:20,phone:"13112345678"}
js对象语法
var js对象变量 = {
属性名1:数据1,
属性名2:数据2,
...
属性名3:数据,
函数名:匿名函数
}
说明: js对象用大括号包括起来,属性和值之间用冒号分隔,多个属性值之间用逗号分隔。js对象除了定义属性还可以定义函数。
举例
<script type="text/javascript">
// js对象
var stu = {
name:"张三",
sex:"男",
age:20,
tall:1.7,
show:function(){
alert(this.name+" "+this.sex+" "+this.age+" "+this.tall);
}
}
//alert(stu.name); // 使用 . 操作符 访问属性值
//alert(stu.sex);
//alert(stu["age"]); // 使用属性下标范文属性值
//alert(stu["tall"]);
stu.show(); // 调用对象函数
</script>
4.2 json对象
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
语法:
var json对象变量 = {
"属性名1":值1,
"属性名2":值2,
...
"属性名3":值3
}
说明: json对象用大括号包括起来,属性和值之间用冒号分隔,多个属性值之间用逗号分隔。json对象的属性名必须用双引号括起来(不能用单引号),而且在json对象中不能定义函数。
<script type="text/javascript">
// json对象
var stu = {
"name":"张三",
"sex":"男",
"age":20,
"tall":1.7
}
// alert(stu.name+" "+stu.sex+" "+stu["age"]+" "+stu["tall"]);
// json字符串:具有json对象格式的字符串称为json字符串
var stuStr = '{"name":"张三","sex":"男","age":20,"tall":1.7}';
//alert(typeof(stu));
//alert(typeof(stuStr));
// json字符串是在网络中传输数据是采用的格式,但是接收到json字符串
// 之后,要转为json对象,才能访问里面的属性数据
// JSON.parse(json字符串): 将json字符串转为json对象
// JSON:是js中的内置对象,专门处理json数据
//var v = JSON.parse(stuStr); // 将json字符串转为json对象
//alert(v.name); // 访问json对象中的属性
// json字符串====> json对象 用 JSON.parse(字符串)
// json对象 ====> json字符串 用 JSON.stringify(json对象)
var s = JSON.stringify(stu);
alert(s+" "+typeof(s));
</script>
<!DOCTYPE html>
<html>
<head>
<title> new document </title>
<style type="text/css">
</style>
</head>
<body>
<fieldset>
<legend>商品信息</legend>
<table border="1">
<thead>
<tr>
<th>编号</th>
<th>名字</th>
<th>价格</th>
<th>添加</th>
</tr>
</thead>
<tbody id="my">
<!--
<tr>
<td>1001</td>
<td>榴莲</td>
<td>3.5</td>
<td>
<input type="button" value="添加"/>
</td>
</tr>
-->
</tbody>
</table>
</fieldset>
<fieldset>
<legend>购物车</legend>
<input type="button" value="批量删除" onclick='delBatch()'/>
<table border="1">
<thead>
<tr>
<th>
<input type="checkbox" name="ckAll" id="ckAll" onclick="checkAll(this)"/>
全选/全不选
</th>
<th>商品名</th>
<th>单价</th>
<th>数量</th>
<th>小计</th>
<th>操作</th>
</tr>
</thead>
<tbody id="mytbody">
<!--
<tr>
<td>
<input type="checkbox" name='ckgoods'/>
</td>
<td>火腿肠</td>
<td>3</td>
<td>
<input type="button" value="+"/>
<input type="text" value='3'/>
<input type="button" value='-'/>
</td>
<td>9</td>
<td>
<input type="button" value="删除"/>
</td>
</tr>
-->
</tbody>
</table>
<b>总价:</b> <span id="totalMoney">9</span> 元
</fieldset>
<script type="text/javascript">
// 生成商品列表
// 定义json数组,存储水果列表
// []:数组 {}:json对象
var fruits = [
{"id":1001,"name":"榴莲","price":3.5},
{"id":1002,"name":"苹果","price":1.8},
{"id":1003,"name":"香蕉","price":1.2},
];
for(var i=0;i<fruits.length;i++){
var f = fruits[i]; // 访问数组中的某个对象
//document.write("编号:"+f.id+" 名字:"+f.name+" 价格:"+f.price+"<br/>");
var tds = "";
tds += "<td>"+f.id+"</td>";
tds +="<td>"+f.name+"</td>";
tds +="<td>"+f.price+"</td>";
tds +="<td><input type='button' value='添加' onclick='addGoods(this)' /></td>";
var tr = document.createElement("tr");
tr.innerHTML=tds;
my.appendChild(tr);
}
// 购物车相关操作
// 添加商品
function addGoods(btnObj){
// 通过点击的按钮,找到商品编号,名字,价格,数量固定为1
var tr = btnObj.parentNode.parentNode;
/*alert(tr.children[0].innerText+" "+
tr.children[1].innerText+" "+
tr.children[2].innerText);*/
var tds = "";
tds += "<td><input type='checkbox' name='ckgoods'/></td>";
tds += "<td>"+tr.children[1].innerText+"</td>";
tds += "<td>"+tr.children[2].innerText+"</td>";
tds += "<td>"+
"<input type='button' value='+' onclick='changeQty(this)' />" +
"<input type='text' value='1' onblur='updateQty(this)' />" +
"<input type='button' value='-' onclick='changeQty(this)' />" +
"</td>";
tds += "<td>"+Number(tr.children[2].innerText)*1+"</td>";
tds += "<td><input type='button' value='删除' onclick='del(this)' /> </td>";
// 输出拼接好的td字符串
alert(tds);
// 创建tr对象
var tr = document.createElement("tr");
// 将拼接好的td字符串设置到tr中
tr.innerHTML = tds;
// 将tr对象,添加到表格的tbody中
mytbody.appendChild(tr);
}
</script>
</body>
</html>