因为您正在谈论您的替换是任何东西,并且还在元素的子元素中间替换,所以它变得比插入单个元素或直接删除和附加更棘手:
function replaceTargetWith( targetID, html ){
/// find our target
var i, tmp, elm, last, target = document.getElementById(targetID);
/// create a temporary div or tr (to support tds)
tmp = document.createElement(html.indexOf('<td')!=-1?'tr':'div'));
/// fill that div with our html, this generates our children
tmp.innerHTML = html;
/// step through the temporary div's children and insertBefore our target
i = tmp.childNodes.length;
/// the insertBefore method was more complicated than I first thought so I
/// have improved it. Have to be careful when dealing with child lists as
/// they are counted as live lists and so will update as and when you make
/// changes. This is why it is best to work backwards when moving children
/// around, and why I'm assigning the elements I'm working with to `elm`
/// and `last`
last = target;
while(i--){
target.parentNode.insertBefore((elm = tmp.childNodes[i]), last);
last = elm;
}
/// remove the target.
target.parentNode.removeChild(target);
}
示例用法:
replaceTargetWith( 'idTABLE', 'I <b>can</b> be <div>anything</div>' );
演示:
通过使用.innerHTML
我们的临时 div 这将生成TextNodes
并且Elements
我们需要插入而不需要任何努力。但与其插入临时 div 本身——这会给我们标记我们不想要的——我们可以扫描并插入它的孩子。
...要么,要么期待使用 jQuery 和它的replaceWith
方法。
jQuery('#idTABLE').replaceWith('<blink>Why this tag??</blink>');
2012/11/15 更新
作为对上述 EL 2002 评论的回应:
这并不总是可能的。例如,当createElement('div')
并设置其innerHTML为时<td>123</td>
,这个div就变成<div>123</div>
了(js丢掉了不合适的td标签)
上述问题显然也否定了我的解决方案——我已经相应地更新了上面的代码(至少对于这个td
问题)。但是,对于某些 HTML,无论您做什么,都会发生这种情况。所有用户代理都通过自己的解析规则解释 HTML,但几乎所有用户代理都会尝试自动更正错误的 HTML。准确实现您正在谈论的内容(在您的某些示例中)的唯一方法是将 HTML 完全从 DOM 中取出,并将其作为字符串进行操作。这将是使用以下实现标记字符串的唯一方法(jQuery 也无法解决此问题):
<table><tr>123 text<td>END</td></tr></table>
如果您随后将此字符串注入到 DOM 中,则取决于浏览器,您将获得以下信息:
123 text<table><tr><td>END</td></tr></table>
<table><tr><td>END</td></tr></table>
剩下的唯一问题是,为什么您首先要实现损坏的 HTML?:)