最开始实现某一项功能的时候,结构、样式和行为是混在一起的。
本来写代码就是为了让自己和别人看明白,这样做的缺点很明显,不方便查看和修改。
1、结构、样式、行为不分离
所有的浏览器都支持这样的写法。例如下面的网页,表格内的奇数行和偶数行有不同的样式,类似斑马线,同时鼠标在不同的行上移入和移出对应的行有不同的样式表现,点击删除按钮有删除表格行的功能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript->JavaScript事件代理</title>
</head>
<body>
<div id="demo">
<h1 align="center">学生成绩表</h1>
<table cellpadding=2 cellspacing=2 style="margin:0 auto;text-align:center;background-color: #cccccc;">
<tr style="line-height: 200%;background-color: #818080;color: rgb(232, 232, 232);text-align: center;">
<td style="width: 100px;">学号</td>
<td style="width: 100px;">姓名</td>
<td style="width: 100px;">语文</td>
<td style="width: 100px">数学</td>
<td style="width: 100px">平均分</td>
<td style="width: 100px">操作</td>
</tr>
<tr style="line-height: 200%;background-color: #f8f8f8;color: rgb(128, 128, 128);text-align: center;" onmouseenter="funcMouseenter(this);" onmouseout="funcMouseout(this)">
<td style="width: 100px;">101</td>
<td style="width: 100px;">小明</td>
<td style="width: 100px;">81.5</td>
<td style="width: 100px">87</td>
<td style="width: 100px">84.25</td>
<td style="width: 100px"><button onclick="del(this)">删除</button></td>
</tr>
<tr style="line-height: 200%;background-color: #efefef;color: rgb(8, 8, 8);text-align: center;" onmouseenter="funcMouseenter(this)" onmouseout="funcMouseout(this)">
<td style="width: 100px;">102</td>
<td style="width: 100px;">小黄</td>
<td style="width: 100px;">61</td>
<td style="width: 100px">47.5</td>
<td style="width: 100px">54.25</td>
<td style="width: 100px"><button onclick="del(this)">删除</button></td>
</tr>
<tr style="line-height: 200%;background-color: #f8f8f8;color: rgb(128, 128, 128);text-align: center;" onmouseenter="funcMouseenter(this)" onmouseout="funcMouseout(this)">
<td style="width: 100px;">103</td>
<td style="width: 100px;">小丽</td>
<td style="width: 100px;">89</td>
<td style="width: 100px">83</td>
<td style="width: 100px">86</td>
<td style="width: 100px"><button onclick="del(this)">删除</button></td>
</tr>
<tr style="line-height: 200%;background-color: #efefef;color: rgb(8, 8, 8);text-align: center;" onmouseenter="funcMouseenter(this)" onmouseout="funcMouseout(this)">
<td style="width: 100px;">104</td>
<td style="width: 100px;">小宋</td>
<td style="width: 100px;">56</td>
<td style="width: 100px">97</td>
<td style="width: 100px">76.5</td>
<td style="width: 100px"><button onclick="del(this)">删除</button></td>
</tr>
<tr style="line-height: 200%;background-color: #f8f8f8;color: rgb(128, 128, 128);text-align: center;" onmouseenter="funcMouseenter(this)" onmouseout="funcMouseout(this)">
<td style="width: 100px;">105</td>
<td style="width: 100px;">小王</td>
<td style="width: 100px;">82</td>
<td style="width: 100px">73</td>
<td style="width: 100px">77.5</td>
<td style="width: 100px"><button onclick="del(this)">删除</button></td>
</tr>
<tr style="line-height: 200%;background-color: #efefef;color: rgb(8, 8, 8);text-align: center;" onmouseenter="funcMouseenter(this)" onmouseout="funcMouseout(this)">
<td style="width: 100px;">106</td>
<td style="width: 100px;">小李</td>
<td style="width: 100px;">31</td>
<td style="width: 100px">63</td>
<td style="width: 100px">47</td>
<td style="width: 100px"><button onclick="del(this)">删除</button></td>
</tr>
<tr style="line-height: 200%;background-color: #f8f8f8;color: rgb(128, 128, 128);text-align: center;" onmouseenter="funcMouseenter(this)" onmouseout="funcMouseout(this)">
<td style="width: 100px;">107</td>
<td style="width: 100px;">小华</td>
<td style="width: 100px;">49</td>
<td style="width: 100px">83</td>
<td style="width: 100px">66</td>
<td style="width: 100px"><button onclick="del(this)">删除</button></td>
</tr>
</table>
</div>
</body>
<script>
function funcMouseenter(obj){
obj.style="line-height: 200%;background-color: #999;color:#d70008;text-align: center";
}
function funcMouseout(obj){
var studentID=obj.cells[0].innerHTML;
if(parseInt(studentID)%2==0){
obj.style="line-height: 200%;background-color: #efefef;color: rgb(8, 8, 8);text-align: center;"
}else{
obj.style="line-height: 200%;background-color: #f8f8f8;color: rgb(128, 128, 128);text-align: center;"
}
}
function del(obj){
var tr = obj.parentNode.parentNode;
var studentID=tr.cells[0].innerHTML;
var flag = confirm("确认删除学号为" + studentID + "记录吗?");
if(flag) {//确认删除
//从数据库中删除学号为studentID
//delFromDB
tr.parentNode.removeChild(tr);//删除tr
}
// console.log(studentID);
//return false
//如果这个删除命令是通过点击超级链接来的,那么超级链接的默认行为是跳转页面,如果不希望跳转,那么return false就可以取消默认行为
}
</script>
</html>
结果图:
2、使用JavaScript完成样式和行为
将样式从网页结构中剥离出来,使用JavaScript代码来完成,这样稍微改进了一下网页结构和样式的组织方式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript->JavaScript事件代理</title>
</head>
<body onload="init()">
<div id="demo">
<h1 align="center">学生成绩表</h1>
<table cellpadding=2 cellspacing=2 style="margin:0 auto;text-align:center;background-color: #cccccc;" id="studentTable">
<tr style="line-height: 200%;background-color: #808080;color: rgb(232, 232, 232);text-align: center;">
<td style="width: 100px;">学号</td>
<td style="width: 100px;">姓名</td>
<td style="width: 100px;">语文</td>
<td style="width: 100px">数学</td>
<td style="width: 100px">平均分</td>
<td style="width: 100px">操作</td>
</tr>
<tr>
<td>101</td>
<td>小明</td>
<td>81.5</td>
<td>87</td>
<td>84.25</td>
<td><button id=1>删除</button></td>
</tr>
<tr>
<td>102</td>
<td>小黄</td>
<td>61</td>
<td>47.5</td>
<td>54.25</td>
<td><button id=2>删除</button></td>
</tr>
<tr>
<td>103</td>
<td>小丽</td>
<td>89</td>
<td>83</td>
<td>86</td>
<td><button id=3>删除</button></td>
</tr>
<tr>
<td>104</td>
<td>小宋</td>
<td>56</td>
<td>97</td>
<td>76.5</td>
<td><button id=4>删除</button></td>
</tr>
<tr>
<td>105</td>
<td>小王</td>
<td>82</td>
<td>73</td>
<td>77.5</td>
<td><button id=5>删除</button></td>
</tr>
<tr>
<td>106</td>
<td>小李</td>
<td>31</td>
<td>63</td>
<td>47</td>
<td><button id=6>删除</button></td>
</tr>
<tr>
<td>107</td>
<td>小华</td>
<td>49</td>
<td>83</td>
<td>66</td>
<td><button id=7>删除</button></td>
</tr>
</table>
</div>
</body>
<script>
function init(){
//设置表格的行和列的样式
var tableObj = document.getElementById("studentTable");
for (var i = 1; i < tableObj.rows.length; i++) { //遍历表格的所有行,表头除外;表头为0
// studentId=tableObj.rows[i].cells[0].innerText;//获取学号
tableObj.rows[i].onmouseenter=function(){this.style="line-height: 200%;background-color: #999;color:#d70008;text-align: center";};
tableObj.rows[i].onmouseout=function(){ funcMouseout(this); };
if(parseInt(i)%2==0){
//偶数行
tableObj.rows[i].style="line-height: 200%;background-color: #efefef;color: rgb(8, 8, 8);text-align: center";
}else{
//奇数行
tableObj.rows[i].style="line-height: 200%;background-color: #f8f8f8;color: rgb(128, 128, 128);text-align: center";
}
//获得按钮
// var btn=tableObj.rows[i].cells[5].innerHTML;
// console.log(btn);
// btn.onclick=function(){ console.log("删除"); };
for (var j = 0; j < tableObj.rows[i].cells.length; j++) { //遍历Row中的每一列
tableObj.rows[i].cells[j].style="width: 100px;";
}
}
var btn=document.getElementsByTagName('button');
for(var i=0;i<btn.length;i++){
btn[i].onclick=function(){ del(this); };
}
}
function funcMouseenter(obj){
obj.style="line-height: 200%;background-color: #999;color:#d70008;text-align: center";
}
function funcMouseout(obj){
var studentID=obj.cells[0].innerText;
if(parseInt(studentID)%2==0){
obj.style="line-height: 200%;background-color: #efefef;color: rgb(8, 8, 8);text-align: center;"
}else{
obj.style="line-height: 200%;background-color: #f8f8f8;color: rgb(128, 128, 128);text-align: center;"
}
}
function del(obj){
var tr = obj.parentNode.parentNode;
console.log(tr);
var studentID=tr.cells[0].innerHTML;
var flag = confirm("确认删除学号为" + studentID + "记录吗?");
if(flag) {//确认删除
//从数据库中删除学号为studentID
//delFromDB
tr.parentNode.removeChild(tr);//删除tr
}
//return false
}
</script>
</html>
上面也可以完成同样的功能,但仍然不方便查看。
3、结构、样式、行为分离
将结构、样式、行为剥离出来,各自放入一个文件,方便查看和修改。
①网页文件:(JavaScript事件代理3.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript事件代理</title>
<link rel="stylesheet" href="JavaScript事件代理.css">
<script src="JavaScript事件代理.js"></script>
</head>
<body onload="init()">
<div id="demo">
<h1 align="center">学生成绩表</h1>
<table align="center" class="table" bgcolor="#cccccc" id="studentTable">
<tr class="rowTitleColorSet">
<td>学号</td>
<td>姓名</td>
<td>语文</td>
<td>数学</td>
<td>平均分</td>
<td>操作</td>
</tr>
</table>
</div>
</body>
</html>
②、样式文件(JavaScript事件代理.css)
.table {
cellpadding:2;
cellspacing:2;
}
.table tr{
line-height:200%;
}
.table td{
width: 100px;
}
.rowTitleColorSet{background-color: #818080;color: rgb(232, 232, 232);text-align: center;}
.evenRowColorSet{background-color: #efefef;color: rgb(8, 8, 8);text-align: center}
.oddRowColorSet{background-color: #f8f8f8;color: rgb(128, 128, 128);text-align: center}
.focusRowColorSet{background-color: #999;color:#d70008;text-align: center}
③、脚本文件:(JavaScript事件代理.js)
function init(){
//创建studentList对象
var studentList=[
{Id:101,Name:'小明',ChineseScore:81.5,MathScore:87},
{Id:102,Name:'小黄',ChineseScore:61,MathScore:47.5},
{Id:103,Name:'小丽',ChineseScore:89.5,MathScore:83},
{Id:104,Name:'小宋',ChineseScore:56,MathScore:97},
{Id:105,Name:'小王',ChineseScore:82,MathScore:73},
{Id:106,Name:'小李',ChineseScore:31,MathScore:63},
{Id:107,Name:'小华',ChineseScore:49,MathScore:83},
]
//生成表格
for(item in studentList){
//第一步:创建td
//创建学号td并加入到表格行
var tdId=document.createElement("td");
tdId.style="width: 100px;";
tdId.appendChild(document.createTextNode(studentList[item].Id));
//创建姓名td
var tdName=document.createElement("td");
tdName.style="width: 100px;";
tdName.appendChild(document.createTextNode(studentList[item].Name));
//创建语文td
var tdChineseScore=document.createElement("td");
tdChineseScore.style="width: 100px;";
tdChineseScore.appendChild(document.createTextNode(studentList[item].ChineseScore));
//创建数学td
var tdMathScore=document.createElement("td");
tdMathScore.style="width: 100px;";
tdMathScore.appendChild(document.createTextNode(studentList[item].MathScore));
//创建平均分td
var tdAverageScore=document.createElement("td");
tdAverageScore.style="width: 100px;";
AverageScore=(studentList[item].MathScore+studentList[item].MathScore)/2;
tdAverageScore.appendChild(document.createTextNode( AverageScore ));
//创建按钮
var tdbtn=document.createElement("td");
tdbtn.style="width: 100px;";
var btn=document.createElement('input');
btn.type="button";
btn.id=item;
btn.value="删除";
btn.onclick=function(){ del(this); };
tdbtn.appendChild( btn );
//第二步:生成tr
var tr=document.createElement("tr");
//设置行样式
if(parseInt(item)%2==0){
tr.className="evenRowColorSet"
}else{
tr.className="oddRowColorSet"
}
tr.appendChild(tdId);
tr.appendChild(tdName);
tr.appendChild(tdChineseScore);
tr.appendChild(tdMathScore);
tr.appendChild(tdAverageScore);
tr.appendChild(tdbtn);
//给行添加事件响应
tr.onmouseenter=funcMouseenter;//鼠标移入事件
tr.onmouseout=funcMouseout;//鼠标移出事件
//第三步:生成表格
//var table=document.getElementsByTagName("table")[0];//也可以但不建议使用
var table=document.getElementById("studentTable");
table.appendChild(tr);
}
}
function funcMouseenter(event){
this.className='focusRowColorSet'
}
function funcMouseout(event){
var studentID=this.cells[0].innerHTML;
if(parseInt(studentID)%2==0){
this.className="evenRowColorSet"
}else{
this.className="oddRowColorSet"
}
}
function del(obj){
var tr = obj.parentNode.parentNode;
console.log(tr);
var studentID=tr.cells[0].innerHTML;
var flag = confirm("确认删除学号为" + studentID + "记录吗?");
if(flag) {//确认删除
//从数据库中删除学号为studentID
//delFromDB
tr.parentNode.removeChild(tr);//删除tr
}
//return false
}
4、改进事件的挂载方式
上面的事件挂载属于赋值的方式,因为事件也是值,后面的挂载事件必然会改写前面的挂载事件,这对代码的组织不友好。
使用下面的方式进行:
domObj.addEventListener(eventType,func,eventModule)
eventType:事件类型,不要加on。
func:事件发生后的回调函数。
eventModule:boolean值,代表事件模型,false代表冒泡模型,true代码捕获模型,默认是false。
这样的方式属于面向对象的方式挂载事件,后面的挂载不会影响到前面的挂载。
为按钮挂载事件:btn.addEventListener('click',function(){ del(this); })
function del(obj){
var tr = obj.parentNode.parentNode;
console.log(tr);
var studentID=tr.cells[0].innerHTML;
var flag = confirm("确认删除学号为" + studentID + "记录吗?");
if(flag) {//确认删除
//从数据库中删除学号为studentID
//delFromDB
tr.parentNode.removeChild(tr);//删除tr
}
//return false
}
为表格行挂载事件:
tr.addEventListener('mouseenter',function(){ funcMouseenter(this); })
tr.addEventListener('mouseout',function(){ funcMouseout(this); })
function funcMouseenter(obj){
obj.className='focusRowColorSet'
}
function funcMouseout(obj){
var studentID=obj.cells[0].innerHTML;
if(parseInt(studentID)%2==0){
obj.className="evenRowColorSet"
}else{
obj.className="oddRowColorSet"
}
}
学习和掌握这些基本操作对学习JQuery、Vue.js、BootStrap等前端架构很有帮助,因为这些WebAPI都是它们所依赖的,只是它们进行了封装。