jQuery:タグ名を変更するには?
例えば:
<tr>
$1
</tr>
私は欲しい
<div>
$1
</div>
はい、できます
しかし、直接作ることはできますか?
PS:
$(tr).get(0).tagName = "div";
結果はDOMException
になります。
JQueryの.replaceWith()
メソッドを使用して、HTMLマークアップを置き換えることができます。
参照:. replaceWith
既存のマークアップを保持する場合は、次のようなコードを使用できます。
$('#target').replaceWith('<newTag>' + $('target').html() +'</newTag>')
いいえ、W3C仕様によると、「DOMString型のtagName、読み取り専用」では不可能です。
今日(2014)ブラウザは 新しいDOM3 renameNodeメソッド を理解していません( W3C を参照)バウザーで実行されているかどうかを確認します: http://jsfiddle.net/ k2jSm/1 /
だから、DOMソリューションはいですし、理解できませんなぜ(??)jQueryは回避策を実装していませんか?
createElement(new_name)
replaceChild()
で古いものを新しいものに置き換えますこのようなものです
function rename_element(node,name) {
var renamed = document.createElement(name);
foreach (node.attributes as a) {
renamed.setAttribute(a.nodeName, a.nodeValue);
}
while (node.firstChild) {
renamed.appendChild(node.firstChild);
}
return node.parentNode.replaceChild(renamed, node);
}
...レビューとjsfiddleを待つ...
@ilpoldoアルゴリズムは良い出発点です。
$from.replaceWith($('<'+newname+'/>').html($from.html()));
他の人がコメントしたように、属性コピーが必要です...一般的な待機...
class
に固有、属性を保存、 http://jsfiddle.net/cDgpS/ を参照
https://stackoverflow.com/a/9468280/287948 も参照してください。
上記のソリューションは、既存の要素を消去し、ゼロから再作成して、プロセス内の子のイベントバインディングを破棄します。
短い答え:(属性を失います)
$("p").wrapInner("<div/>").children(0).unwrap();
長い回答:(属性をコピー)
$("p").each(function (o, elt) {
var newElt = $("<div class='p'/>");
Array.prototype.slice.call(elt.attributes).forEach(function(a) {
newElt.attr(a.name, a.value);
});
$(elt).wrapInner(newElt).children(0).unwrap();
});
からすべてのバインディングをコピーするのはクールですが、 現在のバインディングを取得する は機能しませんでした。
タグの内部コンテンツを保持するには、.html()
とともにアクセサ.replaceWith()
を使用できます。
分岐した例: http://jsfiddle.net/WVb2Q/1/
ericP answerに触発され、フォーマットされ、jQueryプラグインに変換されます。
$.fn.replaceWithTag = function(tagName) {
var result = [];
this.each(function() {
var newElem = $('<' + tagName + '>').get(0);
for (var i = 0; i < this.attributes.length; i++) {
newElem.setAttribute(
this.attributes[i].name, this.attributes[i].value
);
}
newElem = $(this).wrapInner(newElem).children(0).unwrap().get(0);
result.Push(newElem);
});
return $(result);
};
使用法:
$('div').replaceWithTag('span')
あなたは少し基本的に行くことができます。私のために働く。
var oNode = document.getElementsByTagName('tr')[0];
var inHTML = oNode.innerHTML;
oNode.innerHTML = '';
var outHTML = oNode.outerHTML;
outHTML = outHTML.replace(/tr/g, 'div');
oNode.outerHTML = outHTML;
oNode.innerHTML = inHTML;
タグ名を変更するJS
/**
* This function replaces the DOM elements's tag name with you desire
* Example:
* replaceElem('header','ram');
* replaceElem('div.header-one','ram');
*/
function replaceElem(targetId, replaceWith){
$(targetId).each(function(){
var attributes = concatHashToString(this.attributes);
var replacingStartTag = '<' + replaceWith + attributes +'>';
var replacingEndTag = '</' + replaceWith + '>';
$(this).replaceWith(replacingStartTag + $(this).html() + replacingEndTag);
});
}
replaceElem('div','span');
/**
* This function concats the attributes of old elements
*/
function concatHashToString(hash){
var emptyStr = '';
$.each(hash, function(index){
emptyStr += ' ' + hash[index].name + '="' + hash[index].value + '"';
});
return emptyStr;
}
関連するフィドルはこの中にあります link
multipleタグの内部コンテンツを、それぞれ独自のオリジナルコンテンツに置き換えるには、.replaceWith()
および.html()
別様:
replaceWith()
は要素ごとに機能しなかったため(おそらくmap()
内で使用したため)、必要に応じて新しい要素を作成し、属性をコピーすることで実行しました。
$items = $('select option').map(function(){
var
$source = $(this),
$copy = $('<li></li>'),
title = $source.text().replace( /this/, 'that' );
$copy
.data( 'additional_info' , $source.val() )
.text(title);
return $copy;
});
$('ul').append($items);
ノード名を変更するさらに別のスクリプト
function switchElement() {
$element.each(function (index, oldElement) {
let $newElement = $('<' + nodeName + '/>');
_.each($element[0].attributes, function(attribute) {
$newElement.attr(attribute.name, attribute.value);
});
$element.wrapInner($newElement).children().first().unwrap();
});
}
http://jsfiddle.net/rc296owo/5/
属性と内部htmlを新しい要素にコピーしてから、古い要素を置き換えます。
$(function(){
$('#switch').bind('click', function(){
$('p').each(function(){
$(this).replaceWith($('<div/>').html($(this).html()));
});
});
});
p {
background-color: red;
}
div {
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Hello</p>
<p>Hello2</p>
<p>Hello3</p>
<button id="switch">replace</button>
質問「タグ名を変更するには?」私はこの解決策を提案します:
それが理にかなっているかどうかは、ケースバイケースで決定する必要があります。
私の例では、SMSとspanタグのハイパーリンクを含むすべてのa-Tagの名前を変更します。すべての属性とコンテンツを維持します。
$('a[href^="sms:"]').each(function(){
var $t=$(this);
var $new=$($t.wrap('<div>')
.parent()
.html()
.replace(/^\s*<\s*a/g,'<span')
.replace(/a\s*>\s*$/g,'span>')
).attr('href', null);
$t.unwrap().replaceWith($new);
});
Href属性を持つspanタグを持つことは意味をなさないので、私もそれを削除します。この方法で行うことは防弾であり、jqueryでサポートされているすべてのブラウザーと互換性があります。すべての属性を新しい要素にコピーしようとする他の方法もありますが、それらはすべてのブラウザと互換性があるわけではありません。
この方法で行うのは非常に高価だと思いますが。
「tagName」を編集可能にするJqueryプラグイン:
(function($){
var $newTag = null;
$.fn.tagName = function(newTag){
this.each(function(i, el){
var $el = $(el);
$newTag = $("<" + newTag + ">");
// attributes
$.each(el.attributes, function(i, attribute){
$newTag.attr(attribute.nodeName, attribute.nodeValue);
});
// content
$newTag.html($el.html());
$el.replaceWith($newTag);
});
return $newTag;
};
})(jQuery);
この機能を使用できます
var renameTag = function renameTag($obj, new_tag) {
var obj = $obj.get(0);
var tag = obj.tagName.toLowerCase();
var tag_start = new RegExp('^<' + tag);
var tag_end = new RegExp('<\\/' + tag + '>$');
var new_html = obj.outerHTML.replace(tag_start, "<" + new_tag).replace(tag_end, '</' + new_tag + '>');
$obj.replaceWith(new_html);
};
ES6
const renameTag = function ($obj, new_tag) {
let obj = $obj.get(0);
let tag = obj.tagName.toLowerCase();
let tag_start = new RegExp('^<' + tag);
let tag_end = new RegExp('<\\/' + tag + '>$');
let new_html = obj.outerHTML.replace(tag_start, "<" + new_tag).replace(tag_end, '</' + new_tag + '>');
$obj.replaceWith(new_html);
};
サンプルコード
renameTag($(tr),'div');
プロパティ値を変更するだけでは変更できません(他の人が言ったように、一部のHTMLElement
プロパティは読み取り専用です;また、よりプリミティブな要素へのプロトタイプコンテキストを保持します)。 DOM APIを模倣するために最も近いものは、JavaScriptでのプロトタイプ継承のプロセスも模倣することです。
__proto__
を介したオブジェクトのプロトタイプの「設定」は、一般的に嫌われています。また、最初にDOM要素全体を複製する必要があると考える理由を検討することもできます。しかし、ここに行きます:
// Define this at whatever scope you'll need to access it
// Most of these kinds of constructors are attached to the `window` object
window.HTMLBookElement = function() {
function HTMLBookElement() {
var book = document.createElement('book');
book.__proto__ = document.createElement('audio');
return book;
}
return new HTMLBookElement();
}
// Test your new element in a console (I'm assuming you have Chrome)
var harryPotter = new HTMLBookElement();
// You should have access to your new `HTMLBookElement` API as well as that
// of its prototype chain; since I prototyped `HTMLAudioElement`, you have
// some default properties like `volume` and `preload`:
console.log(harryPotter); // should log "<book></book>"
console.log(harryPotter.volume); // should log "1"
console.log(harryPotter.preload); // should log "auto"
すべてのDOM要素はこのように機能します。例:<div></div>
はHTMLDivElement
によって生成され、HTMLElement
を拡張し、さらにElement
を拡張し、さらにObject
を拡張します。