使用 jQuery 更改 HTML 标记?

这可能吗?

例如:

$('a.change').click(function(){
//code to change p tag to h5 tag
});




<p>Hello!</p>
<a id="change">change</a>

因此,单击更改锚点应该会导致 <p>Hello!</p>部分更改为(例如) h5标记,这样在单击之后就会得到 <h5>Hello!</h5>。我知道您可以删除 p 标记并将其替换为 h5,但是是否存在实际修改 HTML 标记的方法呢?

159814 次浏览

我相信,一旦创建了 dom 元素,标签就是不可变的:

$(this).replaceWith($('<h5>' + this.innerHTML + '</h5>'));

您需要更改标记是否有特定的原因?如果您只想使文本更大,那么更改 p 标记的 CSS 类将是一个更好的方法。

就像这样:

$('#change').click(function(){
$('p').addClass('emphasis');
});

您应该更改标记的样式(或者更确切地说,具有特定 id 的标记) ,而不是更改标记的类型更改文档的元素以应用样式更改并不是一种好的做法。试试这个:

$('a.change').click(function() {
$('p#changed').css("font-weight", "bold");
});


<p id="changed">Hello!</p>
<a id="change">change</a>

这里有一个扩展,可以做到这一切,在尽可能多的元素,以尽可能多的方式..。

示例用法:

保留现有的类别和属性:

$('div#change').replaceTag('<span>', true);

或者

放弃现有的类和属性:

$('div#change').replaceTag('<span class=newclass>', false);

甚至

用 span 替换所有 div,复制类和属性,添加额外的类名

$('div').replaceTag($('<span>').addClass('wasDiv'), true);

插件来源:

$.extend({
replaceTag: function (currentElem, newTagObj, keepProps) {
var $currentElem = $(currentElem);
var i, $newTag = $(newTagObj).clone();
if (keepProps) {//\{\{{
newTag = $newTag[0];
newTag.className = currentElem.className;
$.extend(newTag.classList, currentElem.classList);
$.extend(newTag.attributes, currentElem.attributes);
}//}}}
$currentElem.wrapAll($newTag);
$currentElem.contents().unwrap();
// return node; (Error spotted by Frank van Luijn)
return this; // Suggested by ColeLawrence
}
});


$.fn.extend({
replaceTag: function (newTagObj, keepProps) {
// "return" suggested by ColeLawrence
return this.each(function() {
jQuery.replaceTag(this, newTagObj, keepProps);
});
}
});

我注意到第一个答案并不完全是我所需要的,所以我做了一些修改,并认为我可以把它放回这里。

改进的 replaceTag(<tagName>)

replaceTag(<tagName>, [withDataAndEvents], [withDataAndEvents])

论点:

  • TagName: < em > String
    • 标签名称,例如“ div”、“ span”等。
  • With DataAndEvents: < em > Boolean
    • ”一个布尔值,指示是否应将事件处理程序与元素一起复制。从 jQuery 1.4开始,元素数据也将被复制。”信息
  • DeepWithDataAndEvents: 布尔型,
    • 一个布尔值,指示是否应复制克隆元素的所有子元素的事件处理程序和数据。默认情况下,它的值与第一个参数的值相匹配(默认为 false)。”信息

返回:

新创建的 jQuery 元素

好吧,我知道这里有一些答案,但我还是决定再写一遍。

在这里,我们可以像使用克隆一样替换标记。 我们遵循与 。克隆()相同的语法,使用 withDataAndEventsdeepWithDataAndEvents复制 孩子节点的数据和事件(如果使用的话)。

例如:

$tableRow.find("td").each(function() {
$(this).clone().replaceTag("li").appendTo("ul#table-row-as-list");
});

来源:

$.extend({
replaceTag: function (element, tagName, withDataAndEvents, deepWithDataAndEvents) {
var newTag = $("<" + tagName + ">")[0];
// From [Stackoverflow: Copy all Attributes](http://stackoverflow.com/a/6753486/2096729)
$.each(element.attributes, function() {
newTag.setAttribute(this.name, this.value);
});
$(element).children().clone(withDataAndEvents, deepWithDataAndEvents).appendTo(newTag);
return newTag;
}
})
$.fn.extend({
replaceTag: function (tagName, withDataAndEvents, deepWithDataAndEvents) {
// Use map to reconstruct the selector with newly created elements
return this.map(function() {
return jQuery.replaceTag(this, tagName, withDataAndEvents, deepWithDataAndEvents);
})
}
})

注意,这个 不会取代是选中的元素,它返回新创建的元素。

我提出了一种方法,使用 jQuery 对象的字符串表示形式,并使用正则表达式和基本 JavaScript 替换标记名。您不会丢失任何内容,也不必循环遍历每个属性/属性。

/*
* replaceTag
* @return {$object} a new object with replaced opening and closing tag
*/
function replaceTag($element, newTagName) {


// Identify opening and closing tag
var oldTagName = $element[0].nodeName,
elementString = $element[0].outerHTML,
openingRegex = new RegExp("^(<" + oldTagName + " )", "i"),
openingTag = elementString.match(openingRegex),
closingRegex = new RegExp("(<\/" + oldTagName + ">)$", "i"),
closingTag = elementString.match(closingRegex);


if (openingTag && closingTag && newTagName) {
// Remove opening tag
elementString = elementString.slice(openingTag[0].length);
// Remove closing tag
elementString = elementString.slice(0, -(closingTag[0].length));
// Add new tags
elementString = "<" + newTagName + " " + elementString + "</" + newTagName + ">";
}


return $(elementString);
}

