選択した要素の外部HTMLを取得します


792

選択したオブジェクトのHTMLをjQueryで取得しようとしています。私はその.html()機能を認識しています。問題は、選択されたオブジェクトを含むHTMLが必要なことです(この場合はテーブル行で.html()、行内のセルのみを返します)。

私は周りを検索して、オブジェクトを複製し、新しく作成されたdivに追加するなどの非常に「ハッキー」タイプのメソッドをいくつか見つけましたが、これは本当に汚いようです。より良い方法はありますか、またはjQueryの新しいバージョン(1.4.2)は、あらゆる種類のouterHtml機能を提供しますか?


89
jQueryがそのようなことを行う手段を持たないのは、とんでもないことです。これも必要です。
JosefSábl2010

9
このスレッドを参照して機能リクエストを投稿しましたが、最初の回答は肯定的でした。bugs.jquery.com/ticket/8142
mindplay.dk

11
Ulhas Tuscanoのソリューションを試してから数秒の時間を節約するために、それは機能しません。
Dave

73
ええと、wthが起こっています。$('div')[0].outerHTML
Salman von Abbas

24
@Tuscanは$( "#selectorid")。prop( "outerHTML")を意味しました
男モグラビ2013年

回答:


189

2014編集:質問とこの回答は2010年からのものです。その時点で、より優れたソリューションは広く利用できませんでした。さて、他の返信の多くはより優れています:たとえば、Eric HuやRe Capchaです。

このサイトはあなたのための解決策を持っているようです: jQuery:outerHTML | エロトフ

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

4
私はこれを見ましたが、ハッキングのように見え、より良い方法があったはずであるようにそれを避けようとしていましたが、うまく機能しました。ありがとう。
Ryan

359
$( '[selector]')[0] .outerHTML
drogon

25
@drogon:outerHTMLバージョン11(2012年3月)以降、Firefoxでのみサポートされることに注意してください。
ブレーズ

8
@PavingWays:Firefoxの防御でouterHTMLは、Microsoftが発明した独自の属性であり、W3C標準ではありません。(楽しい事実:innerHTMLHTML5以降でのみ標準化されています
Blaise

3
ピュアjsel.outerHTML || document.createElement('div').appendChild( el.cloneNode( true ) ).parentNode.innerHTML
rab

675

現在(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('');

EDIT基本的なサポートの統計についてelement.outerHTML


14
@SalmanPK FireFoxは、2011-11-11までこのプロパティをサポートしていませんでした。bugzilla.mozilla.org/show_bug.cgi?id=92264多くのユーザーが3.6で立ち往生しています。これは実際には、ネイティブ機能ではなくjQueryを使用することを選択した理由の完璧な例だと思います。
Luciferサム

8
@LuciferSam Firefox 3.6のgs.statcounter.comによると、グローバル市場シェアは最大6%ですが、結果を過去6か月(12月11日から12月5月)にフィルタリングし、米国は上位12のリスト(3以下)から除外しました。 %)。この記事では、FF 3.6の使用量が2012年1月以降に大幅に減少したことを示唆しているため、このウィンドウを選択しました。
Eric Hu

4
これ以上同意できませんでした。これはここでの正しい答えであり、人々が提案している他のものではありません。私が選択した要素には、他の回答によって失われる、保持したい属性があります。地獄、これはIEでも動作します!
Matthew Bonig 2012

いいえ。Firefox11は2012年 3月13日(現在修正済み)までリリースされませんでした。つまり、この記事の執筆時点で1年未満です。jQueryの利点の1つは、古いブラウザーをサポートすることです。少なくとも1年はサポートするのが妥当だと思います。一部のサイトは明らかにサポートを希望しています(jQueryがIE6をサポートしていることを忘れないでください)。
Matthew Flaschen 2013年

7
@EricHu statcounterは、IE8がグローバルブラウザシェアの9.3%を持っているとも述べています。しかし、私のウェブサイトのいくつかは40%のマークに近いです。それはすべて相対的であり、Webサイトごとに大きく異なりますが、Firefox 3.6はまだ私のWebサイトのいくつかで約10%を占めています。グローバル市場シェアは何も意味しません。それはあなたのウェブサイトの聴衆についてすべてです。
ジョージリース2013年

343

そのための関数を生成する必要はありません。次のようにしてください:

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

(ところで、ブラウザのコンソールには、ログに記録されたものが表示されます。2009年頃以降の最新のブラウザのほとんどにこの機能があります。)

魔法は最後にこれです:

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

クローンは、実際にDOMを妨害していないことを意味します。それなしで実行すると、p(この例では)すべてのハイパーリンクの前後にタグが挿入されますが、これは望ましくありません。したがって、はい、使用します.clone()

それが機能する方法は、各aタグをp取得し、RAMにそのタグのクローンを作成し、タグでラップし、その親(pタグを意味する)を取得してから、そのinnerHTMLプロパティを取得することです。

編集:入力が少なく、同じように機能するため、アドバイスを取り、divタグをpタグに変更しました。


82
jQueryチームがouterHtml()メソッドを追加しないのはなぜですか?
ドニーV

1
@デレク、それは重要ではないだろう。内部に何かを入れるために、DIVをラッパーとして使用しています。
Volomike 2012年

11
.clone()。wrap( '<p>')。parent()。html(); 短い
UğurGümüşhan

1
はい、キーストロークが少なく、同じ効果が得られます。
Volomike

14
一般的な解決策としては、Pの代わりにDIVを使用する方が良いです。すべての要素を有効なHTMLとしてPでラップできるわけではありません。
Blazemonger 2013年

149

何について:prop('outerHTML')

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

そして設定するには:

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

それは私のために働いた。

PS:これはjQuery 1.6で追加されました。


4
他の回答と比較して非常にきちんとした小さなコード。Q:他の回答に記載されているものと同じouterHTML制限がありますか?FF <11で機能しますか?
MacroMan、2014年

3
これはうまく機能します。これは、ここでの最良の解決策になる可能性があります。ブラウザに関する限り、これはouterHTLMと同じくらい互換性があるはずです。prop()メソッドは、基本的にはouterHTMLプロパティを取得するだけです。
トムトム

2
このソリューションの方が優れていますが、Jquery 1.6.1が2011年にリリースされました。質問(および私の回答)は2010
David V.

1
私にとっては「$( '[selector]')[0] .outerHTML;」いずれの場合も機能しませんでしたが、「$( '#item-to-be-selected')。prop( 'outerHTML');」はい!
Eduardo Lucio

2
$( '#item-to-be-selected')。attr( 'outerHTML'); // **以前のjQueryの場合
Meetai.com

91

jQueryを拡張します。

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

次のように使用します。 $("#myTableRow").outerHTML();


8
このソリューションの小さな問題:wrap()の前にclone()を実行する必要があります。そうしないと、余分な<div>がドキュメントに残ります。
mindplay.dk

1
おかげで、mindplay.dk-私はあなたの提案を組み込むためにコードを編集しました。:)
ジェシカ

