获取选定元素的外部超文本标记语言

我正在尝试使用jQuery获取选定对象的超文本标记语言。我知道.html()函数;问题是我需要包含选定对象的超文本标记语言(在这种情况下是表行,其中.html()仅返回行内的单元格)。

我四处搜索,发现了一些非常“hackish”类型的克隆对象的方法,将其添加到新创建的div中,等等,但这似乎真的很肮脏。有没有更好的方法,或者新版本的jQuery(1.4.2)提供任何类型的outerHtml功能?

478587 次浏览
$("#myTable").parent().html();

也许我没有正确理解你的问题,但这将获得所选元素的父元素的html。

这就是你想要的吗?

2014年编辑:这个问题和这个回复来自2010年。当时,没有更好的解决方案被广泛使用。现在,许多其他回复都更好:例如埃里克·胡的,或Re Capcha的。

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

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

扩展jQuery:

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

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

node.cloneNode()看起来不像是一个黑客。你可以克隆节点并将其附加到任何所需的父元素,还可以通过操作单个属性来操作它,而不必在其上运行正则表达式,或将其添加到DOM中,然后在后面操作它。

也就是说,您也可以遍历元素的属性来构造它的超文本标记语言字符串表示。这似乎是jQuery添加的任何outerHTML函数的实现方式。

我使用Jessica的解决方案(由Josh编辑)让outerHTML在Firefox上工作。然而,问题是我的代码被破坏了,因为她的解决方案将元素包装成DIV。再添加一行代码就解决了这个问题。

以下代码为您提供outerHTML,但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();

希望有人觉得有用!

不需要为它生成函数。只需像这样做:

$('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标签,因为它打字更少并且工作方式相同。

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

可以说,“外部”超文本标记语言只有在您拥有单个元素时才真正有意义,但是在某些情况下,获取超文本标记语言元素列表并将它们转换为标记是有意义的。

扩展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解决方案的另一个问题已修复,请参阅上面的评论。

类似的解决方案添加了临时DOM对象的remove()

我同意阿潘(12月13日10: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;}};

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

与仅返回元素的超文本标记语言内容的. html()不同,此版本的. outerHTML()返回所选元素及其超文本标记语言内容或将其替换为. replace eWith()方法,但不同之处在于允许替换超文本标记语言由链接继承。

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

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

$.fn.outerHTML = function (arg) {var ret;
// If no items in the collection, returnif (!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;}elseel[inOrOut] = arg;
if (!el.outerHTML)$(el).children().unwrap();});
return this;}

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

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

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

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

你也可以这样做

document.getElementById(id).outerHTML

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

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

更新新版本具有更好的控制以及更友好的jQuery选择器服务!:)

;(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>

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

其中“x”是节点号,从0开始作为第一个节点,如果你想得到一个特定的节点,应该得到你想要的正确节点。如果你有子节点,你真的应该在你想要的节点上放一个ID,然后把那个归零。使用这个方法论,没有“x”对我来说很好。

我相信目前(5/1/2012),所有主要浏览器都支持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 elementsvar 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

这对于更改dom上的元素非常有用,但在将html字符串传入jQuery时不适用于ie,如下所示:

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

经过一些操作后,我创建了一个函数,允许上述函数在ie中为html字符串工作:

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

我已经做了这个简单的测试,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");

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

outerHTML:81ms
outterHTML2:439ms

但是如果我们使用没有本机outerHTML函数的Tokimon解决方案(现在几乎每个浏览器都支持)

我们得到

outerHTML:594ms
outterHTML2: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)

简单的解决方案。

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

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

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

当然,像这样使用它:

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

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

我遇到了同样的问题,因为它返回了innerHtml,所以缺少TR标签,TR标签保存了该行的ID,这意味着不可能重复该过程。

我找到的答案是jQueryremove()函数实际上返回了它删除的元素作为对象。因此,要删除并重新添加一行,就像这样简单…

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

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

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

点击这里:http://jsfiddle.net/ezmilhouse/Mv76a/

如果场景动态附加新行,您可以使用以下命令:

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

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

这是一个非常优化的jQuery outerHTML插件:(http://jsperf.com/outerhtml-vs-jquery-clone-hack/5=>另外两个快速代码片段与FF<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=>我不同意你的观点。outerHMTL不需要getter和setter:jQuery已经给了我们'replace eWith'…

为什么加入所有outerHTML?jquery.html只返回FIRST元素的超文本标记语言内容。

(对不起,没有足够的声誉来写评论)

什么是prop('outerHTML')

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

并设置:

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

它为我工作。

PS:这是在jQuery 1.6中添加的。

您还可以使用收到(检索与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">'

短暂而甜蜜。

[].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, '')

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

这对于vanilla JavaScript来说非常简单…

document.querySelector('#selector')

jQuery插件作为速记直接获取全元素超文本标记语言:

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

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

纯JavaScript:

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