最后,您可以替换现有的对象/节点,如下所示:

var $newElement = replaceTag($rankingSubmit, 'a');
$('#not-an-a-element').replaceWith($newElement);

这是我的解决方案,它允许在标签之间切换。

<!DOCTYPE html>
<html>
<head>
<title></title>


<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<script type="text/javascript">


function wrapClass(klass){
return 'to-' + klass;
}


function replaceTag(fromTag, toTag){
	

/** Create selector for all elements you want to change.
* These should be in form: <fromTag class="to-toTag"></fromTag>
*/
var currentSelector = fromTag + '.' + wrapClass(toTag);


/** Select all elements */
var $selected = $(currentSelector);


/** If you found something then do the magic. */
if($selected.size() > 0){


/** Replace all selected elements */
$selected.each(function(){


/** jQuery current element. */
var $this = $(this);


/** Remove class "to-toTag". It is no longer needed. */
$this.removeClass(wrapClass(toTag));


/** Create elements that will be places instead of current one. */
var $newElem = $('<' + toTag + '>');


/** Copy all attributes from old element to new one. */
var attributes = $this.prop("attributes");
$.each(attributes, function(){
$newElem.attr(this.name, this.value);
});


/** Add class "to-fromTag" so you can remember it. */
$newElem.addClass(wrapClass(fromTag));


/** Place content of current element to new element. */
$newElem.html($this.html());


/** Replace old with new. */
$this.replaceWith($newElem);
});


/** It is possible that current element has desired elements inside.
* If so you need to look again for them.
*/
replaceTag(fromTag, toTag);
}
}




</script>


<style type="text/css">
	

section {
background-color: yellow;
}


div {
background-color: red;
}


.big {
font-size: 40px;
}


</style>
</head>
<body>


<button onclick="replaceTag('div', 'section');">Section -> Div</button>
<button onclick="replaceTag('section', 'div');">Div -> Section</button>


<div class="to-section">
<p>Matrix has you!</p>
<div class="to-section big">
<p>Matrix has you inside!</p>
</div>
</div>


<div class="to-section big">
<p>Matrix has me too!</p>
</div>


</body>
</html>

想法是包装元素并打开内容:

function renameElement($element,newElement){


$element.wrap("<"+newElement+">");
var $newElement = $element.parent();


//Copying Attributes
$.each($element.prop('attributes'), function() {
$newElement.attr(this.name,this.value);
});


$element.contents().unwrap();


return $newElement;
}

使用方法:

renameElement($('p'),'h5');

演示

这是使用 jQuery 在 DOM 中更改 HTML 标记的快速方法。我发现这个 用()代替函数非常有用。

   var text= $('p').text();
$('#change').on('click', function() {
target.replaceWith( "<h5>"+text+"</h5>" );
});

你可以通过 data-*属性来实现,比如 data-replace="replaceTarget,replaceBy",所以在 jQuery 的帮助下,通过 .split()方法得到 replaceTargetreplaceBy值,然后使用 .replaceWith()方法。
这种 data-*属性技术可以方便地管理任何标记替换,而不需要修改以下内容(所有标记替换的通用代码) 我希望下面的片段能对你有所帮助。

$(document).on('click', '[data-replace]', function(){
var replaceTarget = $(this).attr('data-replace').split(',')[0];
var replaceBy = $(this).attr('data-replace').split(',')[1];
$(replaceTarget).replaceWith($(replaceBy).html($(replaceTarget).html()));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<p id="abc">Hello World #1</p>
<a href="#" data-replace="#abc,<h1/>">P change with H1 tag</a>
<hr>
<h2 id="xyz">Hello World #2</h2>
<a href="#" data-replace="#xyz,<p/>">H1 change with P tag</a>
<hr>
<b id="bold">Hello World #2</b><br>
<a href="#" data-replace="#bold,<i/>">B change with I tag</a>
<hr>
<i id="italic">Hello World #2</i><br>
<a href="#" data-replace="#italic,<b/>">I change with B tag</a>

下面的函数完成了这个任务,并保留了所有的属性

function changeTag(originTag, destTag) {
while($(originTag).length) {
$(originTag).replaceWith (function () {
var attributes = $(this).prop("attributes");
var $newEl = $(`<${destTag}>`)
$.each(attributes, function() {
$newEl.attr(this.name, this.value);
});
return $newEl.html($(this).html())
})
}
}

要确保它能正常工作,请检查下面的示例

function changeTag(originTag, destTag) {
while($(originTag).length) {
$(originTag).replaceWith (function () {
var attributes = $(this).prop("attributes");
var $newEl = $(`<${destTag}>`)
$.each(attributes, function() {
$newEl.attr(this.name, this.value);
});
return $newEl.html($(this).html())
})
}
}


changeTag("div", "p")


console.log($("body").html())
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<div class="A" style="font-size:1em">
<div class="B" style="font-size:1.1em">A</div>
</div>
<div class="C" style="font-size:1.2em">
B
</div>
</body>