ChatGPT解决这个技术问题 Extra ChatGPT

获取选定元素的外部 HTML

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

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

jQuery 没有办法做这样的事情,这太离谱了。我也需要这个。
我发布了一个功能请求,并引用了这个线程,最初的反应是积极的。 bugs.jquery.com/ticket/8142
为了节省一些人尝试 Ulhas Tuscano 的解决方案的几秒钟时间,它不起作用。
呃,事情正在发生。 $('div')[0].outerHTML
@Tuscan 的意思是 $("#selectorid").prop("outerHTML")

P
Protector one

相信目前(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 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('');

编辑Basic support stats 代表 element.outerHTML

Firefox (Gecko):11 .... 2012-03-13 发布

铬:0.2 ...... 2008-09-02 发布

Internet Explorer 4.0...1997 年发布

Opera 7 .... 2003-01-28 发布

Safari 1.3 .... 2006-01-12 发布


@SalmanPK FireFox 直到 2011 年 11 月 11 日才支持此属性。 bugzilla.mozilla.org/show_bug.cgi?id=92264仍有很多用户停留在 3.6 上。我认为这实际上是一个完美的例子,说明了为什么人们会选择使用 jQuery 而不是原生功能。
@LuciferSam Firefox 3.6 根据 gs.statcounter.com 的全球市场份额约为 6% 但是,filtering the results 到过去 6 个月(2012 年 12 月 11 日至 2012 年 5 月)和美国将其推离了前 12 名(低于 3 %)。我之所以选择这个窗口,是因为 this article 表明 FF 3.6 的使用率在 2012 年 1 月之后显着下降。鉴于这些数据,我支持我的解决方案,以实现更简单的代码而不是向后兼容性。
不能再同意了。这是正确的答案,而不是人们建议的其他内容。我选择的元素具有我想要保留的属性,这些属性会被其他答案丢失。地狱,这甚至可以在 IE 中使用!
不。Firefox 11 直到 2012 年 3 月 13 日(现已修复)才发布,即在撰写本文时不到一年前。 jQuery 的好处之一是它支持较旧的浏览器。我认为至少支持一年是合理的,有些网站显然会想要更多(记住,jQuery 支持 IE6)。
@EricHu statcounter 还指出 IE8 拥有 9.3% 的全球浏览器份额。然而,我的一些网站接近 40% 的标记。这都是相对的,并且因网站而异,Firefox 3.6 在我的一些网站上仍然占大约 10%。全球市场份额毫无意义。这一切都与您的网站受众有关。
p
philipvr

无需为它生成函数。这样做:

$('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 标记,因为它的输入更少且工作方式相同。


我想知道为什么 jQuery 团队不添加 outerHtml() 方法?
@Derek,那没关系。我使用 DIV 作为包装器,以便在其中获取一些东西。
.clone().wrap('

').parent().html();更短

是的,更少的击键,并达到相同的效果。
最好使用 DIV 而不是 P 作为通用解决方案 - 并非所有元素都可以作为有效的 HTML 包装在 P 中。
D
David V.

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

该网站似乎为您提供了解决方案:jQuery: outerHTML | Yelotofu

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

我看到了这一点,但试图避免它,因为它似乎很骇人听闻,而且应该有更好的方法,但它运作良好。谢谢。
$('[选择器]')[0].outerHTML
@drogon:请注意,Firefox 仅从版本 11(2012 年 3 月)开始支持 outerHTML
@PavingWays:为 Firefox 辩护:outerHTML 是微软发明的专有属性,而不是 W3C 标准。 (有趣的事实:innerHTML is standardized only since HTML5
纯 js el.outerHTML || document.createElement('div').appendChild( el.cloneNode( true ) ).parentNode.innerHTML
R
Re Captcha

怎么样:prop('outerHTML')

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

并设置:

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

它对我有用。

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


与其他答案相比,代码非常简洁。问:这是否具有与其他答案中提到的相同的 outerHTML 限制?它适用于 FF < 11 吗?
效果很好,这可能只是这里最好的解决方案。就浏览器而言,这应该与 outerHTLM 一样兼容。 prop() 方法基本上只是获取 outerHTML 属性。
这个解决方案更好,但是 Jquery 1.6.1 于 2011 年发布。问题(和我的回复)来自 2010 年。
对我来说“$('[selector]')[0].outerHTML;”在任何情况下都不起作用,但是 "$('#item-to-be-selected').prop('outerHTML');"是的!
$('#item-to-be-selected').attr('outerHTML'); //** 对于早期的 jQuery
G
Greeso

扩展 jQuery:

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

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


这个解决方案的小问题:你需要在你 wrap() 之前 clone(),否则你会在文档中留下额外的包装
谢谢,mindplay.dk - 我编辑了代码以纳入您的建议......很好。 :)
将其反转为:return $('<div>').append(this.clone()).html(); 这只是更中肯的一点。
您应该首先检查outerHTML,然后将其用于支持它的浏览器
这对于像我这样喜欢使用 jQuery 对象以及 .appendTo() 和 .append() 函数在 AJAX 响应中构建 HTML 的人来说非常棒。 .outerHTML 不适用于我在测试中看到的那些实例。其他人可能想检查更多,但我没有时间。
T
Tokimon

我同意 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;
    }
};

这对我来说非常有效。由于 clone()textarea 的错误,我需要一个非克隆解决方案,而这是正确的。
+1 在可用的情况下使用本机 outerHTML,因为除了 Internet Explorer 之外,Chrome 也支持它。
if (!('outerHTML' in $t[0])) alert('该死的,更新你的浏览器');
B
Brian Donovan

要成为真正的 jQuery 风格,您可能希望 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 文档。


这应该添加到 jQuery 核心中,这样人们就不需要考虑它了。我唯一的问题是 wrap()/unwrap() 的性能是否可能比 clone() 更好或更差?
IMSoP:通常,wrap/unwrap 会更快,因为 clone 必须复制元素的所有子元素和属性。 wrap() 只创建一个元素,而 unwrap() 销毁它,所有其他元素都只是移动,大多数时候这是一个相当快速的操作。
T
Tofandel

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

例如:

$('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">'

S
SpYk3HH

要将完整的 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("我的外层HTML是:" + str); });

