jQueryを使用してHTMLタグを変更しますか?


130

これは可能ですか?

例:

$('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タグを変更する方法はありますか?

回答:


211

dom要素が作成されると、タグは不変になると思います。あなたはこのようなことをしなければならないでしょう:

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

2
以下の私のコメントを参照してください...スタイルを適用するためにドキュメント構造を変更することは、最善のアプローチではありません。
jrista 2009年

39
これは、置き換えた要素にある可能性のある属性を破壊しませんか?スタイル属性、データ属性などの削除により、予期しない動作が発生する可能性があります
Xavi

5
"<" + el.outerHTML.replace(/(^<\w+|\w+>$)/g, "H5") + ">";またはプラグ可能なjQuery関数:リンク
バジル

65

これは、すべての要素に対して、さまざまな方法ですべてを実行する拡張機能です...

使用例:

既存のクラスと属性を保持します。

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

または

既存のクラスと属性を破棄します。

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

あるいは

すべての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);
        });
    }
});

2
うん。そして記録のために、実際にはタグを変更したくなるかもしれない非常に正当な理由がたくさんあります。たとえば、SPAN内にDIVタグがあった場合、これは非標準です。pdbパブリッシングのprincexmlの厳密な標準を使用しているときに、この機能を多く使用しました。
Orwellophile 2013

1
見た目はとてもいいですが、不自然にも、置き換えられた要素のすべてのイベントが失われます。おそらくそれも処理できます—素晴らしいでしょう!
NPC

大都市での生活である@NPC。要素を置き換える場合は、犠牲者が出ます。イベントを複製するための関連するjqueryを知っている人がいると思います:)
Orwellophile

1
@FrankvanLuijn @orwellophile return node;実際にreturn this;は、プラグインの「古いバージョン」に示されているはずです。これは、次のようにイベントを連結するために不可欠です$("tr:first").find("td").clone().replaceTag("li").appendTo("ul#list")
Cole Lawrence

1
わかりません。なぜ2つの関数が必要なのですか。両方必要ですか?申し訳ありませんが、私は迷ってしまいました
ジョアン・ピメンテル・フェレイラ

12

タグのタイプを変更するのではなく、タグのスタイル(または特定のIDのタグ)を変更する必要があります。文書の要素を変更してスタイルの変更を適用することはお勧めできません。これを試して:

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

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

3
この場合でも、ドキュメント構造を変更するべきではありません。編集バッティングがクリックされたことに応答して入力を表示する必要がある場合は、入力を入れて、display:noneまたはvisibility:hiddenを貼り付けます。ボタンのクリックに応答して<h5>を非表示にし、<input>を表示します。常にドキュメントの構造を変更している場合は、スタイルとレイアウトのバケットフルを要求するだけで、すぐに問題が発生します。
jrista 2009年

1
もちろんです。JavaScriptが埋め込まれている、またはリンクされているため、セキュリティが懸念される場合、セキュリティへのアプローチに多少の欠陥があります。ユーザーの役割に応じてドキュメントのコンテンツをレンダリングする必要があります...ロールのコンテンツをブレンドすることは、問題にアプローチする安全な方法ではありません。誰かが管理者としてシステムにログインしている場合は、管理者向けにコンテンツをレンダリングします。リーダーとしてシステムにログインしている場合は、コンテンツをリーダーにレンダリングします。これにより、アクセスすべきでないコンテンツが完全に排除されます。コンテンツがレンダリングされたら、CSSを使用してドキュメントのスタイルを設定し、コンテンツを表示/非表示にします。
jrista 2009年

2
私はあなたに同意し、あなたの提案をプロジェクトに取り入れました。私はtoggle()を使用して、管理者がログインしたときにのみレンダリングされる管理要素を表示します。元の質問とは(直接)無関係ですが、これはおそらく私が最初に行った方向よりも良い解決策です。乾杯!
クリストファークーパー

1
ウー!セキュリティの悪い一塊を手に入れました!勝利、そしてみんなのために丸めます!(ここにビールのアイコンを挿入)
jrista 2009年

1
セキュリティのためにクライアント側のJavaScriptに依存することは、実際にはセキュリティがないよりも悪いです。どうして?自分にはセキュリティがあると思っているので、実際にはない。
BryanH

8

最初の答えが私が必要とするものではないことに気づいたので、私はいくつかの変更を加えて、ここに投稿することを考えました。

改善された replaceTag(<tagName>)

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

引数:

  • tagName:文字列
    • 「div」、「span」などのタグ名。
  • withDataAndEvents:ブール値
    • 「イベントハンドラーを要素と共にコピーするかどうかを示すブール値。jQuery1.4以降、要素データもコピーされます。」情報
  • deepWithDataAndEvents:Boolean
    • 複製された要素のすべての子のイベントハンドラーとデータをコピーするかどうかを示すブール値。デフォルトでは、その値は最初の引数の値(デフォルトはfalse)と一致します。」の情報を

戻り値:

新しく作成されたjQuery要素

さて、ここにいくつかの答えがあることを知っていますが、私はこれをもう一度書くことを自分で思いました。

ここでは、クローニングと同じ方法でタグを置き換えることができます。私たちは、同じ構文を以下の通りです)(.clonewithDataAndEventsし、deepWithDataAndEventsそのコピーした子使用した場合はノードのデータとイベントを。

例:

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

これ選択した要素を置き換えるのではなく、新しく作成された要素を返すことに注意してください。


2
.children()は純粋なテキストノードを含まないことに注意してください。.contents()IIRC を試してみてください。
Orwellophile 2016

5

アイデアは、要素をラップして内容を展開することです:

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;
}

使用例:

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

デモ


0

私は、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);

0

これが私の解決策です。タグを切り替えることができます。

<!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>


0

これは、jQueryを使用してDOM内のHTMLタグを変更する簡単な方法です。このreplaceWith()関数は非常に便利です。

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

0

次の方法で達成することができます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>


0

次の関数はトリックを実行し、すべての属性を保持します。たとえば、次のように使用します。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())
    })
  }
}

動作することを確認するには、次の例を確認してください

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>


-1

タグを変更する必要がある特定の理由はありますか?テキストを大きくしたいだけの場合は、pタグのCSSクラスを変更することをお勧めします。

このようなもの:

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

要素/タグを変更するように求めている理由は、ページ上の他の場所で「編集」ボタンをクリックすると、タグ(タイプは無関係ですが、<h5>)を<input>に変更しようとしているためです。 。
クリストファークーパー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.