2012-08-20 69 views
0

考虑下面的代码:<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);'> 
    &nbsp; 
    </body> 
</html> 

第一个“警告”对话框中显示的标签,我想形成它,但是,在“的onload =警报”行返回结果“ <表> < tr> </tr> </table>“。

我在做什么错?为什么这些事件不与TR标签绑定?

另外,我想补充一点,我最初分配使用JavaScript的事件,即:

tr.onclick = function() { ShowClick(this); }; 

但有完全相同的结果...

我真的不明白这一点,我无法在任何地方找到任何有关该问题的讨论......任何帮助将不胜感激!

+0

请学习在现代浏览器中使用'console.log()'。 – 2012-08-20 01:12:30

+0

@ JaredFarrish--请学会宽容使用的浏览器。 – RobG 2012-08-20 01:52:03

+0

@RobG - 哈哈,有趣的东西。除非你认真,在这种情况下,你呢? – 2012-08-20 01:53:35

回答

1

您的代码会在JavaScript控制台中抛出NO_MODIFICATION_ALLOWED_ERR。该W3C spec具有这样说的:

[element.outerHTML]抛出一个NO_MODIFICATION_ALLOWED_ERR异常,如果元素的父是Document节点。

同样的事情发生在你的代码中。在将其添加到另一个节点(例如table)之前,您正在设置trouterHTML。这就是为什么它的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)的tableouterHTML,你会看到这样的事情:

<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

2

你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

0

你缺少的一部分,你居然添加的表身,即:

document.body.appendChild(table); 

无论哪种方式,outerHTML和创建trtddocument.createElement是跨浏览器颇不一致,您最好的选择是使用table.insertRowrow.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

1

其他答案有有用的信息,这里的多。如果你想使用标记来初始化一个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