wake-up-neo.net

jQuery: Wie kann man den Tagnamen ändern?

jQuery: Wie kann man den Tagnamen ändern?

Zum Beispiel:

<tr>
    $1
</tr>

Ich brauche

<div>
    $1
</div>

Ja, ich kann

  1. Erstellen Sie das DOM-Element <div>
  2. Tr-Inhalt nach div kopieren
  3. Tr von dom entfernen

Aber kann ich es direkt schaffen?

PS:

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

ergibt DOMException.

53
puchu

Sie können jedes HTML-Markup mit der .replaceWith()-Methode von jQuery ersetzen.

beispiel: http://jsfiddle.net/JHmaV/

Ref .: . replaceWith

Wenn Sie das vorhandene Markup beibehalten möchten, können Sie folgenden Code verwenden:

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

Nein, gemäß W3C-Spezifikation ist dies nicht möglich: "tagName vom Typ DOMString, readonly"

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

43
ggarber

Woher kommt die DOM renameNode () Methode?

Heute (2014) versteht kein Browser die neue DOM3 RenameNode-Methode (siehe auch W3C ) Überprüfen Sie, ob sie auf Ihrem Browser ausgeführt werden: http://jsfiddle.net/ k2jSm/1 /

Eine DOM-Lösung ist also hässlich und ich verstehe nicht , warum (??) jQuery keine Problemumgehung implementiert hat?

reiner DOM-Algorithmus

  1. createElement(new_name)
  2. kopieren Sie den gesamten Inhalt in ein neues Element.
  3. ersetzen Sie altes zu neuem durch replaceChild()

ist so etwas,

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

... Bewertung und jsfiddle warten ...

jQuery-Algorithmus

Der @ ilpoldo-Algorithmus ist ein guter Ausgangspunkt,

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

Wie andere kommentiert haben, braucht es eine Attributkopie ... warte generisch ...

spezifisch für class, Erhalt des Attributs , siehe http://jsfiddle.net/cDgpS/

Siehe auch https://stackoverflow.com/a/9468280/287948

13
Peter Krauss

Die oben genannten Lösungen löschen das vorhandene Element und erstellen es von Grund auf neu. Dabei werden alle Ereignisbindungen von untergeordneten Elementen zerstört.

kurze Antwort: (verliert die Attribute)

$("p").wrapInner("<div/>").children(0).unwrap();

längere Antwort: (Attribute der Kopien)

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

Geige mit verschachtelten Bindungen

Es wäre cool, alle Bindungen gleichzeitig zu kopieren, aber aktuelle Bindungen zu bekommen hat bei mir nicht funktioniert.

9
ericP

Um den internen Inhalt des Tags zu erhalten, können Sie den Accessor .html() in Verbindung mit .replaceWith() verwenden.

gegabeltes Beispiel: http://jsfiddle.net/WVb2Q/1/

7
ilpoldo

Sie könnten ein bisschen grundlegend sein. Funktioniert bei mir.

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

Inspiriert von ericP answer, formatiert und in jQuery-Plugin konvertiert:

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

Verwendungszweck:

$('div').replaceWithTag('span')
1
Dmitriy Sintsov

JS, um den Tag-Namen zu ändern

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

Verwandte Geige ist in diesem link

1
illusionist

Um den internen Inhalt von multiple -Tags durch jeweils eigenen Inhalt zu ersetzen, müssen Sie .replaceWith() und .html() unterschiedlich verwenden:

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

1
user856027

Da replaceWith() für mich nicht auf Elementbasis funktioniert hat (vielleicht weil ich es in map() verwendet habe), habe ich es gemacht, indem ich ein neues Element erstellt und die Attribute nach Bedarf kopiert habe.

$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

Noch ein weiteres Skript zum Ändern des Knotennamens

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/

Die Attribute und die innere HTML-Datei werden in ein neues Element kopiert und das alte ersetzt.

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

Nimm ihn beim Wort

Nimmt die Word-Frage "Wie kann ich den Tagnamen ändern?" Ich würde diese Lösung vorschlagen:
Wenn es sinnvoll ist oder nicht, muss von Fall zu Fall entschieden werden.

Mein Beispiel "benennt" alle a-Tags mit Hyperlinks für SMS mit span-Tags um. Alle Attribute und Inhalte pflegen:

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

Da es keinen Sinn macht, ein span-Tag mit einem href-Attribut zu haben, entferne ich das auch .. Die Vorgehensweise auf diese Weise ist kugelsicher und kompatibel mit allen von jquery unterstützten Browsern um alle Attribute in das neue Element zu kopieren, diese sind jedoch nicht mit allen Browsern kompatibel.

Obwohl ich denke, dass es ziemlich teuer ist, es so zu machen.

0

Jquery Plugin um "TagName" editierbar zu machen:

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

Siehe: http://jsfiddle.net/03gcnx9v/3/

0
cedrik

Sie können diese Funktion verwenden 

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

Beispielcode

renameTag($(tr),'div');
0
Sarath Ak

Das Ändern der Eigenschaftswerte macht dies einfach nicht (wie andere bereits gesagt haben, sind einige HTMLElement -Eigenschaften schreibgeschützt; einige halten auch prototypischen Kontext für primitivere Elemente). Am ehesten können Sie die DOM-API nachahmen, indem Sie auch den Prozess der prototypischen Vererbung in JavaScript nachahmen. 

Das Setzen eines Prototyps eines Objekts über __proto__ ist im Allgemeinen verpönt. Sie können auch überlegen, warum Sie denken, dass Sie das gesamte DOM-Element überhaupt duplizieren müssen. Aber hier geht es:

// 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"

Alle DOM-Elemente funktionieren auf diese Weise. Zum Beispiel: <div></div> wird von HTMLDivElement, Erzeugt, das sich HTMLElement, Erstreckt, das wiederum Element, Reicht, das wiederum Object erweitert.

0
Benny