标签未订阅事件
问题描述:
考虑下面的代码:<TR>标签未订阅事件
<!DOCTYPE html> <!-- HTML5 -->
<html>
<head>
<meta http-equiv="Expires" content="Fri, Jan 01 1900 00:00:00 GMT">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-language" content="en">
<title>Untitled</title>
<script type='text/javascript'>
function createTableRow() {
var tr = document.createElement("tr");
var strWork = "<tr onmouseover='this.style.cursor=\"pointer\";'";
strWork += " onmouseout='this.style.cursor=\"auto\";'";
strWork += " onclick='ShowClick(this);'";
strWork += " id='TestCell'><td>Test!</td></tr>";
alert(strWork);
tr.outerHTML = strWork;
return tr;
}
function BuildTable() {
var table = document.createElement("table");
table.appendChild(createTableRow());
return table;
}
function ShowClick(obj) {
alert(obj.id);
}
</script>
</head>
<body onload='alert(BuildTable().outerHTML);'>
</body>
</html>
第一个“警告”对话框中显示的标签,我想形成它,但是,在“的onload =警报”行返回结果“ <表> < tr> </tr> </table>“。
我在做什么错?为什么这些事件不与TR标签绑定?
另外,我想补充一点,我最初分配使用JavaScript的事件,即:
tr.onclick = function() { ShowClick(this); };
但有完全相同的结果...
我真的不明白这一点,我无法在任何地方找到任何有关该问题的讨论......任何帮助将不胜感激!
答
您的代码会在JavaScript控制台中抛出NO_MODIFICATION_ALLOWED_ERR
。该W3C spec具有这样说的:
[element.outerHTML
]抛出一个NO_MODIFICATION_ALLOWED_ERR
异常,如果元素的父是Document
节点。
同样的事情发生在你的代码中。在将其添加到另一个节点(例如table
)之前,您正在设置tr
的outerHTML
。这就是为什么它的outerHTML
无法更改。
最简单的解决方案是不使用outerHTML
。试试你的原始的方法:
function createTableRow() {
var tr = document.createElement('tr');
tr.onmouseover = function() {
this.style.cursor = 'pointer';
};
tr.onmouseout = function() {
this.style.cursor = 'auto';
};
tr.onclick = function() {
ShowClick(this);
};
tr.id = 'TestCell';
tr.innerHTML = '<td>Test!</td>';
return tr;
}
注意,当你alert
(或console.log
)的table
的outerHTML
,你会看到这样的事情:
<table><tr id="TestCell"><td>Test!</td></tr></table>
但不要让这种欺骗你。事件处理程序不显示,但这是因为它们直接连接到DOM节点,因此绕过了HTML。请放心,他们完美地工作。
看到自己,试试这个现场演示:jsbin.com/oterit/1/edit
+0
如果您特别针对Moziall浏览器,MDN是一个适当的参考。更一般地说,(草案)[W3C DOM分析和序列化规范](http://html5.org/specs/dom-parsing.html#outerhtml)是一个更好的参考,因为它适用于所有浏览器,而不是特定的子集。 –
RobG
2012-08-20 01:58:20
+0
@RobG:谢谢你的建议。:) –
PPvG
2012-08-20 02:00:17
+0
@ JaredFarrish-较新的W3C **规范**没有版本号,只是“最后更新”日期,因为它们是“活文件”,而不是静态的。 MDN甚至没有这个愿望,它是Mozilla浏览器中观察到的行为的社区维基。 W3C规范针对**所有**浏览器的当前和未来行为。 –
RobG
2012-08-20 03:14:52
答
你createTableRow功能是关闭...
您已经创建了 “TR” 的对象。然后你把"<tr"
放在下一行。作为strWork
变量的一部分。你基本上正在重复这个任务,那会破坏DOM。
function createTableRow () {
var tr = document.createElement("tr");
tr.setAttribute("onmouseover" , "this.style.cursor='pointer';");
tr.setAttribute("onmouseout" , "this.style.cursor='auto';");
tr.setAttribute("onclick" , "showClick(this);");
tr.setAttribute("id" , "TestCell");
var td = document.createElement("td");
td.appendChild(document.createTextNode("Test!"));
tr.appendChild(td);
return tr;
}
+0
这是因为他使用'outerHTML'来考虑元素本身,而且在浏览器中也很不一致。 –
2012-08-20 01:30:22
答
你缺少的一部分,你居然添加的表身,即:
document.body.appendChild(table);
无论哪种方式,outerHTML
和创建tr
和td
与document.createElement
是跨浏览器颇不一致,您最好的选择是使用table.insertRow
和row.insertCell
:
function createTableRow(table) {
var tr = table.insertRow(0);
tr.onmouseover = function() { this.style.cursor = "pointer"; }
tr.onmouseout = function() { this.style.cursor="auto"; }
tr.onclick = function() { ShowClick(tr); }
tr.id = "TestCell";
var cell = tr.insertCell(0);
cell.innerHTML = "Test!";
}
function BuildTable() {
var table = document.createElement("table");
table.appendChild(createTableRow());
document.body.appendChild(table); // here's where you add the table to the page
return table;
}
下面是一个jsfiddle的例子。
+0
请注意,为了与正在使用的浏览器(即旧版本的IE)兼容,您必须将新的tr添加到tbody元素,并将tbody添加到表中。 –
RobG
2012-08-20 02:57:58
答
其他答案有有用的信息,这里的多。如果你想使用标记来初始化一个DOM片段,你最好创建一个父节点,并插入标记为innerHTML的,如:
function createTableRow() {
var tBody = document.createElement('tbody');
var strWork = "<tr onmouseover='this.style.cursor=\"pointer\";'"
+ " onmouseout='this.style.cursor=\"auto\";'"
+ " onclick='ShowClick(this);'"
+ " id='TestCell'><td>Test!</td></tr>";
tBody.innerHTML = strWork;
return tBody.firstChild;
}
但是,这不会在大多数版本的IE作为工作您不能使用innerHTML或outerHTML创建表格的某些部分,尽管您可以使用它来创建整个表格。
此外,(再次在IE中),您必须将tr元素添加到tbody元素,而不是直接添加到表中,因为tr不能是表格的子元素,它必须是tbody的子元素 - 并且人们说IE不符合标准:-)
底线是,你最好使用纯粹的DOM来创建表格,而不是标记,其他答案。
+0
我会赞成,虽然我承认我不在“IE标准”部分。 –
2012-08-20 03:09:37
考虑下面的代码:<TR>标签未订阅事件
<!DOCTYPE html> <!-- HTML5 -->
<html>
<head>
<meta http-equiv="Expires" content="Fri, Jan 01 1900 00:00:00 GMT">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-language" content="en">
<title>Untitled</title>
<script type='text/javascript'>
function createTableRow() {
var tr = document.createElement("tr");
var strWork = "<tr onmouseover='this.style.cursor=\"pointer\";'";
strWork += " onmouseout='this.style.cursor=\"auto\";'";
strWork += " onclick='ShowClick(this);'";
strWork += " id='TestCell'><td>Test!</td></tr>";
alert(strWork);
tr.outerHTML = strWork;
return tr;
}
function BuildTable() {
var table = document.createElement("table");
table.appendChild(createTableRow());
return table;
}
function ShowClick(obj) {
alert(obj.id);
}
</script>
</head>
<body onload='alert(BuildTable().outerHTML);'>
</body>
</html>
第一个“警告”对话框中显示的标签,我想形成它,但是,在“的onload =警报”行返回结果“ <表> < tr> </tr> </table>“。
我在做什么错?为什么这些事件不与TR标签绑定?
另外,我想补充一点,我最初分配使用JavaScript的事件,即:
tr.onclick = function() { ShowClick(this); };
但有完全相同的结果...
我真的不明白这一点,我无法在任何地方找到任何有关该问题的讨论......任何帮助将不胜感激!
您的代码会在JavaScript控制台中抛出NO_MODIFICATION_ALLOWED_ERR
。该W3C spec具有这样说的:
[
element.outerHTML
]抛出一个NO_MODIFICATION_ALLOWED_ERR
异常,如果元素的父是Document
节点。
同样的事情发生在你的代码中。在将其添加到另一个节点(例如table
)之前,您正在设置tr
的outerHTML
。这就是为什么它的outerHTML
无法更改。
最简单的解决方案是不使用outerHTML
。试试你的原始的方法:
function createTableRow() {
var tr = document.createElement('tr');
tr.onmouseover = function() {
this.style.cursor = 'pointer';
};
tr.onmouseout = function() {
this.style.cursor = 'auto';
};
tr.onclick = function() {
ShowClick(this);
};
tr.id = 'TestCell';
tr.innerHTML = '<td>Test!</td>';
return tr;
}
注意,当你alert
(或console.log
)的table
的outerHTML
,你会看到这样的事情:
<table><tr id="TestCell"><td>Test!</td></tr></table>
但不要让这种欺骗你。事件处理程序不显示,但这是因为它们直接连接到DOM节点,因此绕过了HTML。请放心,他们完美地工作。
看到自己,试试这个现场演示:jsbin.com/oterit/1/edit
如果您特别针对Moziall浏览器,MDN是一个适当的参考。更一般地说,(草案)[W3C DOM分析和序列化规范](http://html5.org/specs/dom-parsing.html#outerhtml)是一个更好的参考,因为它适用于所有浏览器,而不是特定的子集。 – RobG 2012-08-20 01:58:20
@RobG:谢谢你的建议。:) – PPvG 2012-08-20 02:00:17
@ JaredFarrish-较新的W3C **规范**没有版本号,只是“最后更新”日期,因为它们是“活文件”,而不是静态的。 MDN甚至没有这个愿望,它是Mozilla浏览器中观察到的行为的社区维基。 W3C规范针对**所有**浏览器的当前和未来行为。 – RobG 2012-08-20 03:14:52
你createTableRow功能是关闭...
您已经创建了 “TR” 的对象。然后你把"<tr"
放在下一行。作为strWork
变量的一部分。你基本上正在重复这个任务,那会破坏DOM。
function createTableRow () {
var tr = document.createElement("tr");
tr.setAttribute("onmouseover" , "this.style.cursor='pointer';");
tr.setAttribute("onmouseout" , "this.style.cursor='auto';");
tr.setAttribute("onclick" , "showClick(this);");
tr.setAttribute("id" , "TestCell");
var td = document.createElement("td");
td.appendChild(document.createTextNode("Test!"));
tr.appendChild(td);
return tr;
}
这是因为他使用'outerHTML'来考虑元素本身,而且在浏览器中也很不一致。 – 2012-08-20 01:30:22
你缺少的一部分,你居然添加的表身,即:
document.body.appendChild(table);
无论哪种方式,outerHTML
和创建tr
和td
与document.createElement
是跨浏览器颇不一致,您最好的选择是使用table.insertRow
和row.insertCell
:
function createTableRow(table) {
var tr = table.insertRow(0);
tr.onmouseover = function() { this.style.cursor = "pointer"; }
tr.onmouseout = function() { this.style.cursor="auto"; }
tr.onclick = function() { ShowClick(tr); }
tr.id = "TestCell";
var cell = tr.insertCell(0);
cell.innerHTML = "Test!";
}
function BuildTable() {
var table = document.createElement("table");
table.appendChild(createTableRow());
document.body.appendChild(table); // here's where you add the table to the page
return table;
}
下面是一个jsfiddle的例子。
请注意,为了与正在使用的浏览器(即旧版本的IE)兼容,您必须将新的tr添加到tbody元素,并将tbody添加到表中。 – RobG 2012-08-20 02:57:58
其他答案有有用的信息,这里的多。如果你想使用标记来初始化一个DOM片段,你最好创建一个父节点,并插入标记为innerHTML的,如:
function createTableRow() {
var tBody = document.createElement('tbody');
var strWork = "<tr onmouseover='this.style.cursor=\"pointer\";'"
+ " onmouseout='this.style.cursor=\"auto\";'"
+ " onclick='ShowClick(this);'"
+ " id='TestCell'><td>Test!</td></tr>";
tBody.innerHTML = strWork;
return tBody.firstChild;
}
但是,这不会在大多数版本的IE作为工作您不能使用innerHTML或outerHTML创建表格的某些部分,尽管您可以使用它来创建整个表格。
此外,(再次在IE中),您必须将tr元素添加到tbody元素,而不是直接添加到表中,因为tr不能是表格的子元素,它必须是tbody的子元素 - 并且人们说IE不符合标准:-)
底线是,你最好使用纯粹的DOM来创建表格,而不是标记,其他答案。
我会赞成,虽然我承认我不在“IE标准”部分。 – 2012-08-20 03:09:37
请学习在现代浏览器中使用'console.log()'。 – 2012-08-20 01:12:30
@ JaredFarrish--请学会宽容使用的浏览器。 – RobG 2012-08-20 01:52:03
@RobG - 哈哈,有趣的东西。除非你认真,在这种情况下,你呢? – 2012-08-20 01:53:35