2
それを逆転することについてはどうですか:return $('<div>').append(this.clone()).html();それは、もう少し要点です。
Justin Warkentin 2013

2
最初にouterHTMLをチェックし、それをサポートするブラウザーでそれを使用する必要があります
James Westgate

これは、jQueryオブジェクト、および.appendTo()関数と.append()関数を使用して、AJAX応答でHTMLを構築したい私のような人々に最適です。.outerHTMLは、テストで確認したもののインスタンスでは機能しません。他の誰かがそれをもっとチェックしたいと思うかもしれませんが、私には時間がありません。
Sean Kendle、2015

43

私はArpanに同意します(Dec 13 '10 5:59)。

クローンを使用しないので、彼のやり方は実際にははるかに良い方法です。子要素がある場合、cloneメソッドは非常に時間がかかり、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;
    }
};

2
これは完璧に機能しました。clone()and textareaのバグのため、非クローンソリューションが必要でしたが、これは問題ありませんでした。
Shpigford、2011

5
outerHTMLInternet Explorerに加えてChromeでもサポートされているため、可能な場合はネイティブを使用するための+1 。
アンディE

9
if(!( 'outerHTML' in $ t [0]))alert( 'おっと、ブラウザを更新してください');
psycho brm

19

本当にjQuery-esque outerHTML()になるには、ゲッターセッターになり、その振る舞い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の代わりに設定されます。

詳細については、jQueryのドキュメントを参照してくださいhtml()


これをjQueryコアに追加して、人々がそれについて考える必要がないようにする必要があります。私の唯一の質問は、wrap()/ unwrap()がclone()よりもパフォーマンスが良いか悪いか、ということです。
IMSoP 2013年

1
IMSoP:一般に、クローンは要素のすべての子要素と属性をコピーする必要があるため、ラップ/アンラップの方が高速です。wrap()は1つの要素のみを作成し、unwrap()はそれを破棄します。他のすべての要素は移動されるだけで、ほとんどの場合かなり高速な操作です。
アンディE

16

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

11

完全な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);

これにより、1つの要素のouterHTMLを取得できるだけでなく、一度に複数の要素の配列を返すこともできます。両方の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();

スニペットの例:


9

このようにすることもできます

document.getElementById(id).outerHTML

idは、探している要素のidです。


4
$("#" + id).attr("id")信じられないほど冗長です。変数にすでにidがある場合、jqueryセレクターを使用してdomから要素をプルアップし、そのID属性をクエリするのはなぜですか?
Sam Dufel

7

Jessicaのソリューション(Joshが編集したもの)を使用して、outerHTMLをFirefoxで動作させました。しかし問題は、彼女のソリューションが要素をDIVにラップしたため、コードが壊れていたことです。コードを1行追加すると、その問題は解決しました。

