Использовать jQuery для изменения тега HTML? - PullRequest
120 голосов
/ 28 мая 2009

Возможно ли это?

пример:

$('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?

Ответы [ 8 ]

195 голосов
/ 28 мая 2009

Как только элемент dom создан, тег, я думаю, является неизменным. Вы должны сделать что-то вроде этого:

$(this).replaceWith($('<h5>' + this.innerHTML + '</h5>'));
59 голосов
/ 09 декабря 2013

Вот расширение, которое будет делать все это на всех элементах и ​​множеством способов ...

Пример использования:

сохранить существующий класс и атрибуты:

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

или

Отменить существующий класс и атрибуты:

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

или даже

заменить все элементы div на span, скопировать классы и атрибуты, добавить имя дополнительного класса

$('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);
        });
    }
});
12 голосов
/ 28 мая 2009

Вместо того, чтобы менять тип тега, вы должны изменить стиль тега (или, скорее, тег с определенным идентификатором). Не рекомендуется менять элементы вашего документа для применения стилистических изменений. Попробуйте это:

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

<p id="changed">Hello!</p>
<a id="change">change</a>
8 голосов
/ 24 июня 2014

Я заметил, что первый ответ был не совсем тем, что мне было нужно, поэтому я сделал несколько изменений и решил опубликовать его здесь.

Улучшено replaceTag(<tagName>)

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

Аргументы:

  • tagName: String
    • Имя тега, например "div", "span" и т. д.
  • withDataAndEvents: Boolean
    • "Логическое значение, указывающее, следует ли копировать обработчики событий вместе с элементами. Начиная с jQuery 1.4, данные элементов также будут копироваться." информация
  • deepWithDataAndEvents: Boolean ,
    • Логическое значение, указывающее, следует ли копировать обработчики событий и данные для всех дочерних элементов клонированного элемента. По умолчанию его значение соответствует значению первого аргумента (по умолчанию false). " info

Возвращает:

Недавно созданный элемент jQuery

Хорошо, я знаю, что здесь есть несколько ответов, но я взял на себя ответственность написать это снова.

Здесь мы можем заменить тег таким же образом, как мы используем клонирование. Мы придерживаемся того же синтаксиса, что и .clone () с withDataAndEvents и deepWithDataAndEvents, которые копируют данные и события child узлов, если они используются.

Пример:

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

Обратите внимание, что не заменяет выбранный элемент, он возвращает только что созданный.

0 голосов
/ 24 мая 2019

Идея состоит в том, чтобы обернуть элемент и развернуть содержимое:

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 голосов
/ 11 июля 2016

Это моё решение. Позволяет переключаться между тегами.

<!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 голосов
/ 12 марта 2016

Я предложил подход, в котором вы используете строковое представление вашего объекта 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 голосов
/ 28 мая 2009

Есть ли конкретная причина, по которой вам нужно изменить тег? Если вы просто хотите увеличить размер текста, лучше бы изменить CSS-класс тега p.

Примерно так:

$('#change').click(function(){
  $('p').addClass('emphasis');
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...