Сорри, всё оказалось элементарно. Надо было просто отказаться от атрибутов и воспользоваться свойсвом rowSpan. Вот исправленный кроссбраузерный код:
function groupSucc() {
var tables = document.getElementsByTagName('table')
for (var i = 0; i < tables.length; i++) {
var ip = ''
var from = 0
var merged = 1
var rows = tables[i].rows
for (var j = 1; j < rows.length; j++) {
if (rows[j].cells[0].innerHTML != ip) {
ip = rows[j].cells[0].innerHTML
from += merged
merged = 1
} else {
merged++
rows[from].cells[0].rowSpan = merged
rows[from].cells[4].rowSpan = merged
rows[j].deleteCell(0)
rows[j].deleteCell(3)
}
}
}
}
function ungroupSucc() {
var tables = document.getElementsByTagName('table')
for (var i = 0; i < tables.length; i++) {
var from = 0
var merged = 1
var rows = tables[i].rows
for (var j = 1; j < rows.length; j++) {
if (merged > 1) {
rows[j].insertCell(0)
rows[j].insertCell(-1)
rows[j].cells[0].innerHTML = rows[from].cells[0].innerHTML
rows[j].cells[4].innerHTML = rows[from].cells[4].innerHTML
rows[j].cells[4].setAttribute('align', 'right')
rows[j].cells[0].firstChild.href = '#' // Внимание! Если эту строку закомментировать
merged--
if (merged == 1) {
rows[from].cells[0].rowSpan = 1
rows[from].cells[4].rowSpan = 1
}
continue;
}
if (rows[j].cells[0].rowSpan > 1) {
from = j
merged = parseInt(rows[j].cells[0].getAttribute('rowspan'))
}
}
alert(tables[0].rows[2].cells[0].innerHTML); // то здесь выведет <a href="#" onclick="...">
alert(tables[0].rows[3].cells[0].innerHTML); // а здесь - <a href="http://popov654.pp.ru/parser/parser.php#" onclick="..."> В общем случае это не опасно, однако поскольку данный сценарий опирается на идентичность innerHTML ячеек первой колонки, это может привести к неприятным последствиям (а именно, при следующей группировке сгруппируется всё, кроме первых строчек, и получится дублирование первой строки)
}
Просьба обратить внимание на то, что, как отмечено в коде, IE изменяет атрибут ref ссылок при копировании. Для остальных браузеров эта строка не нужна.