Aşağıdaki koda sahibim
<b class="xyzxterms" style="cursor: default; ">bryant keil bio</b>
bEtiketi bir h1etiketle değiştirip diğer tüm nitelikleri ve bilgileri nasıl saklarım?
Aşağıdaki koda sahibim
<b class="xyzxterms" style="cursor: default; ">bryant keil bio</b>
bEtiketi bir h1etiketle değiştirip diğer tüm nitelikleri ve bilgileri nasıl saklarım?
Yanıtlar:
İşte jQuery ile yapmanın bir yolu:
var attrs = { };
$.each($("b")[0].attributes, function(idx, attr) {
attrs[attr.nodeName] = attr.nodeValue;
});
$("b").replaceWith(function () {
return $("<h1 />", attrs).append($(this).contents());
});
Örnek: http://jsfiddle.net/yapHk/
Güncelleme , işte bir eklenti:
(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);
Örnek: http://jsfiddle.net/mmNNJ/
childrenişe yaramadı ama contentsyaptı.
.eachAşağıdaki yanıtın da gösterdiği gibi , gerçekten bir bloğa sarılmalıdır .
JQuery hakkında emin değilim. Düz JavaScript ile şunları yapabilirsiniz:
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);
Ancak bunun tarayıcılar arası ne kadar uyumlu olduğundan emin değilim.
Bir varyasyon şunlar olabilir:
for(var i = 0, len = old_attributes.length; i < len; i++) {
new_element.setAttribute(old_attributes[i].name, old_attributes[i].value);
}
Daha fazla bilgi için Node.attributes [MDN] konusuna bakın .
while(child = child.nextSibling)başarısız oldu. Teşekkürler!
@jakov ve @Andrew Whitaker
Burada, aynı anda birden fazla öğeyi işleyebilmesi için daha fazla iyileştirme var.
$.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);
};
@ Jazzbo'nun yanıtı, zincirlenebilir olmayan bir dizi jQuery nesnesi içeren bir jQuery nesnesi döndürdü. Bunu, $ .each'in döndürdüğüne daha benzer bir nesne döndürmesi için değiştirdim:
$.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);
};
(Ayrıca jslint'i geçmesi için bazı kod temizleme yaptı.)
eachdöngüde değişkenleri yeniden bildirmek zorunda kalmadan ).
Aklıma gelen tek yol, her şeyi manuel olarak kopyalamak: örnek 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: Bu değişikliği öneriyorum:
$.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;
};
O zaman aşağıdaki gibi şeyler yapabilirsiniz: $('<div>blah</div>').changeElementType('pre').addClass('myclass');
changeElementType()Yöntemi eklemek için @AndrewWhitaker ve diğerlerinin bir jQuery eklentisi kullanma fikrini seviyorum . Ancak bir eklenti bir kara kutu gibidir, kodla ilgili bir konu yoktur, eğer küçükse ve iyi çalışıyorsa ... Bu nedenle, performans gereklidir ve koddan en önemlisidir.
"Saf javascript" sahip iyi performans jQuery daha: Ben FelixKling koduna @ AndrewWhitaker en ve diğerleri @ daha iyi bir performansa sahip olduğunu düşünüyorum.
Burada, bir jQuery eklentisine kapsüllenmiş "saf Javavascript" (ve "saf DOM") kodu :
(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);
İşte jquery'de html etiketlerini değiştirmek için kullandığım bir yöntem:
// 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 olmaksızın özelliklerini yineleme:replaceElemYöntem aşağıda kabul old Tag, new Tagve contextve başarılı bir şekilde yerine yürütür:
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>
İyi şanslar...
Javascript çözümü
Eski elemanın niteliklerini yeni elemana kopyalayın
const $oldElem = document.querySelector('.old')
const $newElem = document.createElement('div')
Array.from($oldElem.attributes).map(a => {
$newElem.setAttribute(a.name, a.value)
})
Eski elemanı yeni elemanla değiştirin
$oldElem.parentNode.replaceChild($newElem, $oldElem)
mapkullanılmayan yeni bir dizi yaratırsa, ile değiştirilebilir forEach.
İşte benim versiyonum. Temelde @ fiskhandlarn'ın sürümüdür, ancak yeni bir jQuery nesnesi oluşturmak yerine, yeni oluşturulanların eski öğelerin üzerine yazar, dolayısıyla birleştirme gerekmez.
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;
};