Tôi có mã sau
<b class="xyzxterms" style="cursor: default; ">bryant keil bio</b>
Làm cách nào để thay thế b
thẻ thành h1
thẻ nhưng vẫn giữ tất cả các thuộc tính và thông tin khác?
Tôi có mã sau
<b class="xyzxterms" style="cursor: default; ">bryant keil bio</b>
Làm cách nào để thay thế b
thẻ thành h1
thẻ nhưng vẫn giữ tất cả các thuộc tính và thông tin khác?
Câu trả lời:
Đây là một cách bạn có thể làm với jQuery:
var attrs = { };
$.each($("b")[0].attributes, function(idx, attr) {
attrs[attr.nodeName] = attr.nodeValue;
});
$("b").replaceWith(function () {
return $("<h1 />", attrs).append($(this).contents());
});
Ví dụ: http://jsfiddle.net/yapHk/
Cập nhật , đây là một 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);
Ví dụ: http://jsfiddle.net/mmNNJ/
children
không hoạt động nhưng contents
đã làm.
.each
khối như câu trả lời bên dưới cũng hiển thị.
Không chắc chắn về jQuery. Với JavaScript đơn giản, bạn có thể làm:
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);
Tuy nhiên, không chắc chắn điều này tương thích với nhiều trình duyệt như thế nào.
Một biến thể có thể là:
for(var i = 0, len = old_attributes.length; i < len; i++) {
new_element.setAttribute(old_attributes[i].name, old_attributes[i].value);
}
Để biết thêm thông tin, hãy xem Node.attributes
[MDN] .
while(child = child.nextSibling)
không thành công. Cảm ơn!
@jakov và @Andrew Whitaker
Đây là một cải tiến hơn nữa để nó có thể xử lý nhiều phần tử cùng một lúc.
$.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);
};
Câu trả lời của @ Jazzbo trả về một đối tượng jQuery chứa một mảng các đối tượng jQuery, không thể ghép được. Tôi đã thay đổi nó để nó trả về một đối tượng giống với những gì $ .each sẽ trả về:
$.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);
};
(Cũng đã thực hiện một số dọn dẹp mã để nó vượt qua jslint.)
each
vòng lặp).
Cách duy nhất tôi có thể nghĩ đến là sao chép mọi thứ theo cách thủ công: ví dụ 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: Tôi đề xuất thay đổi này:
$.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;
};
Sau đó, bạn có thể làm những việc như: $('<div>blah</div>').changeElementType('pre').addClass('myclass');
Tôi thích ý tưởng của @AndrewWhitaker và những người khác, sử dụng một plugin jQuery - để thêm changeElementType()
phương thức. Nhưng một plugin giống như một hộp đen, không có phần mềm nào về mã, nếu nó hoạt động tốt ... Vì vậy, hiệu suất là bắt buộc, và quan trọng nhất là mã.
"JavaScript thuần túy" có hiệu suất tốt hơn jQuery: Tôi nghĩ rằng mã của @ FelixKling có hiệu suất tốt hơn mã của @ AndrewWhitaker và các mã khác.
Đây là mã "Javavascript thuần" (và "DOM thuần"), được đóng gói trong một plugin jQuery :
(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);
Đây là một phương pháp tôi sử dụng để thay thế các thẻ html trong jquery:
// 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
mà không cần lặp qua các thuộc tính:Các replaceElem
phương pháp dưới đây chấp nhận old Tag
, new Tag
và context
và thực hiện việc thay thế thành công:
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>
Chúc may mắn...
Giải pháp Javascript
Sao chép các thuộc tính của phần tử cũ sang phần tử mới
const $oldElem = document.querySelector('.old')
const $newElem = document.createElement('div')
Array.from($oldElem.attributes).map(a => {
$newElem.setAttribute(a.name, a.value)
})
Thay thế phần tử cũ bằng phần tử mới
$oldElem.parentNode.replaceChild($newElem, $oldElem)
map
tạo một mảng mới chưa sử dụng, nó có thể được thay thế bằng forEach
.
Đây là phiên bản của tôi. Về cơ bản đây là phiên bản của @ fiskhandlarn, nhưng thay vì xây dựng một đối tượng jQuery mới, nó chỉ ghi đè các phần tử cũ bằng các phần tử mới được tạo, vì vậy không cần hợp nhất.
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;
};