web-dev-qa-db-ja.com

jQuery:タグ名を変更するには?

jQuery:タグ名を変更するには?

例えば:

<tr>
    $1
</tr>

私は欲しい

<div>
    $1
</div>

はい、できます

  1. DOM要素<div>を作成します
  2. Trコンテンツをdivにコピーします
  3. Domからtrを削除する

しかし、直接作ることはできますか?

PS:

    $(tr).get(0).tagName = "div"; 

結果はDOMExceptionになります。

55
puchu

JQueryの.replaceWith()メソッドを使用して、HTMLマークアップを置き換えることができます。

例: http://jsfiddle.net/JHmaV/

参照:. replaceWith

既存のマークアップを保持する場合は、次のようなコードを使用できます。

$('#target').replaceWith('<newTag>' + $('target').html() +'</newTag>')
36
jAndy

いいえ、W3C仕様によると、「DOMString型のtagName、読み取り専用」では不可能です。

http://www.w3.org/TR/DOM-Level-2-Core/core.html

44
ggarber

DOM renameNode()メソッドはどこにありますか?

今日(2014)ブラウザは 新しいDOM3 renameNodeメソッド を理解していません( W3C を参照)バウザーで実行されているかどうかを確認します: http://jsfiddle.net/ k2jSm/1 /

だから、DOMソリューションはいですし、理解できませんなぜ(??)jQueryは回避策を実装していませんか?

純粋なDOMアルゴリズム

  1. createElement(new_name)
  2. すべてのコンテンツを新しい要素にコピーします。
  3. 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を待つ...

jQueryアルゴリズム

@ilpoldoアルゴリズムは良い出発点です。

   $from.replaceWith($('<'+newname+'/>').html($from.html()));

他の人がコメントしたように、属性コピーが必要です...一般的な待機...

classに固有、属性を保存http://jsfiddle.net/cDgpS/ を参照

https://stackoverflow.com/a/9468280/287948 も参照してください。

13
Peter Krauss

上記のソリューションは、既存の要素を消去し、ゼロから再作成して、プロセス内の子のイベントバインディングを破棄します。

短い答え:(属性を失います)

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

ネストされたバインディングのフィドル

からすべてのバインディングをコピーするのはクールですが、 現在のバインディングを取得する は機能しませんでした。

10
ericP

タグの内部コンテンツを保持するには、.html()とともにアクセサ.replaceWith()を使用できます。

分岐した例: http://jsfiddle.net/WVb2Q/1/

7
ilpoldo

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')
2
Dmitriy Sintsov

あなたは少し基本的に行くことができます。私のために働く。

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;
2
Cory

タグ名を変更する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

1
illusionist

multipleタグの内部コンテンツを、それぞれ独自のオリジナルコンテンツに置き換えるには、.replaceWith()および.html()別様:

http://jsfiddle.net/kcrca/VYxxG/

1
user856027

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);
0
WoodrowShigeru

ノード名を変更するさらに別のスクリプト

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を新しい要素にコピーしてから、古い要素を置き換えます。

0
Berty
$(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>
0
Ifeanyi Chukwu

言葉で彼を取る

質問「タグ名を変更するには?」私はこの解決策を提案します:
それが理にかなっているかどうかは、ケースバイケースで決定する必要があります。

私の例では、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でサポートされているすべてのブラウザーと互換性があります。すべての属性を新しい要素にコピーしようとする他の方法もありますが、それらはすべてのブラウザと互換性があるわけではありません。

この方法で行うのは非常に高価だと思いますが。

0

「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);

参照: http://jsfiddle.net/03gcnx9v/3/

0
cedrik

この機能を使用できます

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');
0
Sarath Ak

プロパティ値を変更するだけでは変更できません(他の人が言ったように、一部の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を拡張します。

0
Benny