获取所选元素的外部HTML

时间:2010-03-10 19:09:03

标签: jquery

我正在尝试使用jQuery获取所选对象的HTML。我知道.html()函数;问题是我需要包含所选对象的HTML(在这种情况下是一个表行,其中.html()只返回行内的单元格。)

我已经四处搜索,发现了一些克隆对象的非常“黑客”类型的方法,将它添加到新创建的div等等,但这看起来真的很脏。有没有更好的方法,或新版本的jQuery(1.4.2)是否提供任何类型的outerHtml功能?

30 个答案:

答案 0 :(得分:653)

我相信目前(2012年5月1日),所有主流浏览器都支持outerHTML功能。在我看来,这个片段就足够了。我个人会选择记住这个:

// Gives you the DOM element without the outside wrapper you want
$('.classSelector').html()

// Gives you the outside wrapper as well only for the first element
$('.classSelector')[0].outerHTML

// Gives you the outer HTML for all the selected elements
var html = '';
$('.classSelector').each(function () {
    html += this.outerHTML;
});

//Or if you need a one liner for the previous code
$('.classSelector').get().map(function(v){return v.outerHTML}).join('');
对于element.outerHTML

编辑Basic support stats

答案 1 :(得分:342)

无需为其生成功能。就这样做:

$('a').each(function(){
    var s = $(this).clone().wrap('<p>').parent().html();
    console.log(s);
});

(顺便提一下,您的浏览器控制台将显示记录的内容。自2009年左右以来,大多数最新的浏览器都具有此功能。)

魔术就是这样:

.clone().wrap('<p>').parent().html();

克隆意味着你实际上并没有打扰DOM。没有它就运行它,你会看到在所有超链接之前/之后插入p标签(在这个例子中),这是不可取的。所以,是的,请使用.clone()

它的工作方式是它需要每个a标记,在RAM中复制它,包装p标记,获取它的父标记(意味着p标记),然后获取它的innerHTML属性。

编辑:提出建议并将div代码更改为p代码,因为它的输入次数较少且效果相同。

答案 2 :(得分:186)

2014编辑:问题和回复是从2010年开始的。当时,还没有更好的解决方案可供使用。现在,其他许多回复都更好:例如Eric Hu's,或Re Capcha's。

这个网站似乎有一个解决方案: jQuery: outerHTML | Yelotofu

jQuery.fn.outerHTML = function(s) {
    return s
        ? this.before(s).remove()
        : jQuery("<p>").append(this.eq(0).clone()).html();
};

答案 3 :(得分:138)

怎么样:prop('outerHTML')

var outerHTML_text = $('#item-to-be-selected').prop('outerHTML');

并设置:

$('#item-to-be-selected').prop('outerHTML', outerHTML_text);

它对我有用。

PS :这已添加到jQuery 1.6

答案 4 :(得分:89)

扩展jQuery:

(function($) {
  $.fn.outerHTML = function() {
    return $(this).clone().wrap('<div></div>').parent().html();
  };
})(jQuery);

并使用它:$("#myTableRow").outerHTML();

答案 5 :(得分:42)

我同意Arpan(2010年12月13日5:59)。

他这样做的方式实际上是一种更好的方法,因为你不使用克隆。克隆方法非常耗时,如果你有子元素,没有其他人似乎关心IE实际上有outerHTML属性(是的IE实际上有一些有用的技巧)。

但我可能会创建他的脚本有点不同:

$.fn.outerHTML = function() {
    var $t = $(this);
    if ($t[0].outerHTML !== undefined) {
        return $t[0].outerHTML;
    } else {
        var content = $t.wrap('<div/>').parent().html();
        $t.unwrap();
        return content;
    }
};

答案 6 :(得分:18)

要成为真正的jQuery-esque,您可能希望outerHTML()成为一个getter 一个setter,其行为尽可能与html()类似:

$.fn.outerHTML = function (arg) {
    var ret;

    // If no items in the collection, return
    if (!this.length)
        return typeof arg == "undefined" ? this : null;
    // Getter overload (no argument passed)
    if (!arg) {
        return this[0].outerHTML || 
            (ret = this.wrap('<div>').parent().html(), this.unwrap(), ret);
    }
    // Setter overload
    $.each(this, function (i, el) {
        var fnRet, 
            pass = el,
            inOrOut = el.outerHTML ? "outerHTML" : "innerHTML";

        if (!el.outerHTML)
            el = $(el).wrap('<div>').parent()[0];

        if (jQuery.isFunction(arg)) { 
            if ((fnRet = arg.call(pass, i, el[inOrOut])) !== false)
                el[inOrOut] = fnRet;
        }
        else
            el[inOrOut] = arg;

        if (!el.outerHTML)
            $(el).children().unwrap();
    });

    return this;
}
  

工作演示:http://jsfiddle.net/AndyE/WLKAa/

这允许我们将参数传递给outerHTML,这可以是

  • 可取消的函数 - function (index, oldOuterHTML) { } - 其中返回值将成为元素的新HTML(除非返回false)。
  • 一个字符串,它将被设置为代替每个元素的HTML。

有关详细信息,请参阅html()的jQuery文档。

答案 7 :(得分:15)

您还可以使用get(检索jQuery对象匹配的DOM元素。)。

e.g:

$('div').get(0).outerHTML;//return "<div></div>"

作为扩展方法:

jQuery.fn.outerHTML = function () {
  return this.get().map(function (v) {
    return v.outerHTML
  }).join()
};

或者

jQuery.fn.outerHTML = function () {
  return $.map(this.get(), function (v) {
    return v.outerHTML
  }).join()
};

多项选择并返回所有匹配元素的外部html。

$('input').outerHTML()

返回:

'<input id="input1" type="text"><input id="input2" type="text">'

答案 8 :(得分:10)

要将完整的jQuery插件设为.outerHTML,请将以下脚本添加到任何js文件中,并在标题中包含jQuery之后:

  

update 新版本有更好的控制以及更多jQuery Selector友好服务! :)

;(function($) {
    $.extend({
        outerHTML: function() {
            var $ele = arguments[0],
                args = Array.prototype.slice.call(arguments, 1)
            if ($ele && !($ele instanceof jQuery) && (typeof $ele == 'string' || $ele instanceof HTMLCollection || $ele instanceof Array)) $ele = $($ele);
            if ($ele.length) {
                if ($ele.length == 1) return $ele[0].outerHTML;
                else return $.map($("div"), function(ele,i) { return ele.outerHTML; });
            }
            throw new Error("Invalid Selector");
        }
    })
    $.fn.extend({
        outerHTML: function() {
            var args = [this];
            if (arguments.length) for (x in arguments) args.push(arguments[x]);
            return $.outerHTML.apply($, args);
        }
    });
})(jQuery);

这将使您不仅可以获得一个元素的outerHTML,甚至可以同时获得多个元素的Array返回!并且可以在两种jQuery标准样式中使用:

$.outerHTML($("#eleID")); // will return outerHTML of that element and is 
// same as
$("#eleID").outerHTML();
// or
$.outerHTML("#eleID");
// or
$.outerHTML(document.getElementById("eleID"));

对于多个元素

$("#firstEle, .someElesByClassname, tag").outerHTML();

摘录示例:

console.log('$.outerHTML($("#eleID"))'+"\t", $.outerHTML($("#eleID"))); 
console.log('$("#eleID").outerHTML()'+"\t\t", $("#eleID").outerHTML());
console.log('$("#firstEle, .someElesByClassname, tag").outerHTML()'+"\t", $("#firstEle, .someElesByClassname, tag").outerHTML());

