通过`appendChild`添加到DOM树的元素不会出现在IE6 / 7中(也是`onclick`事件没有触发)

时间:2011-05-06 05:20:38

标签: javascript internet-explorer events dom html-table

考虑以下JavaScript代码,用于在id="c"的容器div内创建一个8x8表:

//first, two shortcut functions
function $id(a){return(a&&a.nodeType)?a:document.getElementById(a);}
function $cr8(a){return document.createElement(a);}

//now the meat    
var ct = $id('c'),
    t = $cr8('table'),
    tr, td,
    row = 8, cols = 8,
    tdclkfn = function () { alert('row: '+this.i+' col: '+this.j); }

for(var i=0;i<row;i++) {
    tr = $cr8('tr');
    for(var j=0;j<cols;j++) {
        td = $cr8('td');
        td.i = i;
        td.j = j;
        td.onclick = tdclkfn;
        tr.appendChild(td);
    }
    t.appendChild(tr);
}
ct.appendChild(t);

这在Firefox,Chrome和IE8中正常运行。在IE6 / IE7中没有那么多。正如您在this live example中看到的那样,就好像表标记不存在一样。

如果你使用Firebug Lite或IE Developer Toolbar在幕后探索,你会发现DOM元素实际上存在,它们只是因为某种原因而不显示。有谁知道为什么?

我决定看看如果我将ct.innerHTML += '<div/>'添加到上述JavaScript的尾端会发生什么。它出现了(见this updated live example)。为什么这样可以解决问题?

此外,我附加到每个onclick的{​​{1}}事件处理程序的函数?显然它根本不会发射。它是附加的,你可以通过手动调用触发它,但点击单元格?不,不是在IE6 / 7中。为什么呢?

我知道我可以通过使用一个表现良好的JS / DOM框架解决这个问题,但我真的很想知道这里发生了什么。

1 个答案:

答案 0 :(得分:4)

table个元素不能直接包含tr个元素; IE和其他浏览器很乐意在解析标记时自动处理它(自动插入tbody;见下文),但显然当你直接操作DOM时,IE会更加挑剔。

如果你把tbody放在那里,IE6和IE7很高兴(显示的方框,点击处理程序工作):

var ct = $id('c'),
    t = $cr8('table'),
    tbody = $cr8('tbody'),
    tr, td,
    row = 8, cols = 8,
    tdclkfn = function () {
        alert('row: '+this.i+' col: '+this.j);
    }

for(var i=0;i<row;i++) {
    tr = $cr8('tr');
    for(var j=0;j<cols;j++) {
        td = $cr8('td');
        td.i = i;
        td.j = j;
        td.onclick = tdclkfn;
        tr.appendChild(td);
    }
    tbody.appendChild(tr);
}
t.appendChild(tbody);
ct.appendChild(t);

Live copy(在jsbin.com上; IE6和IE7以及jsfiddle.net似乎没有太多运气)。您的原始代码here可在同一网站上进行比较。

关于自动为您插入tbody,您可以看到实际操作:

HTML:

<table id='theTable'><tr><td>Test</td></tr></table>

(注意没有tbody。)

JavaScript的:

window.onload = function() {
  var elm, markup;

  elm = document.getElementById('theTable');
  markup = ["<ol>"];
  walk(elm);
  markup.push("</ol>");
  display(markup.join(""));

  function walk(node) {
    var child;

    markup.push("<li>");
    markup.push(node.nodeName);
    if (node.nodeType === 1 ||
        node.nodeType === 9 ||
        node.nodeType === 11) {
      markup.push("<ol>");
      for (child = node.firstChild;
           child;
           child = child.nextSibling) {
        walk(child);
      }
      markup.push("</ol>");
    }
    markup.push("</li>");
  }

  function display(markup) {
    var div = document.createElement('div');
    div.innerHTML = markup;
    document.body.appendChild(div);
  }
};

输出:

    1. TBODY
      1. TR
        1. TD
          1. #text
  1. 请注意其中的tbody

    Live copy