3

是否可以替换节点名称?像:

HTML:

<strong id="element">Text</strong>

Javascript:

var element = document.getElementById("element");
    element.nodeName = "b";

如我所见,它不起作用,如果以这种方式不可能,那怎么办?

为什么我需要它:

我正在构建一个文本编辑器,IE 在 execCommand() 函数中使用 strong 而不是 b 并且我想改变它,我尝试从头开始构建 execCommand("bold") 但有很多问题和即使在 IE 8 和 9 之间也存在差异。所以现在我决定更改它的节点名称,这真的很容易,但不起作用.. :(

注意:我需要它只在 Internet Explorer 中工作。

谢谢

4

5 回答 5

5

不,但您可以轻松替换节点:

var oldNode = document.getElementById('element'),
    newNode = document.createElement('b'),
    node,
    nextNode;

node = oldNode.firstChild;
while (node) {
    nextNode = node.nextSibling;
    newNode.appendChild(node);
    node = nextNode;
}

newNode.className = oldNode.className;
// Do attributes too if you need to
newNode.id = oldNode.id; // (Not invalid, they're not both in the tree at the same time)
oldNode.parentNode.replaceChild(newNode, oldNode);

活生生的例子

非常感谢 Haochi 指出replaceChild,我这样做了:

oldNode.parentNode.insertBefore(newNode, oldNode);
oldNode.parentNode.removeChild(oldNode);

活生生的例子……但replaceChild更干净。

文件:

于 2011-03-26T17:49:08.363 回答
3
Element.prototype.setTagName=function(strTN) {
 var oHTML=this.outerHTML, tempTag=document.createElement(strTN); //document.createElement will fire an error if string has wrong characters.
 var tName={original: this.tagName.toUpperCase(), change: strTN.toUpperCase()}
 if (tName.original == tName.change) return;
 oHTML=oHTML.replace(RegExp("(^\<" + tName.original + ")|(" + tName.original + "\>$)","gi"), function(x){return (x.toUpperCase().replace(tName.original, tName.change));});
 tempTag.innerHTML=oHTML;
 this.parentElement.replaceChild(tempTag.firstChild,this);
}

使用(如果您想为正文的第一个元素设置跨度):

document.body.firstElementChild.setTagName("SPAN");

编辑:

我忘了提一件事。它创建了一个新元素,因此如果您将原始元素存储在变量中,则该变量将存储旧的(未更改的)元素。如果元素没有父元素,它会失败。

这就是为什么我做了一个新的:

Element.prototype.spawn = function(strTN = "spawn") {
 let tName = ({original: this.tagName.toUpperCase(), change: strTN.toUpperCase()}); if (tName.original == tName.change) { return; }
 let fragment = document.createRange().createContextualFragment(this.outerHTML.replace(new RegExp("(^\<\\b" + tName.original + "\\b)|(\\b" + tName.original + "\\b\>$)","gi"), function(x){return(x.toUpperCase().replace(tName.original, tName.change));}));
 return(fragment.firstChild);
}

这个只是创建了包含所有原始后代的新元素,但如果需要,您必须手动将其放置到 DOM 中:

var e = document.body.firstElementChild;
e.replaceWith(e.spawn("i"));
于 2015-04-28T17:17:18.450 回答
1

不,nodeName是只读的。从规范:

readonly attribute DOMString       nodeName;

见这里:http ://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1950641247

于 2011-03-26T17:45:28.000 回答
1

您可以尝试获取outerHTML并替换开始和结束标签。

var element = document.getElementById("element");
element.outerHTML = element.outerHTML.trim()
                                     .replace('<strong ','<button ')
                                     .replace('</strong>'.'</button');

但请注意,上述解决方案仅适用于简单的用例。要获得更好的解决方案,请查看下面的代码段。

var element = document.getElementById("element");
changeNodeName(element,'button');

function changeNodeName(el,str){
  var elNodeName = el.nodeName.toLowerCase();
  var newString = el.outerHTML.trim()
                    .replace('<'+ elNodeName,'<'+str);

  // To replace the end tag, we can't simply use replace()
  // because, replace() will replace the first occurrence,
  // which means if our element has a child element with the
  // same node name the end tag of the *child element* will be 
  // replaced, not the parent element. So,

  newString = newString
           .slice(0,newString.lastIndexOf('</'+str+'>'));    
  //now newString = "<button id='element'>Text"

  newString = newString + "</" + str + ">";
  el.outerHTML = newString;
}
<strong id="element">
  <strong>
    Text
  </strong>
</strong>

于 2017-12-06T14:18:38.913 回答
0

您可以将 strong 元素的 innerHTML 值存储在 temp 变量中,然后创建一个新的“b”元素并将其 innerHTML 设置为存储在 temp 变量中的值,最后使用 strong 元素的 parent 上的 replaceChild 方法替换strong 元素与新的 b 元素。

于 2011-03-26T17:49:38.333 回答