32

我在替换 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, 但根本没有结果 =(

4

7 回答 7

57

由于 Jquery replaceWith() 代码过于庞大、棘手和复杂,这是我自己的解决方案。=)

最好的方法是使用 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);
    }

就这样

于 2012-11-17T18:36:55.820 回答
10

因为您正在谈论您的替换是任何东西,并且还在元素的子元素中间替换,所以它变得比插入单个元素或直接删除和附加更棘手:

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?:)

于 2012-11-14T22:50:24.017 回答
9

使用 jQuery 你可以这样做:

var str = '<td>1</td><td>2</td>';
$('#__TABLE__').replaceWith(str);

http://jsfiddle.net/hZBeW/4/

或者在纯 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;

http://jsfiddle.net/hZBeW/1/

于 2012-11-14T22:24:48.557 回答
3

您将首先删除表,然后将新的替换添加到表的父对象中。

抬头removeChildappendChild

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/

于 2012-11-14T22:23:37.247 回答
1

如果您需要实际替换您从 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)来执行此操作,但它需要更多的代码行,并且您的问题明确表示您想使用字符串。

于 2012-11-14T22:43:53.933 回答
1

在这种情况下,您的输入太模棱两可了。您的代码必须知道它是否应该按原样插入文本或解析出一些 HTML 标记(否则会以错误的 HTML 结束)。这是不必要的复杂性,您可以通过调整您提供的输入来避免。

如果乱码输入是不可避免的,那么如果没有一些复杂的解析(最好在一个单独的函数中),您最终可能会得到一些糟糕的 HTML(就像您在第二个示例中所做的那样......这很糟糕,对吗?)。

我猜您想要一个将列插入 1 行表的函数。在这种情况下,您的内容应作为数组传入(不带 table、tr、td 标记)。每个数组元素将是一列。

HTML

<table id="__TABLE__"><tr><td></td></tr></table>

JS

为简洁起见使用 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>
于 2012-11-14T23:47:46.370 回答
-1

使用属性“innerHTML”

以某种方式选择表格:

var a = document.getElementById('table, div, whatever node, id')
a.innerHTML = your_text
于 2012-11-14T22:29:58.393 回答