var checkThisOut = $("div").outerHTML();
console.log('var checkThisOut = $("div").outerHTML();'+"\t\t", checkThisOut);
$.each(checkThisOut, function(i, str){ $("div").eq(i).text("My outerHTML Was: " + str); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://rawgit.com/JDMcKinstry/ce699e82c7e07d02bae82e642fb4275f/raw/deabd0663adf0d12f389ddc03786468af4033ad2/jQuery.outerHTML.js"></script>
<div id="eleID">This will</div>
<div id="firstEle">be Replaced</div>
<div class="someElesByClassname">At RunTime</div>
<h3><tag>Open Console to see results</tag></h3>

答案 9 :(得分:8)

你也可以这样做

document.getElementById(id).outerHTML

其中id是您要查找的元素的ID

答案 10 :(得分:6)

我使用了Jessica的解决方案(由Josh编辑)来使outerHTML能够在Firefox上运行。然而问题是我的代码破坏了,因为她的解决方案将元素包装到DIV中。再添加一行代码解决了这个问题。

以下代码为您提供了外部HTML,使DOM树保持不变。

$jq.fn.outerHTML = function() {
    if ($jq(this).attr('outerHTML'))
        return $jq(this).attr('outerHTML');
    else
    {
    var content = $jq(this).wrap('<div></div>').parent().html();
        $jq(this).unwrap();
        return content;
    }
}

并像这样使用:$(“#myDiv”)。outerHTML();

希望有人发现它有用!

答案 11 :(得分:5)

// no cloning necessary    
var x = $('#xxx').wrapAll('<div></div>').parent().html(); 
alert(x);

在这里小提琴:http://jsfiddle.net/ezmilhouse/Mv76a/

答案 12 :(得分:3)

如果方案是动态追加新行,您可以使用:

var row = $(".myRow").last().clone();
$(".myRow").last().after(row);

.myrow<tr>的类名。它会复制最后一行并将其作为新的最后一行插入。 这也适用于 IE7 ,而[0].outerHTML方法不允许 ie7

中的分配

答案 13 :(得分:2)

你可以在https://github.com/darlesson/jquery-outerhtml找到一个好的.outerHTML()选项。

与仅返回元素的HTML内容的.html()不同,此版本的.outerHTML()返回所选元素及其HTML内容,或将其替换为.replaceWith()方法,但区别在于允许替换HTML被链接继承。

示例也可以在上面的URL中看到。

答案 14 :(得分:2)

Anothe similar solution添加了remove()临时DOM对象。

答案 15 :(得分:2)

请注意,Josh的解决方案仅适用于单个元素。

可以说,当你有一个单独的元素时,“外部”HTML才真正有意义,但在某些情况下,获取HTML元素列表并将其转换为标记是有意义的。

扩展Josh的解决方案,这个解决方案将处理多个元素:

(function($) {
  $.fn.outerHTML = function() {
    var $this = $(this);
    if ($this.length>1)
      return $.map($this, function(el){ return $(el).outerHTML(); }).join('');
    return $this.clone().wrap('<div/>').parent().html();
  }
})(jQuery);

编辑:修复了Josh解决方案的另一个问题,请参阅上面的评论。

答案 16 :(得分:2)

我使用outerHTML做了这个简单的测试是tokimon解决方案(没有克隆),而outerHTML2是jessica解决方案(克隆)

console.time("outerHTML");
for(i=0;i<1000;i++)
 {                 
  var html = $("<span style='padding:50px; margin:50px; display:block'><input type='text' title='test' /></span>").outerHTML();
 }                 
console.timeEnd("outerHTML");

console.time("outerHTML2");

 for(i=0;i<1000;i++)
 {                 
   var html = $("<span style='padding:50px; margin:50px; display:block'><input type='text' title='test' /></span>").outerHTML2();
  }                 
  console.timeEnd("outerHTML2");

我的chrome(版本20.0.1132.57(0))浏览器中的结果是

outerHTML:81ms
outerHTML2:439ms

但是如果我们使用没有原生outerHTML功能的tokimon解决方案(现在几乎每个浏览器都支持它)

我们得到了

outerHTML:594ms
outerHTML2:332ms

并且在现实世界的例子中会有更多的循环和元素,所以完美的组合将是

$.fn.outerHTML = function() 
{
  $t = $(this);
  if( "outerHTML" in $t[0] ) return $t[0].outerHTML; 
  else return $t.clone().wrap('<p>').parent().html(); 
}

所以克隆方法实际上比包装/解包方法更快 (jquery 1.7.2)

答案 17 :(得分:2)

我使用过Jessica更新的Volomike解决方案。只需添加一个检查以查看该元素是否存在,并使其返回空白,以防它不存在。

jQuery.fn.outerHTML = function() {
return $(this).length > 0 ? $(this).clone().wrap('<div />').parent().html() : '';
};

当然,请使用它:

$('table#buttons').outerHTML();

答案 18 :(得分:2)

node.cloneNode()似乎不是一个黑客。您可以克隆节点并将其附加到任何所需的父元素,并通过操纵单个属性来操纵它,而不是必须例如在其上运行正则表达式,或将其添加到DOM中,然后在之后对其进行操作。

也就是说,你也可以iterate over the attributes of the element构建它的HTML字符串表示。似乎这就是jQuery添加一个外部HTML实现的方式。

答案 19 :(得分:1)

这对于更改dom上的元素很有用,但不适用于将html字符串传递给jquery时:

$('<div id="foo">Some <span id="blog">content</span></div>').find('#blog').outerHTML();

经过一些操作后,我创建了一个函数,允许上面的工作,即对于html字符串:

$.fn.htmlStringOuterHTML = function() {     
    this.parent().find(this).wrap('<div/>');        
    return this.parent().html();
};

答案 20 :(得分:1)

这对于香草JavaScript很简单...

document.querySelector('#selector')

答案 21 :(得分:1)

简短又甜蜜。

[].reduce($('.x'), function(i,v) {return i+v.outerHTML}, '')

或在箭头功能的帮助下更加甜蜜的事件

[].reduce.call($('.x'), (i,v) => i+v.outerHTML, '')

或根本没有jQuery

[].reduce.call(document.querySelectorAll('.x'), (i,v) => i+v.outerHTML, '')

或者如果您不喜欢这种方法,请检查

$('.x').get().reduce((i,v) => i+v.outerHTML, '')

答案 22 :(得分:1)

这是一个针对jquery的非常优化的outerHTML插件: (http://jsperf.com/outerhtml-vs-jquery-clone-hack/5 =&gt;其他2个快速代码段与某些浏览器不兼容,如FF&lt; 11)

(function($) {

  var DIV = document.createElement("div"),
      outerHTML;

  if ('outerHTML' in DIV) {
    outerHTML = function(node) {
      return node.outerHTML;
    };
  } else {
    outerHTML = function(node) {
      var div = DIV.cloneNode();
      div.appendChild(node.cloneNode(true));
      return div.innerHTML;
    };
  }

  $.fn.outerHTML = function() {
    return this.length ? outerHTML(this[0]) : void(0);
  };

})(jQuery);

@Andy E =&gt;我不同意你的看法。 outerHMTL不需要getter和setter:jQuery已经给我们'replaceWith'......

@mindplay =&gt;你为什么加入所有outerHTML? jquery.html仅返回FIRST元素的HTML内容。

(抱歉,没有足够的声誉来撰写评论)

答案 23 :(得分:0)

$.html = el => $("<div>"+el+"</div>").html().trim();

答案 24 :(得分:0)

作为直接获取整个元素HTML的简写的jQuery插件:

jQuery.fn.outerHTML = function () {
    return jQuery('<div />').append(this.eq(0).clone()).html();
};

并像这样使用它:$(".element").outerHTML();

答案 25 :(得分:0)

纯JavaScript:

var outerHTML = function(node) {
  var div = document.createElement("div");
  div.appendChild(node.cloneNode(true));
  return div.innerHTML;
};

答案 26 :(得分:-1)

我在寻找我的问题的答案时遇到了这个问题,那就是我试图删除一个表格行然后将其添加回表格的底部(因为我是动态创建数据行但是想要显示一个“添加新记录”类型行位于底部。)

我有同样的问题,因为它返回了innerHtml,所以缺少TR标签,它保存了该行的ID并且意味着无法重复该过程。

我发现答案是jquery remove()函数实际上将它作为对象返回的元素返回。因此,要删除并重新添加一行,就像这一样简单......

var a = $("#trRowToRemove").remove();            
$('#tblMyTable').append(a);  

如果您没有删除对象但想要将其复制到其他位置,请改用clone()函数。

答案 27 :(得分:-3)

$("#myNode").parent(x).html(); 

在哪里&#39; x&#39;是节点编号,从0开始作为第一个节点编号,如果您正在尝试获取特定节点,则应该获得所需的正确节点。如果您有子节点,那么您应该在所需的节点上放置一个ID,然后将该ID放在该节点上。使用该方法而不是&#39; x&#39;对我来说很好。

答案 28 :(得分:-4)

简单的解决方案。

var myself = $('#div').children().parent();

答案 29 :(得分:-12)

$("#myTable").parent().html();

也许我不能正确理解你的问题,但这会得到所选元素的父元素的html。

这就是你要追求的吗?