Ich habe den folgenden Code
<b class="xyzxterms" style="cursor: default; ">bryant keil bio</b>
Wie würde ich das bTag durch ein h1Tag ersetzen , aber alle anderen Attribute und Informationen beibehalten?
Ich habe den folgenden Code
<b class="xyzxterms" style="cursor: default; ">bryant keil bio</b>
Wie würde ich das bTag durch ein h1Tag ersetzen , aber alle anderen Attribute und Informationen beibehalten?
Antworten:
Hier ist eine Möglichkeit, wie Sie dies mit jQuery tun können:
var attrs = { };
$.each($("b")[0].attributes, function(idx, attr) {
attrs[attr.nodeName] = attr.nodeValue;
});
$("b").replaceWith(function () {
return $("<h1 />", attrs).append($(this).contents());
});
Beispiel: http://jsfiddle.net/yapHk/
Update , hier ist ein Plugin:
(function($) {
$.fn.changeElementType = function(newType) {
var attrs = {};
$.each(this[0].attributes, function(idx, attr) {
attrs[attr.nodeName] = attr.nodeValue;
});
this.replaceWith(function() {
return $("<" + newType + "/>", attrs).append($(this).contents());
});
};
})(jQuery);
Beispiel: http://jsfiddle.net/mmNNJ/
childrenhat nicht funktioniert, aber contentsfunktioniert.
.eachBlock eingewickelt werden , wie eine Antwort unten auch zeigt.
Ich bin mir bei jQuery nicht sicher. Mit einfachem JavaScript können Sie Folgendes tun:
var new_element = document.createElement('h1'),
old_attributes = element.attributes,
new_attributes = new_element.attributes;
// copy attributes
for(var i = 0, len = old_attributes.length; i < len; i++) {
new_attributes.setNamedItem(old_attributes.item(i).cloneNode());
}
// copy child nodes
do {
new_element.appendChild(element.firstChild);
}
while(element.firstChild);
// replace element
element.parentNode.replaceChild(new_element, element);
Ich bin mir nicht sicher, wie browserübergreifend dies ist.
Eine Variation könnte sein:
for(var i = 0, len = old_attributes.length; i < len; i++) {
new_element.setAttribute(old_attributes[i].name, old_attributes[i].value);
}
Weitere Informationen finden Sie unter Node.attributes [MDN] .
while(child = child.nextSibling)fehlgeschlagen ist. Vielen Dank!
@jakov und @Andrew Whitaker
Hier ist eine weitere Verbesserung, damit mehrere Elemente gleichzeitig verarbeitet werden können.
$.fn.changeElementType = function(newType) {
var newElements = [];
$(this).each(function() {
var attrs = {};
$.each(this.attributes, function(idx, attr) {
attrs[attr.nodeName] = attr.nodeValue;
});
var newElement = $("<" + newType + "/>", attrs).append($(this).contents());
$(this).replaceWith(newElement);
newElements.push(newElement);
});
return $(newElements);
};
Die Antwort von @ Jazzbo gab ein jQuery-Objekt zurück, das ein Array von jQuery-Objekten enthielt, das nicht verkettbar war. Ich habe es so geändert, dass es ein Objekt zurückgibt, das dem ähnelt, was $ .each zurückgegeben hätte:
$.fn.changeElementType = function (newType) {
var newElements,
attrs,
newElement;
this.each(function () {
attrs = {};
$.each(this.attributes, function () {
attrs[this.nodeName] = this.nodeValue;
});
newElement = $("<" + newType + "/>", attrs).append($(this).contents());
$(this).replaceWith(newElement);
if (!newElements) {
newElements = newElement;
} else {
$.merge(newElements, newElement);
}
});
return $(newElements);
};
(Hat auch einige Code-Bereinigungen durchgeführt, damit jslint übergeben wird.)
eachSchleife neu deklarieren zu müssen ).
Ich kann mir nur vorstellen, alles manuell zu kopieren: Beispiel jsfiddle
HTML
<b class="xyzxterms" style="cursor: default; ">bryant keil bio</b>
Jquery / Javascript
$(document).ready(function() {
var me = $("b");
var newMe = $("<h1>");
for(var i=0; i<me[0].attributes.length; i++) {
var myAttr = me[0].attributes[i].nodeName;
var myAttrVal = me[0].attributes[i].nodeValue;
newMe.attr(myAttr, myAttrVal);
}
newMe.html(me.html());
me.replaceWith(newMe);
});
@ Andrew Whitaker: Ich schlage diese Änderung vor:
$.fn.changeElementType = function(newType) {
var attrs = {};
$.each(this[0].attributes, function(idx, attr) {
attrs[attr.nodeName] = attr.nodeValue;
});
var newelement = $("<" + newType + "/>", attrs).append($(this).contents());
this.replaceWith(newelement);
return newelement;
};
Dann können Sie Dinge tun wie: $('<div>blah</div>').changeElementType('pre').addClass('myclass');
Ich mag die Idee von @AndrewWhitaker und anderen, ein jQuery-Plugin zu verwenden - um das hinzuzufügen changeElementType() Methode . Aber ein Plugin ist wie eine Blackbox, egal wie der Code aussieht, wenn er klein ist und gut funktioniert ... Leistung ist also erforderlich und am wichtigsten als Code.
"Pure Javascript" hat eine bessere Leistung als jQuery: Ich denke, dass der Code von @ FelixKling eine bessere Leistung hat als der von @ AndrewWhitaker und anderen.
Hier ein "reines Javavascript" (und "reines DOM") Code, gekapselt in ein jQuery-Plugin :
(function($) { // @FelixKling's code
$.fn.changeElementType = function(newType) {
for (var k=0;k<this.length; k++) {
var e = this[k];
var new_element = document.createElement(newType),
old_attributes = e.attributes,
new_attributes = new_element.attributes,
child = e.firstChild;
for(var i = 0, len = old_attributes.length; i < len; i++) {
new_attributes.setNamedItem(old_attributes.item(i).cloneNode());
}
do {
new_element.appendChild(e.firstChild);
}
while(e.firstChild);
e.parentNode.replaceChild(new_element, e);
}
return this; // for chain... $(this)? not working with multiple
}
})(jQuery);
Hier ist eine Methode, mit der ich HTML-Tags in jquery ersetze:
// Iterate over each element and replace the tag while maintaining attributes
$('b.xyzxterms').each(function() {
// Create a new element and assign it attributes from the current element
var NewElement = $("<h1 />");
$.each(this.attributes, function(i, attrib){
$(NewElement).attr(attrib.name, attrib.value);
});
// Replace the current element with the new one and carry over the contents
$(this).replaceWith(function () {
return $(NewElement).append($(this).contents());
});
});
jQuery ohne über Attribute zu iterieren:Das replaceElemVerfahren , das unten übernimmt old Tag, new Tagund contextund führt den Austausch erfolgreich:
replaceElem('h2', 'h1', '#test');
function replaceElem(oldElem, newElem, ctx) {
oldElems = $(oldElem, ctx);
//
$.each(oldElems, function(idx, el) {
var outerHTML, newOuterHTML, regexOpeningTag, regexClosingTag, tagName;
// create RegExp dynamically for opening and closing tags
tagName = $(el).get(0).tagName;
regexOpeningTag = new RegExp('^<' + tagName, 'i');
regexClosingTag = new RegExp(tagName + '>$', 'i');
// fetch the outer elem with vanilla JS,
outerHTML = el.outerHTML;
// start replacing opening tag
newOuterHTML = outerHTML.replace(regexOpeningTag, '<' + newElem);
// continue replacing closing tag
newOuterHTML = newOuterHTML.replace(regexClosingTag, newElem + '>');
// replace the old elem with the new elem-string
$(el).replaceWith(newOuterHTML);
});
}
h1 {
color: white;
background-color: blue;
position: relative;
}
h1:before {
content: 'this is h1';
position: absolute;
top: 0;
left: 50%;
font-size: 5px;
background-color: black;
color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test">
<h2>Foo</h2>
<h2>Bar</h2>
</div>
Viel Glück...
Javascript-Lösung
Kopieren Sie die Attribute des alten Elements in das neue Element
const $oldElem = document.querySelector('.old')
const $newElem = document.createElement('div')
Array.from($oldElem.attributes).map(a => {
$newElem.setAttribute(a.name, a.value)
})
Ersetzen Sie das alte Element durch das neue Element
$oldElem.parentNode.replaceChild($newElem, $oldElem)
maperstellt ein neues nicht verwendetes Array, das durch ersetzt werden könnte forEach.
Hier ist meine Version. Es handelt sich im Grunde genommen um die Version von @ fiskhandlarn, aber anstatt ein neues jQuery-Objekt zu erstellen, werden einfach die alten Elemente mit den neu erstellten überschrieben, sodass kein Zusammenführen erforderlich ist.
Demo: http://jsfiddle.net/0qa7wL1b/
$.fn.changeElementType = function( newType ){
var $this = this;
this.each( function( index ){
var atts = {};
$.each( this.attributes, function(){
atts[ this.name ] = this.value;
});
var $old = $(this);
var $new = $('<'+ newType +'/>', atts ).append( $old.contents() );
$old.replaceWith( $new );
$this[ index ] = $new[0];
});
return this;
};