我在替换 HTML 元素时遇到问题。
例如,这是一个表格:
<table>
<tr>
<td id="idTABLE">0</td>
<td>END</td>
</tr>
</table>
(可以是 div、span、任何东西)
JavaScript 中的字符串:
var str = '<td>1</td><td>2</td>';
(可以是任何东西,
123 text
,<span>123 element</span> 456
或 <tr><td>123</td>
或任何东西)
如何将元素
idTABLE
替换为 str
?
所以:
<table>
<tr>
<td id="idTABLE">0</td>
<td>END</td>
</tr>
</table>
变成:
<table>
<tr>
<td>1</td>
<td>2</td>
<td>END</td>
</tr>
</table>
<!-- str = '<td>1</td><td>2</td>'; -->
<table>
<tr>
123 text
<td>END</td>
</tr>
</table>
<!-- str = '123 text' -->
<table>
<tr>
<td>123</td>
<td>END</td>
</tr>
</table>
<!-- str = '<td>123</td>' -->
我尝试过
createElement
、replaceChild
、cloneNode
,但完全没有结果。
我发现最好的方法是使用outerHTML属性,但它还没有跨浏览器支持,所以我编写了自己的代码来管理它:
var str = '<a href="http://www.com">item to replace</a>'; //it can be anything
var Obj = document.getElementById('TargetObject'); //any element to be fully replaced
if(Obj.outerHTML) { //if outerHTML is supported
Obj.outerHTML=str; ///it's simple replacement of whole element with contents of str var
}
else { //if outerHTML is not supported, there is a weird but crossbrowsered trick
var tmpObj=document.createElement("div");
tmpObj.innerHTML='<!--THIS DATA SHOULD BE REPLACED-->';
ObjParent=Obj.parentNode; //Okey, element should be parented
ObjParent.replaceChild(tmpObj,Obj); //here we placing our temporary data instead of our target, so we can find it then and replace it into whatever we want to replace to
ObjParent.innerHTML=ObjParent.innerHTML.replace('<div><!--THIS DATA SHOULD BE REPLACED--></div>',str);
}
使用 jQuery 你可以做到这一点:
var str = '<td>1</td><td>2</td>';
$('#__TABLE__').replaceWith(str);
或者用纯 JavaScript:
var str = '<td>1</td><td>2</td>';
var tdElement = document.getElementById('__TABLE__');
var trElement = tdElement.parentNode;
trElement.removeChild(tdElement);
trElement.innerHTML = str + trElement.innerHTML;
因为你正在谈论你的替换是任何东西,并且还在元素的子元素中间进行替换,所以它变得比仅仅插入单个元素或直接删除和附加更棘手:
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>' );
演示:
通过使用临时 div 的
.innerHTML
,这将生成我们需要插入的 TextNodes
和 Elements
,无需任何艰苦的工作。但是,我们可以扫描并插入它的子项,而不是插入临时 div 本身(这会给我们带来我们不想要的标记)。
...要么使用 jQuery,要么使用 jQuery,这是
replaceWith
方法。
jQuery('#idTABLE').replaceWith('<blink>Why this tag??</blink>');
作为对上面 EL 2002 评论的回应:
这并不总是可能的。例如,当
并将其innerHTML设置为createElement('div')
时,这个div就变成了<td>123</td>
(js扔掉了不合适的td标签)<div>123</div>
上述问题显然也否定了我的解决方案 - 我已相应地更新了上面的代码(至少对于
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? :)
您首先要删除表,然后将新的替换添加到表的父对象中。
向上查找
removeChild
和 appendChild
http://javascript.about.com/library/bldom09.htm
https://developer.mozilla.org/en-US/docs/DOM/Node.appendChild
编辑: jQuery .append 允许 sting-html 而不删除标签:http://api.jquery.com/append/
您在这种情况下的输入太含糊了。 您的代码必须知道是否应该按原样插入文本或解析一些 HTML 标签(否则最终会出现错误的 HTML)。 这是不必要的复杂性,您可以通过调整您提供的输入来避免。
如果乱码输入是不可避免的,那么如果没有一些复杂的解析(最好在单独的函数中),您最终可能会得到一些错误的 HTML(就像您在第二个示例中所做的那样......这很糟糕,对吧?)。
我猜您想要一个将列插入到单行表中的函数。 在这种情况下,您的内容应作为数组传入(不带 table、tr、td 标签)。 每个数组元素将是一列。
<table id="__TABLE__"><tr><td></td></tr></table>
为了简洁起见,使用 jQuery...
function insert_columns (columns)
{
var $row = $('<tr></tr>');
for (var i = 0; i < columns.length; i++)
$row.append('<td>'+columns[i]+'</td>');
$('#__TABLE__').empty(); // remove everything inside
$('#__TABLE__').append($row);
}
那么...
insert_columns(['hello', 'there', 'world']);
<table id="__TABLE__"><tr><td>hello</td><td>there</td><td>world</td></tr></table>
如果您需要实际替换从 DOM 中选择的 td,那么您需要首先转到parentNode,然后替换内容用代表您想要的新 html 字符串替换innerHTML。技巧是将第一个表格单元格转换为字符串,以便您可以在字符串替换方法中使用它。
我添加了一个小提琴示例:http://jsfiddle.net/vzUF4/
<table><tr><td id="first-table-cell">0</td><td>END</td></tr></table>
<script>
var firstTableCell = document.getElementById('first-table-cell');
var tableRow = firstTableCell.parentNode;
// Create a separate node used to convert node into string.
var renderingNode = document.createElement('tr');
renderingNode.appendChild(firstTableCell.cloneNode(true));
// Do a simple string replace on the html
var stringVersionOfFirstTableCell = renderingNode.innerHTML;
tableRow.innerHTML = tableRow.innerHTML.replace(stringVersionOfFirstTableCell,
'<td>0</td><td>1</td>');
</script>
这里的很多复杂性在于您将 DOM 方法与字符串方法混合在一起。
如果 DOM 方法适用于您的应用程序,那么使用它们会更好。
您也可以使用纯 DOM 方法(document.createElement、removeChild、appendChild)来执行此操作,但需要更多行代码,并且您的问题明确表示您想要使用字符串。
我也有同样的情况。这是我当前的代码,因为我无法做得更好:
function update() {
var game = $("a#customGame");
games.forEach(updateGameList());
}
function updateGameList() {
var i = 0;
var game0 = $("span#game");
var game1 = $("span#game1");
var game2 = $("span#game2");
var game3 = $("span#game3");
var game4 = $("span#game4");
var game5 = $("span#game5");
switch (i) {
case 0:
game0.innerHTML = "<a href='" + gameLink + "'>" + gameName + "</a>";
break;
case 1:
game1.innerHTML = "<a href='" + gameLink + "'>" + gameName + "</a>";
break;
case 2:
game2.innerHTML = "<a href='" + gameLink + "'>" + gameName + "</a>";
break;
}
i++;
if (i > 5) {
i = 0;
}
}
这显然非常糟糕。我尝试使用
createElement
的想法,但失败了。我担心我使用了错误的功能innerHTML
。我希望这对你们有帮助。
使用属性“innerHTML”
以某种方式选择表格:
var a = document.getElementById('table, div, whatever node, id')
a.innerHTML = your_text