这将
被替换
At RunTime

打开控制台查看结果


p
pbfy0

你也可以这样做

document.getElementById(id).outerHTML

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


$("#" + id).attr("id") 非常多余。如果变量中已经有 id,为什么要使用 jquery 选择器从 dom 中提取元素,然后查询其 ID 属性?
A
Arpan Dhandhania

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

以下代码为您提供了使 DOM 树保持不变的 outerHTML。

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

希望有人觉得它有用!


只需像@mindplay 在他的评论中建议的那样使用 .clone - 它更容易
A
Abdennour TOUMI
// no cloning necessary    
var x = $('#xxx').wrapAll('<div></div>').parent().html(); 
alert(x);

在这里摆弄:http://jsfiddle.net/ezmilhouse/Mv76a/


M
Mark Schultheiss

如果场景是动态添加新行,则可以使用:

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

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


C
Community

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

也就是说,您还可以 iterate over the attributes of the element 构造它的 HTML 字符串表示。如果 jQuery 添加一个,这似乎就是任何 outerHTML 函数的实现方式。


I
Ivan Chaer

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

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

当然,像这样使用它:

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

D
Darlesson

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

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

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


H
Holly

这对于原生 JavaScript 来说非常简单......

document.querySelector('#selector')

m
mindplay.dk

请注意,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);

编辑:乔希解决方案的另一个问题已解决,请参阅上面的评论。


大多数 jQuery“getter”方法只返回第一个元素的数据,所以匹配这种行为会更有意义。
我想我清楚地说明了为什么它会这样工作?当你有一个元素列表时,它会产生丑陋/复杂的代码 - 如果由于某种原因你只想要第一个元素的标记,只需在选择器中使用 :first 。
当然,就像您可以将 map 与其他人的解决方案一起使用来获取多个元素的 HTML。我所说的是匹配标准 jQuery 方法的行为更加一致。
C
Community

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


P
Petar

我做了这个简单的测试,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))浏览器中的结果是

外层HTML:81 毫秒外层HTML2:439 毫秒

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

我们得到

外层HTML:594 毫秒外层HTML2:332 毫秒

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

$.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)


g
gtournie

这是一个针对 jquery 的非常优化的 outerHTML 插件:(http://jsperf.com/outerhtml-vs-jquery-clone-hack/5 => 其他 2 个快速代码片段与 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 已经给了我们'replaceWith'...

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

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


r
rolacja

短而甜。

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

S
Somnath Muluk

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

$('<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();
};

e
evandrix

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


d
dav1d

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

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

我找到的答案是 jquery remove() 函数实际上将它删除的元素作为对象返回。所以,要删除并重新添加一行,就这么简单......

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

如果您不是要移除对象而是想将其复制到其他位置,请改用 clone() 函数。


S
Sky Yip

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

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

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


R
Rehmat

纯 JavaScript:

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

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

其中“x”是节点号,从 0 开始作为第一个,如果您想获得特定的节点,应该获得您想要的正确节点。如果你有子节点,你真的应该在你想要的那个上放一个 ID,但是,在那个上只是零。使用这种方法并且没有“x”对我来说效果很好。


人们对此投了反对票,愿意发表评论吗?我正在将代码上传到 PARENT,然后获取内容的 HTML - 而不仅仅是在给定元素上执行 .html()。这行得通,我想解释一下为什么行不通。
Z
Zeeshan

简单的解决方案。

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

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

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

这就是你所追求的吗?


Acually 不,因为如果该父母有其他孩子,他也会得到那个 html。
……他说的。我正在寻找元素本身,而不是它及其所有父母的其他孩子。这是怎么得到两个赞成票的???