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

39
이 클로버는 대체 한 요소에있을 수있는 속성이 아닙니까? 스타일 속성, 데이터 속성 등으로 인해 예기치 않은 동작이 발생할 수 있습니다.
Xavi

5
"<" + el.outerHTML.replace(/(^<\w+|\w+>$)/g, "H5") + ">";또는 플러그 가능한 jQuery 함수 : link
basil

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

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 개의 기능이 필요합니까? 둘 다 필요합니까? 죄송합니다, Lost
João Pimentel Ferreira

12

태그 유형을 변경하는 대신 태그 스타일 (또는 특정 ID가있는 태그)을 변경해야합니다. 스타일 변경을 적용하기 위해 문서의 요소를 변경하는 것은 좋지 않습니다. 이 시도:

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

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

3
이 경우에도 문서 구조를 수정해서는 안됩니다. 편집 버트를 클릭 한 것에 대한 응답으로 입력을 표시해야하는 경우 입력을 입력하고 스틱 표시 : 없음 또는 가시성 : 숨김을 표시하십시오. <h5>를 숨기고 버튼 클릭에 대한 응답으로 <입력>을 표시하십시오. 문서 구조를 지속적으로 수정하고 있다면, 스타일과 레이아웃 문제를 물색하는 것이 좋습니다.
jrista

1
물론. 자바 스크립트가 포함되거나 연결되어 있으므로 걱정이 보안 인 경우 보안에 대한 접근 방식에 다소 결함이 있습니다. 사용자의 역할에 따라 문서의 내용을 렌더링해야합니다. 역할의 내용을 혼합하는 것은 문제에 접근하는 안전한 방법이 아닙니다. 누군가 시스템에 관리자로 로그인 한 경우 관리자 용 컨텐츠를 렌더링하십시오. 시스템에 리더로 로그인 한 경우 리더 용 컨텐츠를 렌더링하십시오. 이렇게하면 액세스해서는 안되는 콘텐츠가 완전히 제거됩니다. 내용이 렌더링되면 CSS를 사용하여 문서의 스타일을 지정하고 내용을 표시 / 숨 깁니다.
jrista

2
동의하며 프로젝트에 대한 권장 사항을 취했습니다. 관리자가 로그인 할 때만 렌더링되는 관리 요소를 표시하기 위해 toggle ()을 사용할 것입니다. 원래 질문과 관련이 없지만 (직접적으로) 이것은 원래가는 방향보다 더 나은 솔루션 일 것입니다. 건배!
Christopher Cooper

1
우! 나쁜 보안의 또 하나의 엉망을 깨뜨렸다! 모두를위한 승리! (맥주 아이콘을 여기에 삽입하십시오)
jrista

1
보안을 위해 클라이언트 측 자바 스크립트에 의존하는 것은 실제로 한 더 전혀 보안보다. 왜? 보안 이 있다고 생각 하기 때문에 실제로는 그렇지 않습니다.
BryanH

8

첫 번째 답변이 필요한 것이 아니라는 것을 알았으므로 몇 가지 수정을하고 여기에 다시 게시 할 것이라고 생각했습니다.

향상 replaceTag(<tagName>)

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

인수 :

  • tagName : 문자열
    • 태그 이름 (예 : "div", "span"등)
  • withDataAndEvents : 부울
    • "이벤트 핸들러를 요소와 함께 복사해야하는지 여부를 나타내는 부울입니다. jQuery 1.4부터 요소 데이터도 복사됩니다." 정보
  • deepWithDataAndEvents : 부울 ,
    • 복제 된 요소의 모든 하위에 대한 이벤트 핸들러 및 데이터를 복사해야하는지 여부를 나타내는 부울입니다. 기본적으로이 값은 첫 번째 인수의 값 (디폴트는 false)를 찾습니다. " 정보를

보고:

새로 작성된 jQuery 요소

좋아, 나는 지금 여기에 몇 가지 대답이 있다는 것을 알고 있지만, 나는 이것을 다시 작성하기 위해 나 자신에게 그것을 가져 갔다.

여기서 복제를 사용하는 것과 같은 방식으로 태그를 교체 할 수 있습니다. 우리는 같은 문법 다음과 같다 .clone () 과를 withDataAndEvents하고 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

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를의 도움으로 그렇게 replaceTarget& replaceBy에 의해 값 .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>). .
Christopher Cooper
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.