次のコードは、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();

誰かがそれが便利だと思うことを願っています!


1
コメントで@mindplayが提案するように.cloneを使用するだけです
Yarin


4

シナリオが新しい行を動的に追加する場合は、これを使用できます。

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

.myrowのクラス名です<tr>。最後の行のコピーを作成し、それを新しい最後の行として挿入します。これはまたで働くIE7ながら、[0].outerHTMLこの方法は、内の割り当てを許可しないIE7を


3

node.cloneNode()はハックのようには見えません。ノードを複製して任意の親要素に追加し、個々のプロパティを操作して操作することもできます。たとえば、ノードで正規表現を実行したり、DOMに追加したり、あとで操作したりする必要はありません。

つまり、要素の属性を反復処理して、その要素のHTML文字列表現を構築することもできます。これは、おそらく外部HTML関数がどのように実装されるかであり、jQueryで追加されるようです。


3

私はジェシカによって更新されたVolomikeのソリューションを使用しました。要素が存在するかどうかを確認するチェックを追加し、存在しない場合は空白を返すようにしました。

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

もちろん、次のように使用します。

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

3

あなたはここで良い.outerHTML()オプションを見つけることができますhttps://github.com/darlesson/jquery-outerhtml

要素のHTMLコンテンツのみを返す.html()とは異なり、このバージョンの.outerHTML()は、選択された要素とそのHTMLコンテンツを返すか、それを.replaceWith()メソッドとして置き換えますが、置換するHTMLを継承できるようにする違いがあります。連鎖。

上記のURLでも例を確認できます。


2

ジョシュのソリューションは単一の要素に対してのみ機能することに注意してください。

間違いなく、「外部」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のソリューションで修正された別の問題。上記のコメントを参照してください。


1
ほとんどのjQuery "getter"メソッドは最初の要素のデータのみを返すため、この動作に一致させる方が理にかなっています。
アンディE

なぜこのように機能するのかを明確に述べたと思いますか?要素のリストがある場合、醜い/複雑なコードになります-何らかの理由で最初の要素のみのマークアップが必要な場合は、セレクターで:firstを使用します。
mindplay.dk 2011

もちろん、他のすべての人のソリューションでマップを使用して、複数の要素のHTMLを取得するのと同じです。私が言っていたのは、標準のjQueryメソッドの動作と一致させるほうが一貫しているということです。
アンディE


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");

そして私のクロム(バージョン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(); 
}

したがって、cloneメソッドは実際にはwrap / unwrapメソッドよりも高速です
(jquery 1.7.2)


2

ここで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にはゲッターとセッターは必要ありません。jQueryはすでに 'replaceWith'を提供しています...

@mindplay =>なぜすべてのouterHTMLに参加するのですか?jquery.htmlは、FIRST要素のHTMLコンテンツのみを返します。

(申し訳ありませんが、コメントを書くのに十分な評判がありません)


2

短くて甘い。

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

2

これはバニラJavaScriptで非常に簡単です...

document.querySelector('#selector')

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


0

テーブル行を削除し、それをテーブルの下部に追加しようとしていたという私の問題に対する回答を探しているときにこれに遭遇しました(データ行を動的に作成していたが、「新規追加」を表示したかったため下部にある「レコード」タイプの行)。

同じ問題がありました。これはinnerHtmlを返すため、その行のIDを保持し、手順を繰り返すことが不可能であることを意味するTRタグが欠落していたことです。

私が見つけた答えは、jquery remove()関数が実際に削除する要素をオブジェクトとして返すというものでした。したがって、行を削除して再度追加するには、次のように簡単です...

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

オブジェクトを削除するのではなく、別の場所にコピーする場合は、clone()代わりに関数を使用します。


0

要素全体のHTMLを直接取得するための省略形としてのjQueryプラグイン:

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

次のように使用します。 $(".element").outerHTML();


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

「x」はノード番号で、最初のノードを0として、特定のノードを取得しようとする場合は、必要な正しいノードを取得する必要があります。子ノードがある場合は、実際に必要なIDにIDを設定して、そのIDをゼロにする必要があります。その方法論を使用して、「x」はうまく機能しませんでした。


1
これに投票する人は、コメントを残してくれませんか?私はコードをPARENTまで上げて、コンテンツのHTMLを取得しています.html()。これは機能し、なぜ機能しないのか説明をお願いします。
vapcguy 2015


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

多分私はあなたの質問を正しく理解していませんが、これは選択された要素の親要素のhtmlを取得します。

それはあなたが求めているものですか?


25
その親が他の子を持っている場合、彼はそのhtmlも取得するため、実際にはありません。
デビッドV.

1
...彼が言ったこと。私は要素自体を探しています。それとそのすべての親の他の子ではありません。これはどうやって2票を獲得したのですか???
Ryan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.