不解以下现象:
原始版本代码:可跳过代码直接看解决方案部分。前面的文字是在解决问题时的思考。
<body>
<div id="div1">
<form method="get" action="Demo8_table.html">
<input type = "text" id = "code" >
<input type="text" id = "name">
<input type = "text" id = "sex">
<input type="button" id = "add" value="add">
</form>
</div>
<div id = "div2">
<table id = "table">
<caption>学生信息表</caption>
<tr id = "tr" class="thS">
<th><input type="checkbox" id="firstcheckbox"></th>
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>操作</th>
</tr>
</table>
</div>
<div id = "div3">
</div>
<script>
document.getElementById("firstcheckbox").onclick = function(){
alert("hello");
// 获取所有的复选框
var element = document.getElementsByName("check");
for(var i = 0;i < element.length;i++){
//获取后this为数据源
element[i].checked = true;
}
}
window.document.getElementById(`add`).onclick = function () {
var a = window.document.getElementById("code");
var b = window.document.getElementById("name");
var c = window.document.getElementById("sex");
var code = a.value;
//code为对象类型 其后加上 value获取值
var name = b.value;
var sex = c.value;
var table = document.getElementById("table");
button = "<input type='checkbox' name='check' value='+code+'>";
table.innerHTML += "<tr οnmοuseοver='changeR(this)' οnmοuseοut='changeO(this)'class='thS'>"+"<td>"+button+"</td>"+"<td>"+code+"</td>"+"<td >"+name+"</td>"+"<td>"+sex+"</td>"+"<td>"+"<a href='javascript:void(0);' οnclick='delate(this)' >delete</a>"+"</td>"+"</tr>";
}
function delate(Obj){
//删除行 可以通过获取父标签的方法 获取tr
var getTd = Obj.parentNode;
var getTr = getTd.parentNode;
//获取table
var table = getTr.parentNode;
table.removeChild(getTr);
}
</script>
</body>
这个代码是将script标签放在底部,在文档加载后再执行方法,但对第一个checkbox实现onclick点击事件,且未触碰add事件前,这个点击事件是有效地,触碰之后,发现失效,分析,之所以失效源于在增加table后,自动取消了第一个checkbox的onclick事件。
在询问同学后,他建议我将Element对象的innerHTML更新的方式改为用Node节点的方式,问题得到了解决!
//更新之前:table.innerHTML += "<tr>"+"<td>"+button+"</td>"+"<td>"+code+"</td>"+"<td >"+name+"</td>"+"<td>"+sex+"</td>"+"<td>"+"<a href='javascript:void(0);' οnclick='delate(this)' >delete</a>"+"</td>"+"</tr>";
var tr = document.createElement("tr");
tr.setAttribute("onmouseover","changeR("+this+")");
tr.setAttribute("onmouseout","changeO("+this+")");
tr.setAttribute("class","thS");
var td0 = document.createElement("td");
var in0 = document.createElement("input");
in0.setAttribute("type","checkbox");
in0.setAttribute("id","firstcheckbox");
in0.setAttribute("name","check");
td0.appendChild(in0);
var td1 = document.createElement("td");
td1.appendChild(document.createTextNode(code));
tr.appendChild(td1);
var td2 = document.createElement("td");
td2.appendChild(document.createTextNode(name));
tr.appendChild(td2);
var td3 = document.createElement("td");
td3.appendChild(document.createTextNode(sex));
var td4 = document.createElement("td");
var td5 = document.createElement("a");
td5.setAttribute("href","javascript:void(0);");
td5.setAttribute("onclick","delateE("+this+");");
td5.appendChild(document.createTextNode("delete"));
td4.appendChild(td5);
tr.appendChild(td0);
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
tr.appendChild(td4);
table.appendChild(tr);
但是新的问题又来了,更改前有效的mouseover事件、点击删除超链接可删除一整行的功能却失效了,经过浏览器的错误信息【函数未定义】便知道更新后,函数未一起更新,也就是说JS代码存在着随着动态加载而丢失代码的现象。于是,我查找onclick在设置属性的时候是否和正常的href等有不一样的地方。在当onclick的属性设置为alert时,确实能弹出,因此在使用Node节点对象的触发事件时其它方法还未加载进来。与onclick确实无关,那是什么导致了设置onclick属性调用带形式参数的方法行不通呢?
问题确定下来,onclick在设置事件的属性值的时候,由于是在加载后才引入函数的,而在加载后调用delete时,发现没有delete函数,出现错误。先不寻找原因,那只能尝试一下其他的方法,能不能在函数中创建函数?也像下面这样?
解决方案:
与window.load加载无关,根本在于onclick调用实现带参数的函数需要特别注意!
另注意,innerHTML有风险 可能会出现onclick失效的问题,尽量选择appendChild。
window.document.getElementById('添加元素的按钮ID').onclick = function(){
window.document.getElementBy('onmouseover事件源ID').onclick = function(){
}
}
//或者采取下面的这种形式也可以,直接赋值value
td5.setAttribute("onclick","delate(this);");
结果是行的通的,于是我把所有触发的函数需要参数的部分全部改成了上面的形式,所有问题都得到了解决。
实现反选的巧妙方法
另外,在学习时有一部分代码和老师讲的思路一样,但老师的代码更为简洁,和题目无关,但想总结下来。
//我的思路
for(var i = 0;i < click_element.length;i++){
if(click_element[i].checked === true){
click_element[i].checked = false;
}else if(click_element[i].checked === false){
click_element[i].checked = true;
}
}
//老师代码:仅仅用了一行
//简化
for(var i = 0;i < click_element.length;i++){
click_element[i].checked = !click_element[i].checked;
}
附完整代码 CSS样式部分可略
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#div1{
text-align: center;
}
table{
margin: auto;
width:1000px;
text-align: center;
border: 2px solid gray;
border-spacing: 0px;
}
.thS{
border: 2px solid gray;
}
.thF{
border: 2px solid gray;
background-color: greenyellow;
}
th,td{
border: 2px solid gray;
}
#div3{
text-align: center;
width: 100%;
}
</style>
<script>
window.onload= function () {
function de(Obj){
//删除行 可以通过获取父标签的方法 获取tr
var getTd = Obj.parentNode;
var getTr = getTd.parentNode;
//获取table
var table = getTr.parentNode;
table.removeChild(getTr);
}
// 第一个
// click_all
document.getElementById("firstcheckbox").onclick = function(){
// 获取所有的复选框
var element = document.getElementsByName("check");
for(var i = 0;i < element.length;i++){
//获取后this为数据源
element[i].checked = this.checked;
}
}
var click_all = window.document.getElementById("click_all");
click_all.onclick = function(){
var click_element = document.getElementsByName("check");
for(var i = 0;i < click_element.length;i++){
click_element[i].checked = true;
}
}
//查找值 将true改为false 将false 改为true
//anti_click
var anti_click = window.document.getElementById("anti_click");
anti_click.onclick = function(){
var click_element = document.getElementsByName("check");
//简化
for(var i = 0;i < click_element.length;i++){
click_element[i].checked = !click_element[i].checked;
}
}
//全不选
var not_click = window.document.getElementById("not_click");
not_click.onclick = function(){
var click_element = document.getElementsByName("check");
for(var i = 0;i < click_element.length;i++){
click_element[i].checked = false;
}
}
window.document.getElementById(`add`).onclick =function(){
var a = window.document.getElementById("code");
var b = window.document.getElementById("name");
var c = window.document.getElementById("sex");
var code = a.value;
//code为对象类型 其后加上 value获取值
var name = b.value;
var sex = c.value;
var table = document.getElementById("table");
button = "<input type='checkbox' name='check' value='+code+'>";
//appendChild方式
var tr = document.createElement("tr");
tr.setAttribute("class","thS");
tr.onmouseover = function () {
this.className = "thF";
}
tr.onmouseout = function () {
this.className = "thS";
}
var td0 = document.createElement("td");
var in0 = document.createElement("input");
in0.setAttribute("type","checkbox");
in0.setAttribute("id","firstcheckbox");
in0.setAttribute("name","check");
td0.appendChild(in0);
var td1 = document.createElement("td");
td1.appendChild(document.createTextNode(code));
tr.appendChild(td1);
var td2 = document.createElement("td");
td2.appendChild(document.createTextNode(name));
tr.appendChild(td2);
var td3 = document.createElement("td");
td3.appendChild(document.createTextNode(sex));
var td4 = document.createElement("td");
//<a href='javascript:void(0);' οnclick='delate(this)' >delete</a>
var td5 = document.createElement("a");
td5.setAttribute("href","javascript:void(0);");
td5.onclick = function(){
de(this);
}
td5.appendChild(document.createTextNode("delete"));
td4.appendChild(td5);
tr.appendChild(td0);
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
tr.appendChild(td4);
table.appendChild(tr);
}
}
</script>
</head>
<body>
<div id="div1">
<form method="get" action="Demo8_table.html">
<input type = "text" id = "code" >
<input type="text" id = "name">
<input type = "text" id = "sex">
<input type="button" id = "add" value="add">
</form>
</div>
<div id = "div2">
<table id = "table">
<caption>学生信息表</caption>
<tr id = "tr" class="thS">
<th><input type="checkbox" id="firstcheckbox"></th>
<th>编号</th>
<th>姓名</th>
<th>性别</th>
<th>操作</th>
</tr>
</table>
</div>
<div id = "div3">
<input type="button" id="click_all" value="全选">
<input type="button" id="anti_click" value="反选">
<input type="button" id="not_click" value="全不选">
</div>
</body>
</html>
不足之处,近一天的时间未找到错误原因,只是找到了解决途径,感谢李俍为我提供了思路,使问题得到了解决。感谢大家的阅读,初学者若有总结错误之处,恳请批评指正。