jQuery / JavaScript заменить тип тега - PullRequest
21 голосов
/ 12 мая 2010

Есть ли простой способ перебрать все теги td и изменить их на th? (И т.д.).

Мой текущий подход заключается в том, чтобы обернуть их с помощью th, а затем удалить td, но тогда я потеряю другие свойства и т. Д.

Ответы [ 8 ]

24 голосов
/ 27 февраля 2012

jQuery.replaceTagName

Ниже приведен плагин 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"

Больше ресурсов

jsFiddle с тестами Qunit

16 голосов
/ 12 мая 2010

Совершенно непроверено, но это приводит в движение:

$("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) для каждого из этих тд, зацикливаться на каждом из его атрибутов
4) добавить этот атрибут и значение в новый элемент th
5) как только все атрибуты будут на месте, добавьте элемент в DOM сразу после td и удалите td

Редактировать: отлично работает: http://jsbin.com/uqofu3/edit

5 голосов
/ 01 июля 2011
$("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

3 голосов
/ 12 мая 2010

Это может сработать, но я не проверял это подробно:

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

Надеюсь, это поможет.

0 голосов
/ 04 мая 2015

Это немного чище, чем ответ @ GlenCrawford, и дополнительно копирует дочерние элементы замененного элемента.

$('td').each(function(){
    var newElem = $('<th></th>', {html: $(this).html()});
    $.each(this.attributes, function() {
        newElem.attr(this.name, this.value);
    });
    $(this).replaceWith(newElem);
});
0 голосов
/ 28 апреля 2015
document.body.innerHTML=document.body.innerHTML.replace(/(\<td\>)|(\<td\s)|(\<\/td\>)/gi,function(x){return x.replace("td","th");})
0 голосов
/ 13 июля 2014

Ну, этот вопрос довольно старый, но в любом случае это может помочь: единственный плагин 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)}});
0 голосов
/ 08 ноября 2011

Небольшое дополнение к ответу @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();
});
...