核心知识点:
1.BOM(浏览器窗口对象模型) DOM(文本对象模型)
2.window对象是客户端JavaScript最高层对象之一,属于全局对象,一般书写可以省略
3.window对象常用的方法
(1)窗口对象方法
(2)子对象方法
a.navigator对象(一般用于读取浏览器信息)
b.screen对象
c.history对象(forward back go)
d.location对象(reload href)
4.DOM:是一套对文档抽象和概念化的一种方法,可以说是一个应用程序接口
5.节点种类:文档、元素、文本、属性、注释
6.查找标签:
a.直接查找(通过ID、className、Name、TagName)
b.间接查找(父-子-兄)
7.属性节点操作方法:
a.attributes、getAttribute、setAttribute
8.文本节点操作方法:
a.修改文本信息
ele.innerText 获取文本节点内容
ele.innerText="字符串" 修改标签的文本信息
b.文档内容(HTML内容)
ele.innerHTML 获取文档内容
ele.innerHTML="<h1>hao</h1>" 赋值HTML内容
9.样式操作:
a.操作class类(className/calssList.[remove/add/contains/toggle])
b.指定CSS操作:obj.style.backgroundColor = "red"直接指定元素进行修改
10.事件
a.常用事件(onclick onfocus onchange onkeydown onload onselect )
b.事件的绑定
(1) 在标签里面直接写on动作=func();
(2)通过JS代码绑定事件 ele.click=function(){alert(123);}
(3)基于已经存在的父标签来给子标签绑定事件, --> 事件委托的方式
之前我们已经学过了JavaScript的一些简单的语法。但是这些简单的语法并没有和浏览器有任何交互,本章将介绍一些DOM和BOM的相关知识。
JavaScript分为ECMAScript、DOM、BOM。
BOM(Browser Object Model)是指浏览器窗口对象模型,顶级对象是window。
DOM(Document Object Model)是指文档对象模型,并非一个对象。
window、document都是一个实例对象,他们都属于Object,表示浏览器中打开窗口。
Window对象是客户端JavaScript最高层对象之一,由于window对象是其它大部分对象的共同祖先,
在调用window对象的方法和属性时,可以省略window对象的引用。例如:window.document.write()可以简写成:document.write().
一、BOM——window对象
window对象表示一个浏览器窗口。
在客户端JavaScript中,window对象是全局对象,所有的表达式都是在当前的环境中计算。
也就是说,要引用当前窗口根本不需要特殊的语法,可以把那个窗口的属性作为全局变量来使用。例如,可以只写document,而不必写window.document。
1.窗口对象常用方法
同样,可以把当前窗口对象的方法当作函数来使用,如只写alert(),而不必写window.alert()。
方法 | 功能 |
alert() | 显示带有一段消息和一个确认按钮的警告框 |
setInterval() | 按照指定的周期(以毫秒计)来调用函数或计算表达式 |
clearInterval() | 取消由setInterval()设置的timeout |
setTimeout() | 在指定的毫秒数后调用函数或计算表达式 |
clearTimeout() | 取消由setTimeout()方法设置的timeout |
scrollTo() | 把内容滚动到指定的坐标 |
confirm() | 显示带有一段消息以及确认按钮的对话框。 |
prompt() | 显示可提示用户输入的对话框 |
open() | 打开一个新的浏览器窗口或查找一个已命名的窗口 |
close() | 关闭浏览器窗口 |
2.window的子对象
1)navigator对象
- navigator.appName:Web浏览器全称
- navigator.appVersion:Web浏览器厂商和版本的详细字符串
- navigator.userAgent:客户端绝大部分信息
- navagator.platform:浏览器运行所在的操作系统
navigator.appName "Netscape" <--一般是网景公司--> navigator.appVersion "5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36" navigator.userAgent "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36" navigator.platform "Win32"
2)screen对象(屏幕对象,不常用)
3)history对象
浏览历史对象,包含了用户对当前页面的浏览历史,但我们无法查看具体的地址,可以用来前进或后退一个页面。
- history.forward():前进一页
- history.back:后退一页
- history.go(n):前进n页
4)location对象
- location.href:获取URL
- location.href="URL":跳转到指定页面
- location.reload():重新加载页面
二、DOM
DOM(Document Object Model)是一套对文档的内容进行抽象和概念化的方法。
它是一个与系统平台和编程语言无关的接口,程序和脚本可以通过这个接口动态地对文档的内容、结构和样式进行访问和修改。
简单来讲,DOM是一种API(应用程序接口)。
JavaScript对DOM进行了实现,对应于JavaScript中的document对象,通过对象对DOM文档进行程序级别的控制。
DOM标准规定HTML文档中的每个成分都是一个节点(node):
- 文档节点(document对象):代表整个文档
- 元素节点(element对象):代表一个元素(标签)
- 文本节点(text对象):代表元素(标签)中的文本
- 属性节点(attribute对象):代表一个属性,元素(标签)才有属性
- 注释是注释节点(comment对象)
1.查找标签
- document.getElementById
- document.getElementsByName
- document.getElementsByClassName
- document.getElementsByTagName
<--源码--> <div class="c1"> <div><p id="p1">标签1</p></div> <div class="c2">标签2</div> <div class="c3">标签3</div> </div> <--查找--> document.getElementById("p1") <p id="p1">标签1</p> document.getElementsByClassName("c2") [div.c2] document.getElementsByTagName("P") [p#p1, p1: p#p1]
2.间接查找
命令 | 功能 |
parentNode | 父节点 |
childNodes | 所有子节点 |
firstChild | 第一个子节点 |
lastChild | 最后一个子节点 |
nextSibling | 下一个兄弟节点 |
previousSibling | 上一个兄弟节点 |
parentElement | 父节点标签元素 |
children | 所有子标签 |
firstElementChild | 第一个子标签元素 |
lastElementChild | 最后一个子标签元素 |
nextElementSibling | 下一个兄弟标签元素 |
previousElementSibling | 上一个兄弟标签元素 |
<--代码--> <hl>DOM文档结构</hl> <div class="c1"> <div><p id="p1">标签1</p></div> <div class="c2">标签2</div> <div class="c3">标签3</div> </div>222 <div class="c4">标签4</div> <--间接查找--> <--获取c1对象--> var eleC1 = document.getElementsByClassName("c1")[0]; eleC1 <div class="c1">…</div> <--父节点--> eleC1.parentNode <body>…</body> <--所有子节点--> eleC1.childNodes (7) [text, div, text, div.c2, text, div.c3, text] <--第一个子节点--> eleC1.firstChild #text <--最后一个子节点--> eleC1.lastChild #text <--下一个兄弟节点--> eleC1.nextSibling "222 " <--上一个兄弟节点--> eleC1.previousSibling #text <--父节点标签元素--> eleC1.parentElement <body>…</body> <--所有子标签--> eleC1.children (3) [div, div.c2, div.c3] <--第一个子标签元素--> eleC1.firstElementChild <div>…</div> <--最后一个子标签元素--> eleC1.lastElementChild <div class="c3">标签3</div> <--下一个兄弟标签元素--> eleC1.nextElementSibling <div class="c4">标签4</div> <--上一个兄弟标签元素--> eleC1.previousElementSibling <hl>DOM文档结构</hl>
三、document对象的属性和操作
1.属性节点
attributes | 获取所有标签属性 |
getAttributes() | 获取所有标签属性 |
setAttributes() | 设置指定标签属性 |
removeAttribute() | 移除指定标签属性 |
var s= document.creatAttribute("age") s.nodeValue = "18" |
创建age属性,设置属性值为18 |
eleC1.attributes NamedNodeMap {0: class, length: 1} <--查看指定的标签属性--> eleC1.getAttribute("class") "c1" <--修改标签属性--> eleC1.setAttribute("class",'c11'); undefined eleC1.getAttribute("class") "c11" <--移除标签属性--> eleC1.removeAttribute("class"); undefined eleC1.attributes NamedNodeMap {length: 0}
2.文本节点
innerText | 所有的纯文本内容,包含子标签中的文本 |
outerText | 与innerText类似 |
innerHTML | 所有子节点(包括元素、注释与文本节点) |
outerHTML | 返回自身节点与所有子节点 |
textContent | 与innerText类似,返回的内容带样式 |
data | 文本内容 |
length | 文本长度 |
createTextNode() | 创建文本 |
normalize() | 删除文本与文本之间的空白 |
splitText() | 分割 |
appendData() | 追加 |
deleteData(offset,count) | 从offset指定的位置开始删除count个字符 |
insertDara(offset,text) | 在offset指定的位置插入text |
replaceDate(offset,count,text) | 替换,从offset开始到offscount处的文本被text替换 |
substringData(offset,count) | 提取从offset开始到offscount处的文本 |
注意:加粗的部分为常用的部分
eleC1.innerText "标签1 标签2 标签3 " eleC1.outerText "标签1 标签2 标签3 " eleC1.innerHTML " <div><p id="p1">标签1</p></div> <div class="c2" style="color: #CC0000">标签2</div> <div class="c3">标签3</div> " eleC1.outerHTML "<div class="c1"> <div><p id="p1">标签1</p></div> <div class="c2" style="color: #CC0000">标签2</div> <div class="c3">标签3</div> </div>"
3.样式操作
1)操作class类
- className:获取所有样式类名(字符串)
- classList.remove(cls):删除指定类
- classList.add(cls):添加类
- classList.contains(cls):存在返回true,否则返回false
- classList.toggle(cls):存在就删除,否则就添加
eleC1.classList
(4) ["c1", "c12", "c13", "c14", value: "c1 c12 c13 c14"]
eleC1.classList.remove("c13")
undefined
eleC1.classList
(3) ["c1", "c12", "c14", value: "c1 c12 c14"]
eleC1.classList.add("c15");
undefined
eleC1.classList
(4) ["c1", "c12", "c14", "c15", value: "c1 c12 c14 c15"]
eleC1.classList.contains("c14");
true
eleC1.classList.toggle("c16");
true
eleC1.classList
(5) ["c1", "c12", "c14", "c15", "c16", value: "c1 c12 c14 c15 c16"]
实例1:来回切换的功能的实现
<style> .c1 { height: 300px; width: 300px; border-radius: 150px; background-color: red; } .c2 { height: 300px; width: 300px; border-radius: 150px; background-color: yellow; } </style> <script> function change() { //找标签,改变颜色 var d1 = document.getElementById("d1"); //有这个属性就删除,没有就添加,这样就能实现无限切换 d1.classList.toggle("c2") } </script> </head> <body> <div id="d1" class="c1"></div> <input type="button" value="切换" onclick=change()> </body> </html>
效果:
点击切换
可以无限切换,只是暂时改变对象的属性
实例2:简单菜单打印:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta http-equiv="x-ua-compatible" content="IE=edge"> <style> .left { position: fixed; left: 0; top: 0; width: 20%; background-color: #2559a2; height: 100%; } .right { width: 80%; } .tital { text-align: center; padding: 8px 15px; border-bottom: 1px solid red; } .content > div { padding: 7px; background-color: rebeccapurple; color: white; border-bottom: 1px solid black; } .hide { display: none; } </style> <script> //定义一个函数 function show(ths) { //隐藏所有的.content标签 --> classList.add("hide") //1.找标签(所有.content标签),通过class找 var contentEles = document.getElementsByClassName("content"); //节点对象属性 //遍历上面的标签数组 for (var i = 0; i < contentEles.length; i++) { contentEles[i].classList.add("hide") } //如何让函数知道我点的那个菜单(传参数) //显示我下面的content标签 -->classlist.remove("hide") //1.找这个标签下面的content标签,通过查找兄弟标签的方法来进行 var nextEle = ths.nextElementSibling; //2.显示这个content标签 //有就删除,没有就添加 nextEle.classList.toggle("hide"); console.log(nextEle) } </script> </head> <body> <div class="left"> <div class="item1"> <div class="tital" onclick="show(this)">菜单一</div> <div class="content hide"> <div>111</div> <div>222</div> <div>333</div> </div> </div> <!--总结一下思路,当你点击一个菜单的时候,它会把所有content隐藏--> <!--然后根据你点的,查找他们下面的content,然他们显示出来--> <div class="item2"> <div class="tital" onclick="show(this)">菜单二</div> <div class="content hide"> <div>111</div> <div>222</div> <div>333</div> </div> </div> <div class="item3"> <div class="tital" onclick="show(this)">菜单三</div> <div class="content hide"> <div>111</div> <div>222</div> <div>333</div> </div> </div> </div> <div class="right"></div> </body> </html>
效果:指到谁显示谁
2)指定CSS操作
object.style.backgroundColor="green";
JS操作CSS属性的规律
(1).对于没有中横线的CSS属性一般直接使用style属性名即可.如:
obj.style.width
obj.style.left
obj.style.position
(2)对于含有中横线的CSS属性,将中横线后面的第一个字母换成大写即可:
obj.style.marginTop
obj.style.borderLeftWidth
4.事件
HTML DOM使JavaScript有能力对HTML事件做出反应。
我们可以在事件发生时执行Javascript,比如当用户在HTML元素上点击时。
命令 | 功能 |
onclick | 单击对象触发 |
ondblclick | 双击对象触发 |
ofocus | 元素获得焦点 |
onblur | 元素失去焦点 |
onchange | 域的内容被改变 |
onkeydown | 某个键盘按键被按下 |
onkeypress | 某个键盘按键被按下并松开 |
onkeyup | 某个键盘按键被松开 |
onload | 进入或离开界面 |
onselect | 文本框中的文本被选中 |
onsubmit | 确认按钮被点击,使用的对象是form |
onmousedown | 鼠标按钮被按下 |
onmousemove | 鼠标被移到 |
onmouseout | 鼠标从某个元素移开 |
onmouseover | 鼠标移到某个元素之上 |
(1)onclick:当用户点击某个对象时调用的事件句柄。
ondblclick:当用户双击某个对象时调用的事件句柄。
例1:当用户在<h1>元素上点击时,会改变其内容:
<!--点击文本之后就会弹出来一个框,它是直接调用了一个函数--> <hl onclick="f1();">请点击该文本</hl> <script> function f1() { alert("你好!") } </script> <!-- 另一种方式,不需要调用函数--> <!--直接改变结果--> <hl onclick="this.innerHTML='你好'">请点击该文本</hl>
例2:双击一片区域,救护弹出内容:
<!--双击触发事件--> <style> .c1 { height: 300px; width: 300px; background-color: yellow; } </style> <script> function show() { alert(123) } <body> <div class="c1" ondblclick="show();"></div> </body>
(2)onload事件
onload事件会在用户进入或离开页面时被触发。
例1:当进入页面就会弹出一个框。
<!DOCTYPE html> <head> <script> function f1() { var i1Ele = document.getElementById("i1"); alert(i1Ele); //找到标签,弹出框 } </script> </head> <body onload="f1()"> <input type="text" value="哈哈" id="i1"> </body> </html>
(3)onmouseover和onmouseout事件(鼠标移动事件)
onmouseover和onmouseout事件可用于在用户鼠标移至HTML元素上方或移除元素时触发事件。
例1:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta http-equiv="x-ua-compatible" content="IE=edge"> <style> .c1 { height: 150px; width: 300px; background-color: green; text-align: center; line-height: 150px; font-size: 30px; color: white; } </style> </head> <body> <div class="c1" onmouseover="mOver(this);" onmouseout="mOut(this);">请移动鼠标</div> <script> function mOver(obj) { obj.innerHTML="谢谢"; } function mOut(obj) { obj.innerHTML="请把鼠标移到上面"; } </script> </body> </html>
效果:
(4)onfocus和onblur
onfocus:鼠标获得焦点;onblur:鼠标失去焦点
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta http-equiv="x-ua-compatible" content="IE=edge"> </head> <body>姓名: <input type="text" value="请输入姓名" onfocus="f1(this);" onblur="f2(this);"> <script> function f1(ths) { ths.setAttribute("value","") } function f2(ths) { ths.setAttribute("value","请输入姓名") } </script> </body> </html>
效果:
(5)onkeydown:某个键盘按键被按下
应用场景:当用户在最后一个输入框按下回车键时,表单提交
<body onkeydown="f1(event);"> <script> function f1(evt) { alert(evt.keyCode); //按下某个键时,弹出某个代码 } </script> </body>
(6)onselect:在文本框种的内容被选中时发生
<body> <input type="text" value="红烧茄子" onselect="f1();"> <textarea name="" id="" cols="30" rows="10" onselect="f2()"> </textarea> <script> function f1() { alert("真香啊"); } function f2() { alert("再来一盘"); } </script> </body>
(7)onchange:域的内容被改变
应用场景:用于表达元素,当元素内容被改变时触发
<!--自动让输入的字符大写--> 请输入英文字符:<input type="text" id="d1" onchange="f1();"> <script> function f1() { var x = document.getElementById("d1"); x.value=x.value.toUpperCase(); } </script>
5.文档标签常用的增删改查
(1)增
- createElement(name) 创建节点标签
- appendChild() 末尾添加节点,并返回新增节点
- insertBefore() 参照节点之前插入节点,两个参数:要插入的节点和参照节点。
示例1:
<!--已有无序列表--> <div id="d1"> <u1 type="disc" class="c1"> <li>第一项</li> <li>第二项</li> </u1> </div>
现在添加第三项
//先找到c1标签对象
var c1Ele = document.getElementsByClassName("c1")[0]
undefined
//创建一个新的li标签
var liEle = document.createElement("li");
undefined
//重新赋值
liEle.innerText="第三项";
"第三项"
//添加到列表之中
c1Ele.appendChild(liEle);
根据位置来添加
<!--创建需要添加的标签--> var li2Ele = document.createElement("li"); undefined li2Ele.innerText = "选项"; "选项" <!--选取参照物--> var li1 = c1Ele.firstElementChild; <!--添加--> c1Ele.insertBefore(li2Ele,li1)
(2)删:查找到要删除的元素,获取它的父元素,使用removeChild()方法删除
c1Ele.lastChild <li>第三项</li> var ss = c1Ele.lastChild undefined c1Ele.removeChild(ss); <li>第三项</li>
(3)改
第一种方式:使用setAttribute();方法修改属性;
第二种方式:使用innerHTML属性修改元素的内容。
综合示例1:select联动
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta http-equiv="x-ua-compatible" content="IE=edge"> </head> <body> <select name="" id="s1" onclick="loadDate();"> <option value="">请选择省份</option> </select> <select name="" id="s2"> <option value="">请选择省份</option> </select> <script> //script标签一般写在body标签下面,除非是文档加载之前就要运行的代码要放在head标签里 var data = {"河北":["保定","沧州","廊坊"],"湖南":["长沙","湘潭"],"湖北":["武汉","黄石","襄阳"]}; //拿出所有key var str for (var key in data){ var s = "<option>"+key+"</option>"; //使用字符串拼接的方式来创建新的标签 str+=s; //整个select标签累加 var seEle = document.getElementById("s1"); //找到是标签 seEle.innerHTML = str; //给它赋值,省份就显示出来了 } function loadDate() { var s2Ele = document.getElementById("s2"); s2Ele.options.length=0; //首先将每个对象下的文本清空 var indexValue = seEle.selectedIndex; //根据点击的元素去取索引 var optionEles = seEle.options; //所有的省份 var key = optionEles[indexValue].innerText; //得到具体的省份 var data2 = data[key]; //根据省份取下面的市区 for (var i=0;i<data2.length;i++) { var optionEle = document.createElement("option"); //生成一个标签 optionEle.innerText = data2[i]; //给新的标签赋值 s2Ele.appendChild(optionEle); //添加进去 } } </script> </body> </html> <!--思路整理--> 给你一个多重字典,你要把它分级把其中的内容显示出来, 可以循环创建标签,然后加入,最后就会把标签显示出来, 难点就是如何在点其中一个能显示下面的标签,通过什么来练习, 可以知道,系统取元素的时候也是用的索引
综合示例2:事件绑定
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta http-equiv="x-ua-compatible" content="IE=edge"> </head> <body> <ul id="d1"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> <li>11</li> <li>12</li> <li>13</li> <li>14</li> <li>15</li> </ul> <script> //传统写法:点击元素,弹出代表相应元素的框 // var liEles = document.getElementsByTagName("li"); // for (var i=0;i<liEles.length;i++) { // liEles[i].onclick=function () { // alert(this.innerText) // } // } //更好的做法 var ulEle = document.getElementById("d1"); ulEle.onclick=function (event) { // console.log(event.target); var targetEle = event.target; alert(targetEle.innerText); } </script> </body> </html>
综合示例3:定时器示例(在一个input框里面让时间自己跳动,你说停就停,你说开始就开始)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>定时器示例</title> <meta http-equiv="x-ua-compatible" content="IE=edge"> </head> <body> <input type="text" id="i1"> <input type="button" value="开始" onclick="start();"> <input type="button" value="结束" onclick="stop();"> <script> var t; function f1() { //创建一个时间对象 var dateObj = new Date(); //找到ID为i1的那个对象 var ilEle = document.getElementById("i1"); //给它赋值 ilEle.value = dateObj.toLocaleString(); } //每隔一秒就执行一次 function start() { f1(); //只创建一个定时器,避免能同时创建多个定时器,这样会导致停不下来 //怎么解决这个问题了?判断 if (t === undefined) { //指定周期来调用函数,每隔一秒来执行一次,然你感觉时间自己在跳动 t = setInterval(f1, 1000); } } //停止定时 function stop() { //停止函数周期性调用 clearInterval(t); //如果这里不清空,下一次就开始不了 t = undefined; } </script> </body> </html>
综合示例4:多个事件的绑定
如果你想在一个触发上绑定多个事件,你也许会顺序执行,但是可能你不会得到你想要得到的结果。
就像这样:
<input type="button" value="点击" id="d1"> <script> function f1() { alert("你好"); } function f2() { alert("朋友!"); } var c1Ele = document.getElementById("d1"); c1Ele.onclick = function () { f1(); }; c1Ele.onclick = function () { f2(); }; </script>
你会发现只能执行一个事件,那么该如何做才能按照你的意愿来了,你应该这样:
<input type="button" value="点击" id="d1"> <script> function f1() { alert("你好"); } function f2() { alert("朋友!"); } var c1Ele = document.getElementById("d1"); addEventListener("click",f1); addEventListener("click",f2); </script>
综合示例5:表格的编辑
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>周末作业</title> <meta http-equiv="x-ua-compatible" content="IE=edge"> <style> table { text-align: center; } .cover { position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0, 0, 0, 0.3); z-index: 999; } .modal { position: fixed; top: 50%; left: 50%; background-color: whitesmoke; height: 300px; width: 500px; z-index: 1000; margin-left: -250px; margin-top: -150px; z-index: 1000; } .hide { display: none; } </style> </head> <body> <input type="button" id="btn" onclick="showModal();" value="新增"> <div class="cover hide"></div> <div class="modal hide"> <input type="text" class="name"> <input type="text" class="sex"> <input type="button" value="提交" onclick="summitValue();"> <input type="button" value="取消" onclick="modalCancel();"> </div> <table border="1" width="250px"> <thead> <tr> <th>#</th> <th>姓名</th> <th>性别</th> <th>操作</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>科比</td> <td>男</td> <td><input type="button" value="编辑" onclick="edit()"> <input type="button" value="删除"></td> </tr> <tr> <td>2</td> <td>毛线</td> <td>男</td> <td><input type="button" value="编辑" onclick="edit()"> <input type="button" value="删除"></td> </tr> <tr> <td>3</td> <td>小鸟</td> <td>女</td> <td><input type="button" value="编辑" onclick="edit()"> <input type="button" value="删除"></td> </tr> </tbody> </table> <script> var modalEle = document.getElementsByClassName("modal")[0]; var coverEle = document.getElementsByClassName("cover")[0]; //输入框对象 var eleName = document.getElementsByClassName("name")[0]; var eleSex = document.getElementsByClassName("sex")[0]; //新增 function showModal() { //显示背景色 coverEle.classList.remove("hide"); modalEle.classList.remove("hide"); } //取消 function modalCancel() { coverEle.classList.add("hide"); modalEle.classList.add("hide"); eleName.value = ""; eleSex.value = "" } //提交 var val; var n = 4; function summitValue() { if (val === undefined) { //获取tbody这个标签 var eleTbody = document.getElementsByTagName("tbody")[0]; //创建45个标签 var newTr = document.createElement("tr"); var new1 = document.createElement("td"); var new2 = document.createElement("td"); var new3 = document.createElement("td"); var new4 = document.createElement("td"); //赋值 new1.innerText = n; new2.innerText = eleName.value; new3.innerText = eleSex.value; new4.innerHTML = "<input type="button" value="编辑" onclick="edit()"> <input type="button" value="删除">" //添加标签 newTr.appendChild(new1); newTr.appendChild(new2); newTr.appendChild(new3); newTr.appendChild(new4); eleTbody.appendChild(newTr); n++; } else { upEles.innerText = eleSex.value; upUpEles.innerText = eleName.value; val = undefined; } modalCancel(); } //编辑和删除 //事件绑定 function editDel() { var tbodyEles = document.getElementsByTagName("tbody")[0]; tbodyEles.onclick = function (eve) { var targetEle = eve.target; if (targetEle.value === "删除") { //删除 var tdEles = targetEle.parentElement; var trEles = tdEles.parentElement; //找到这行的标签,直接移除 tbodyEles.removeChild(trEles); } else { //编辑 showModal(); //找到标签,先找父标签,然后,找到前面两个字段的值 var ftEles = targetEle.parentElement; upEles = ftEles.previousElementSibling; upUpEles = upEles.previousElementSibling; eleName.value = upUpEles.innerText; eleSex.value = upEles.innerText; //赋值之后,点击提交又会触发提交那个函数 //这里var随便赋一个值 val = 1; } } } editDel(); </script> </body> </html>