使用 jQuery 更改 HTML 标签?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/918792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 10:07:29  来源:igfitidea点击:

Use jQuery to change an HTML tag?

jquery

提问by Christopher Cooper

Is this possible?

这可能吗?

example:

例子:

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


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

So clicking the change anchor should cause the <p>Hello!</p>section to change to (as an example) an h5 tag so you'd end up with <h5>Hello!</h5>after the click. I realize you can delete the p tag and replace it with an h5, but is there anyway to actually modify an HTML tag?

因此,单击更改锚点应该会导致该<p>Hello!</p>部分更改为(例如)一个 h5 标记,因此您将<h5>Hello!</h5>在单击后结束。我意识到您可以删除 p 标签并用 h5 替换它,但是无论如何实际上可以修改 HTML 标签吗?

回答by mishac

Once a dom element is created, the tag is immutable, I believe. You'd have to do something like this:

我相信,一旦创建了 dom 元素,标签就是不可变的。你必须做这样的事情:

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

回答by Orwellophile

Here's an extension that will do it all, on as many elements in as many ways...

这是一个扩展,它将以多种方式在尽可能多的元素上完成所有工作......

Example usage:

用法示例:

keep existing class and attributes:

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

保留现有的类和属性:

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

or

或者

Discard existing class and attributes:

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

丢弃现有的类和属性:

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

or even

甚至

replace all divs with spans, copy classes and attributes, add extra class name

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

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

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

Plugin Source:

插件来源:

$.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);
        });
    }
});

回答by jrista

Rather than change the type of tag, you should be changing the style of the tag (or rather, the tag with a specific id.) Its not a good practice to be changing the elements of your document to apply stylistic changes. Try this:

与其更改标签的类型,不如更改标签的样式(或者更确切地说,是具有特定 id 的标签)。更改文档的元素以应用样式更改并不是一个好习惯。尝试这个:

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

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

回答by Cole Lawrence

I noticed that the first answer wasn't quite what I needed, so I made a couple of modifications and figured I'd post it back here.

我注意到第一个答案并不是我所需要的,所以我做了一些修改,并想我会把它发回这里。

Improved replaceTag(<tagName>)

改进 replaceTag(<tagName>)

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

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

Arguments:

参数:

  • tagName: String
    • The tag name e.g. "div", "span", etc.
  • withDataAndEvents: Boolean
    • "A Boolean indicating whether event handlers should be copied along with the elements. As of jQuery 1.4, element data will be copied as well." info
  • deepWithDataAndEvents: Boolean,
    • A Boolean indicating whether event handlers and data for all children of the cloned element should be copied. By default its value matches the first argument's value (which defaults to false)." info
  • 标签名称:字符串
    • 标签名称,例如“div”、“span”等。
  • withDataAndEvents:布尔值
    • “一个布尔值,指示是否应与元素一起复制事件处理程序。从 jQuery 1.4 开始,元素数据也将被复制。” 信息
  • deepWithDataAndEvents: Boolean,
    • 一个布尔值,指示是否应复制克隆元素的所有子元素的事件处理程序和数据。默认情况下,它的值与第一个参数的值匹配(默认为 false)。”信息

Returns:

返回:

A newly created jQuery element

一个新创建的 jQuery 元素

Okay, I know there are a few answers here now, but I took it upon myself to write this again.

好的,我知道现在这里有一些答案,但我还是自己写了一遍。

Here we can replace the tag in the same way we use cloning. We are following the same syntax as .clone()with the withDataAndEventsand deepWithDataAndEventswhich copy the childnodes' data and events if used.

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

Example:

例子:

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

Source:

来源:

$.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);
        })
    }
})

Note that this does not replacethe selected element, it returns the newly created one.

请注意,这不会替换所选元素,而是返回新创建的元素。

回答by Shubanker

Idea is to wrap the element & unwrap the contents:

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

function renameElement($element,newElement){

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

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

    $element.contents().unwrap();       

    return $newElement;
}

Sample usage:

示例用法:

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

Demo

演示

回答by Luka S

I know that there are probably better ways to do it, as everyone else has said, but the easiest way I found to do it was:

我知道可能有更好的方法来做到这一点,正如其他人所说,但我发现最简单的方法是:

// Get all of element as an array...
var elementAllHTML = document.getElementById("element").outerHTML.split("");

// Switch the opening tag...
elementAllHTML[1]="a";
elementAllHTML[2]="";
elementAllHTML[3]="";

// Make it a string again...
elementAllHTML = elementAllHTML.join();

// Switch the ending tag and remove any ','s...
elementAllHTML = elementAllHTML.substring(0, elementAllHTML.length-7);
elementAllHTML = elementAllHTML.replace(/,/gi, "");
elementAllHTML = elementAllHTML+"a>";

// Remove current element from the HTML document...
document.body.removeChild(document.getElementById("element"));

// Attach new element to the HTML document...
document.body.innerHTML += elementAllHTML;

Bear in mind that this was to change a element to a element so that I could later put a href attribute and a download attribute onto it, so it may need some tweaking to your needs.
It also messes up any positioning for element within, but I just tweaked this later.

请记住,这是将一个元素更改为一个元素,以便我稍后可以将一个 href 属性和一个下载属性放到它上面,因此它可能需要根据您的需要进行一些调整。
它也会弄乱内部元素的任何定位,但我稍后对其进行了调整。

回答by Mahafuz

This the quick way to change HTML tags inside your DOM using jQuery. I find this replaceWith()function is very useful.

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

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

回答by Raeesh Alam

You can achieve by data-*attribute like data-replace="replaceTarget,replaceBy"so with help of jQuery to get replaceTarget& replaceByvalue by .split()method after getting values then use .replaceWith()method.
This data-*attribute technique to easily manage any tag replacement without changing below (common code for all tag replacement).

I hope below snippet will help you lot.

您可以通过实现data-*属性,像data-replace="replaceTarget,replaceBy"这样使用jQuery的帮助来获得replaceTargetreplaceBy由值.split()法得到的值,然后使用后.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>

回答by Jo?o Pimentel Ferreira

The following function does the trick and keeps all the attributes. You use it for example like this: changeTag("div", "p")

以下函数可以解决问题并保留所有属性。例如,您可以像这样使用它:changeTag("div", "p")

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())
    })
  }
}

To be sure that it works, check the following example

为确保它有效,请检查以下示例

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>

回答by kevinweber

I came up with an approach where you use a string representation of your jQuery object and replace the tag name using regular expressions and basic JavaScript. You will not loose any content and don't have to loop over each attribute/property.

我想出了一种方法,您可以使用 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);
}

Finally, you can replace the existing object/node as follows:

最后,您可以按如下方式替换现有对象/节点:

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