Есть ли простой способ перебрать все теги td и изменить их на th? (И т.д.).
Мой текущий подход состоял бы в том, чтобы обернуть их с помощью th, а затем удалить td, но затем я потеряю другие свойства и т.д.
Есть ли простой способ перебрать все теги td и изменить их на th? (И т.д.).
Мой текущий подход состоял бы в том, чтобы обернуть их с помощью th, а затем удалить td, но затем я потеряю другие свойства и т.д.
Полностью непроверенный, но дающий этому вихрь:
$("td").each(function(index) {
var thisTD = this;
var newElement = $("<th></th>");
$.each(this.attributes, function(index) {
$(newElement).attr(thisTD.attributes[index].name, thisTD.attributes[index].value);
});
$(this).after(newElement).remove();
});
Я смотрю и смотрю на него, и я не могу придумать, почему это не сработает!
1) через каждый элемент td
2) создать новый элемент
3) для каждого из этих td, цикл над каждым из его атрибутов
4) добавьте этот атрибут и значение в новый элемент
5) после того, как все атрибуты на месте, добавьте элемент в DOM сразу после td и удалите td
Изменить: отлично работает: http://jsbin.com/uqofu3/edit
Ниже приведен плагин jQuery для замены имени тега элементов DOM.
(function($) {
$.fn.replaceTagName = function(replaceWith) {
var tags = [],
i = this.length;
while (i--) {
var newElement = document.createElement(replaceWith),
thisi = this[i],
thisia = thisi.attributes;
for (var a = thisia.length - 1; a >= 0; a--) {
var attrib = thisia[a];
newElement.setAttribute(attrib.name, attrib.value);
};
newElement.innerHTML = thisi.innerHTML;
$(thisi).after(newElement).remove();
tags[i] = newElement;
}
return $(tags);
};
})(window.jQuery);
(function(e){e.fn.replaceTagName=function(t){var n=[],r=this.length;while(r--){var i=document.createElement(t),s=this[r],o=s.attributes;for(var u=o.length-1;u>=0;u--){var a=o[u];i.setAttribute(a.name,a.value)}i.innerHTML=s.innerHTML;e(s).after(i).remove();n[r]=i}return e(n)}})(window.jQuery);
Включите указанный выше миниатюрный источник в javascript после jQuery.
Затем вы можете использовать плагин следующим образом:
$('div').replaceTagName('span'); // replace all divs with spans
Или в вашем случае это:
$('td').replaceTagName('th');
Селекторы jQuery работают как ожидалось
$('.replace_us').replaceTagName('span'); // replace all elements with "replace_us" class with spans
$('#replace_me').replaceTagName('div'); // replace the element with the id "replace_me"
$("td").each(function() {
var tmp = $('<div/>').append($(this).clone(true)).html().replace(/td/i,'th');
$(this).after(tmp).remove();
});
или чистый DOM
function replaceElm(oldTagName, newTagName, targetElm) {
var target = targetElm || window.document;
var allFound = target.getElementsByTagName(oldTagName);
for (var i=0; i<allFound.length; i++) {
var tmp = document.createElement(newTagName);
for (var k=0; k<allFound[i].attributes.length; k++) {
var name = allFound[i].attributes[k].name;
var val = allFound[i].attributes[k].value;
tmp.setAttribute(name,val);
}
tmp.innerHTML = allFound[i].innerHTML;
allFound[i].parentNode.insertBefore(tmp, allFound[i]);
allFound[i].parentNode.removeChild(allFound[i]);
}
}
replaceElm('td','th',document.getElementsByTagName('table')[0]);
DOM всегда быстрее: http://jsperf.com/replace-tag-names
Это может сработать, но я не тестировал его широко:
var tds = document.getElementsByTagName("td");
while(tds[0]){
var t = document.createElement("th");
var a = tds[0].attributes;
for(var i=0;i<a.length;i++) t.setAttribute(a[i].nodeName,a[i].nodeValue);
t.innerHTML = tds[0].innerHTML;
tds[0].parentNode.insertBefore(t,tds[0]);
tds[0].parentNode.removeChild(tds[0]);
}
Я надеюсь, что это поможет в некотором роде.
Незначительное дополнение к ответу @GlenCrawford, чтобы сохранить внутренний текст с помощью строки:
newElement.text($(value).text());
Теперь все вместе:
$("td").each(function(index) {
var thisTD = this;
var newElement = $("<th></th>");
newElement.text($(value).text());
$.each(this.attributes, function(index) {
$(newElement).attr(thisTD.attributes[index].name, thisTD.attributes[index].value);
});
$(this).after(newElement).remove();
});
Ну, этот вопрос довольно старый, но это может помочь в любом случае: единственный плагин jQuery, который действительно работает так, как ожидалось (вы не можете повторно использовать возвращенный объект в другом, чтобы добавить атрибуты, например):
jQuery.fn.extend({
replaceTagName: function(replaceWith) {
var tags=[];
this.each(function(i,oldTag) {
var $oldTag=$(oldTag);
var $newTag=$($("<div />").append($oldTag.clone(true)).html().replace(new RegExp("^<"+$oldTag.prop("tagName"),"i"),"<"+replaceWith));
$oldTag.after($newTag).remove();
tags.push($newTag.get(0));
});
return $(tags);
}
});
Помимо основного $("td").replaceTagName("th");
, вы также можете создавать вызовы типа $("td").replaceTagName("th").attr("title","test");
Минимальная версия:
jQuery.fn.extend({replaceTagName:function(a){var b=[];this.each(function(d,c){var e=$(c);var f=$($("<div />").append(e.clone(true)).html().replace(new RegExp("^<"+e.prop("tagName"),"i"),"<"+a));e.after(f).remove();b.push(f.get(0))});return $(b)}});
Это немного чище, чем ответ @GlenCrawford, и дополнительно копирует дочерние элементы замененного элемента.
$('td').each(function(){
var newElem = $('<th></th>', {html: $(this).html()});
$.each(this.attributes, function() {
newElem.attr(this.name, this.value);
});
$(this).replaceWith(newElem);
});
document.body.innerHTML=document.body.innerHTML.replace(/(\<td\>)|(\<td\s)|(\<\/td\>)/gi,function(x){return x.replace("td","th");})