关于jquery:获取所选元素的外部HTML

Get selected element's outer HTML

我正在尝试用jquery获取所选对象的HTML。我知道.html()函数;问题是我需要包含所选对象的HTML(在本例中是表行,其中.html()只返回行中的单元格)。

我四处搜索,发现了一些非常"黑客"类型的方法,比如克隆一个对象,将其添加到一个新创建的DIV等等,但这看起来确实很糟糕。有没有更好的方法,或者jquery(1.4.2)的新版本提供了任何类型的outerHtml功能?


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 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的基本支持统计

  • 火狐(Gecko):11….2012-03-13发布
  • 铬:0.2………..2008-09-02发布
  • Internet Explorer 4.0…1997年发布
  • 歌剧7…………………2003-01-28发行
  • Safari 1.3………发布日期:2006-01-12


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

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

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

最神奇的是这一点:

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

克隆意味着您实际上没有干扰DOM。不使用它运行它,您将看到在所有超链接之前/之后插入的p标记(在本例中),这是不可取的。所以,是的,使用.clone()

它的工作方式是:取每个a标记,在RAM中克隆它,用p标记包装,得到它的父级(即p标记),然后得到它的innerHTML属性。

编辑:听取建议,将div标记改为p标记,因为它的输入量较小,工作原理相同。


2014年编辑:问题和本回复来自2010年。当时,没有更好的解决方案被广泛采用。现在,许多其他的回答都比较好:例如,胡耀威的,或者雷卡查的。

此网站似乎为您提供了解决方案:jquery:outerhtml_yelotofu

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


那:prop('outerHTML')呢?

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

并设置:

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

这对我很有用。

附言:这是在jquery 1.6中添加的。


扩展jQuery:

1
2
3
4
5
(function($) {
  $.fn.outerHTML = function() {
    return $(this).clone().wrap('').parent().html();
  };
})(jQuery);

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


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

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

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

1
2
3
4
5
6
7
8
9
10
$.fn.outerHTML = function() {
    var $t = $(this);
    if ($t[0].outerHTML !== undefined) {
        return $t[0].outerHTML;
    } else {
        var content = $t.wrap('').parent().html();
        $t.unwrap();
        return content;
    }
};


为了真正的jquery风格,您可能希望outerHTML()成为getter和setter,并且其行为尽可能类似于html()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$.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('').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('').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;
}

Working demo: http://jsfiddle.net/AndyE/WLKAa/

这使我们可以向outerHTML传递一个论点,它可以

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

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


也可以使用get(检索jquery对象匹配的dom元素)。

例如:

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

作为扩展方法:

1
2
3
4
5
jQuery.fn.outerHTML = function () {
  return this.get().map(function (v) {
    return v.outerHTML
  }).join()
};

1
2
3
4
5
jQuery.fn.outerHTML = function () {
  return $.map(this.get(), function (v) {
    return v.outerHTML
  }).join()
};

多选并返回所有匹配元素的外部HTML。

1
$('input').outerHTML()

返回:

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

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

update New version has better control as well as a more jQuery Selector friendly service! :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
;(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,而且还可以同时获得多个元素的数组返回!并且可以在jquery标准样式中使用,例如:

1
2
3
4
5
6
7
$.outerHTML($("#eleID")); // will return outerHTML of that element and is
// same as
$("#eleID").outerHTML();
// or
$.outerHTML("#eleID");
// or
$.outerHTML(document.getElementById("eleID"));

对于多个元素

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

代码段示例:

1
2
3
4
5
6
7
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); });
1
2
3
4
5
6
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
<script src="https://rawgit.com/JDMcKinstry/ce699e82c7e07d02bae82e642fb4275f/raw/deabd0663adf0d12f389ddc03786468af4033ad2/jQuery.outerHTML.js">
This will
be Replaced
At RunTime
<tag>Open Console to see results</tag>


你也可以这样做

1
document.getElementById(id).outerHTML

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


我用杰西卡的解决方案(由乔希编辑)让OuterHTML在Firefox上工作。但问题是,我的代码被破坏了,因为她的解决方案将元素包装成一个分区,再添加一行代码就解决了这个问题。

下面的代码给出了outerhtml,使DOM树保持不变。

1
2
3
4
5
6
7
8
9
10
$jq.fn.outerHTML = function() {
    if ($jq(this).attr('outerHTML'))
        return $jq(this).attr('outerHTML');
    else
    {
    var content = $jq(this).wrap('').parent().html();
        $jq(this).unwrap();
        return content;
    }
}

像这样使用:$("myDiv").outerhtml();

希望有人发现它有用!


1
2
3
// no cloning necessary    
var x = $('#xxx').wrapAll('').parent().html();
alert(x);

小提琴:http://jsfiddle.net/ezmilhouse/mv76a/


如果场景正在动态附加新行,则可以使用此选项:

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

.myrow

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


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

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

当然,可以这样使用:

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


我做了一个简单的测试,outerhtml是tokimon解决方案(没有克隆),outerhtml是jessica解决方案(克隆)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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))的结果是

OUTHTML: 81MS外部TML2:439ms

但是,如果我们使用没有本地outerhtml功能的tokimon解决方案(现在几乎每个浏览器都支持这个功能)

我们得到

外部TML:594ms外部TML2:332毫秒

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

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

所以clone方法实际上比wrap/unwrap方法更快(jQuery 1.7.2)


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


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

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

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

1
2
3
4
5
6
7
8
(function($) {
  $.fn.outerHTML = function() {
    var $this = $(this);
    if ($this.length>1)
      return $.map($this, function(el){ return $(el).outerHTML(); }).join('');
    return $this.clone().wrap('').parent().html();
  }
})(jQuery);

编辑:另一个问题与乔希的解决方案修复,见评论以上。


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

也就是说,您还可以迭代元素的属性来构造它的HTML字符串表示。如果jquery添加一个outerhtml函数,很可能就是这样实现的。


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

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

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


这对于普通的javascript来说非常简单…

1
document.querySelector('#selector')

这对于更改DOM上的元素非常有用,但在将HTML字符串传递到jquery时不适用于IE,如下所示:

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

在一些操作之后,我创建了一个函数,允许上面的函数在IE中用于HTML字符串:

10


以下是jquery的一个非常优化的outerhtml插件:(http://jspef.com/outerhtml-vs-jquery-clone-hack/5=>另外两个快速代码段与某些浏览器(如ff<11)不兼容)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(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);

@安迪,我不同意你的看法。outerhmtl不需要getter和setter:jquery已经给了我们"replaceWith"…

@Mindplay=>你为什么要加入所有OuterHTML?jquery.html只返回第一个元素的html内容。

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


又矮又甜。

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

或在箭头功能的帮助下,活动更甜蜜

10

或者根本没有jquery

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

或者如果你不喜欢这种方法,检查一下

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

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


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

我也有同样的问题,因为它返回了innerhtml,所以缺少了tr标签,它保存了该行的ID,意味着不可能重复该过程。

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

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

如果不删除对象,但希望将其复制到其他地方,请使用clone()函数。


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

其中"x"是节点号,以0开头作为第一个节点,如果您试图获得特定的节点,则应该获得所需的正确节点。如果您有子节点,那么您应该在所需的节点上放置一个ID,使其仅为零。使用这种方法,没有"x"对我来说很好。


简单的解决方案。

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

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

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

这就是你想要的吗?