J'essaie d'obtenir le code HTML d'un objet sélectionné avec jQuery. Je connais la fonction .html()
; le problème est que j'ai besoin du HTML, y compris de l'objet sélectionné (une ligne de tableau dans ce cas, où .html()
ne renvoie que les cellules à l'intérieur de la ligne).
J’ai cherché et trouvé quelques méthodes très "hackish" pour cloner un objet, l’ajouter à un div nouvellement créé, etc., etc., mais cela semble vraiment sale. Existe-t-il un meilleur moyen ou la nouvelle version de jQuery (1.4.2) offre-t-elle une fonctionnalité de type outerHtml
?
2014 Edit: La question et cette réponse datent de 2010. À l'époque, aucune meilleure solution n'était largement disponible. Maintenant, beaucoup d'autres réponses sont meilleures: Eric Hu, ou Re Capcha, par exemple.
Ce site semble avoir une solution pour vous: jQuery: outerHTML | Yelotofu
jQuery.fn.outerHTML = function(s) {
return s
? this.before(s).remove()
: jQuery("<p>").append(this.eq(0).clone()).html();
};
Je crois qu'actuellement (5/1/2012), tous les principaux navigateurs supportent la fonction outerHTML. Il me semble que cet extrait est suffisant. Personnellement, je choisirais de mémoriser ceci:
// 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: Statistiques de support de base pour element.outerHTML
Pas besoin de générer une fonction pour cela. Fais-le comme ça:
$('a').each(function(){
var s = $(this).clone().wrap('<p>').parent().html();
console.log(s);
});
(La console de votre navigateur indiquera ce qui est journalisé, soit dit en passant. La plupart des navigateurs les plus récents depuis 2009 ont cette fonctionnalité.)
La magie est la suivante:
.clone().wrap('<p>').parent().html();
Le clone signifie que vous ne dérangez pas réellement le DOM. Exécutez-le sans cela et vous verrez les balises p
insérées avant/après tous les hyperliens (dans cet exemple), ce qui n'est pas souhaitable. Donc, oui, utilisez .clone()
.
Cela fonctionne de la manière suivante: il prend chaque balise a
, en crée un clone dans la RAM, le recouvre de balises p
, en obtient le parent (signifiant la balise p
), puis la propriété innerHTML
.
EDIT: pris conseil et changé les balises div
en p
parce que c’est moins typé et qui fonctionne de la même manière.
Qu'en est-il de: prop('outerHTML')
?
var outerHTML_text = $('#item-to-be-selected').prop('outerHTML');
Et pour régler:
$('#item-to-be-selected').prop('outerHTML', outerHTML_text);
Cela a fonctionné pour moi.
PS: Ceci est ajouté dans jQuery 1.6 .
Étendre jQuery:
(function($) {
$.fn.outerHTML = function() {
return $(this).clone().wrap('<div></div>').parent().html();
};
})(jQuery);
Et utilisez-le comme ceci: $("#myTableRow").outerHTML();
Je suis d'accord avec Arpan (déc 13 '10 5:59).
Sa façon de le faire est en fait une bien meilleure façon de le faire, car vous n’utilisez pas de clone. La méthode de clonage prend beaucoup de temps, si vous avez des éléments enfants et que personne d'autre ne semble s'inquiéter du fait que IE a réellement l'attribut outerHTML
(oui, oui IE a QUELQUES astuces utiles).
Mais je créerais probablement son script un peu différent:
$.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;
}
};
Pour être vraiment jQuery-esque, vous voudrez peut-être que outerHTML()
soit un getter and _ et un comportement aussi semblable que possible à 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;
}
Démo de travail: http://jsfiddle.net/AndyE/WLKAa/
Cela nous permet de passer un argument à outerHTML
, qui peut être
function (index, oldOuterHTML) { }
- où la valeur de retour deviendra le nouveau code HTML de l'élément (sauf si false
est renvoyé).Pour plus d'informations, voir la documentation jQuery pour html()
.
Vous pouvez également utiliser get (Récupérer les éléments DOM mis en correspondance par l’objet jQuery.).
par exemple:
$('div').get(0).outerHTML;//return "<div></div>"
Comme méthode d'extension:
jQuery.fn.outerHTML = function () {
return this.get().map(function (v) {
return v.outerHTML
}).join()
};
Ou
jQuery.fn.outerHTML = function () {
return $.map(this.get(), function (v) {
return v.outerHTML
}).join()
};
Choix multiple et retourne le code HTML externe de tous les éléments correspondants.
$('input').outerHTML()
revenir:
'<input id="input1" type="text"><input id="input2" type="text">'
Pour créer un plugin jQuery COMPLET en .outerHTML
, ajoutez le script suivant à tout fichier js et incluez après jQuery dans votre en-tête:
mettre à jour La nouvelle version offre un meilleur contrôle ainsi qu'un service plus convivial pour 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);
Cela vous permettra non seulement d’obtenir la couche HTML externe d’un élément, mais également d’obtenir un retour Array de plusieurs éléments à la fois! et peut être utilisé dans les deux styles standard jQuery en tant que tel:
$.outerHTML($("#eleID")); // will return outerHTML of that element and is
// same as
$("#eleID").outerHTML();
// or
$.outerHTML("#eleID");
// or
$.outerHTML(document.getElementById("eleID"));
Pour plusieurs éléments
$("#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>
vous pouvez aussi le faire de cette façon
document.getElementById(id).outerHTML
où id est l'identifiant de l'élément que vous recherchez
J'ai utilisé la solution de Jessica (qui a été éditée par Josh) pour que outerHTML fonctionne avec Firefox. Le problème cependant, c'est que mon code était en train de s'effriter car sa solution englobait l'élément dans une DIV. L'ajout d'une ligne de code supplémentaire a résolu ce problème.
Le code suivant vous donne le fichier outerHTML en laissant l’arborescence DOM inchangée.
$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;
}
}
Et utilisez-le comme ceci: $ ("# myDiv"). OuterHTML ();
J'espère que quelqu'un le trouvera utile!
// no cloning necessary
var x = $('#xxx').wrapAll('<div></div>').parent().html();
alert(x);
Violon ici: http://jsfiddle.net/ezmilhouse/Mv76a/
Si le scénario ajoute une nouvelle ligne de manière dynamique, vous pouvez utiliser ceci:
var row = $(".myRow").last().clone();
$(".myRow").last().after(row);
.myrow
est le nom de classe du <tr>
. Il crée une copie de la dernière ligne et l'insère en tant que nouvelle dernière ligne . Cela fonctionne également dans IE7 , alors que la méthode [0].outerHTML
n'autorise pas les affectations dans ie7
Vous pouvez trouver une bonne option .outerHTML () ici https://github.com/darlesson/jquery-outerhtml .
Contrairement à .html () qui renvoie uniquement le contenu HTML de l'élément, cette version de .outerHTML () renvoie l'élément sélectionné et son contenu HTML ou le remplace en tant que méthode .replaceWith (), mais à la différence qui permet au code HTML de remplacement d'hériter le chaînage.
Des exemples peuvent également être vus dans l'URL ci-dessus.
Une autre solution similaire avec l'ajout de remove()
de l'objet DOM temporaire.
J'ai utilisé la solution de Volomike mise à jour par Jessica. Je viens juste d'ajouter une vérification pour voir si l'élément existe et l'a renvoyé en blanc au cas où il ne l'aurait pas.
jQuery.fn.outerHTML = function() {
return $(this).length > 0 ? $(this).clone().wrap('<div />').parent().html() : '';
};
Bien sûr, utilisez-le comme:
$('table#buttons').outerHTML();
J'ai fait ce test simple avec outerHTML étant la solution tokimon (sans clone), et outerHTML2 étant la solution Jessica (clone)
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");
et le résultat dans mon navigateur chrome (version 20.0.1132.57 (0)) était
outerHTML: 81ms
outerHTML2: 439ms
mais si nous utilisons la solution tokimon sans la fonction native outerHTML (qui est maintenant prise en charge dans presque tous les navigateurs)
on a
outerHTML: 594ms
outerHTML2: 332ms
et il y aura plus de boucles et d'éléments dans des exemples réels, de sorte que la combinaison parfaite serait
$.fn.outerHTML = function()
{
$t = $(this);
if( "outerHTML" in $t[0] ) return $t[0].outerHTML;
else return $t.clone().wrap('<p>').parent().html();
}
alors la méthode de clonage est en réalité plus rapide que la méthode de bouclage/déroulage
(jquery 1.7.2)
Voici un plugin outerHTML très optimisé pour jQuery: ( http://jsperf.com/outerhtml-vs-jquery-clone-hack/5 > les 2 autres extraits de code rapides ne sont pas compatibles avec certains des navigateurs comme 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 => Je ne suis pas d'accord avec toi. outerHMTL n'a pas besoin de getter ET de setter: jQuery nous donne déjà 'replaceWith' ...
@mindplay => Pourquoi rejoignez-vous tous les outerHTML? jquery.html renvoie uniquement le contenu HTML de l'élément FIRST.
(Désolé, je n'ai pas assez de réputation pour écrire des commentaires)
Notez que la solution de Josh ne fonctionne que pour un seul élément.
On peut soutenir que le code HTML "externe" n'a de sens que si vous avez un seul élément, mais il existe des situations où il est judicieux de transformer une liste d'éléments HTML en un balisage.
En prolongeant la solution de Josh, celle-ci gérera plusieurs éléments:
(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);
Edit: un autre problème avec la solution de Josh résolu, voir le commentaire ci-dessus.
node.cloneNode () ne semble guère être un hack. Vous pouvez cloner le nœud et l'ajouter à n'importe quel élément parent souhaité, mais aussi le manipuler en manipulant des propriétés individuelles, plutôt que d'avoir à le faire, par exemple. exécuter des expressions régulières sur celui-ci, ou l'ajouter dans le DOM, puis le manipuler après les mots.
Cela dit, vous pouvez également parcourir les attributs de l'élément pour en construire une représentation sous forme de chaîne HTML. Il semble probable que c'est de cette manière que n'importe quelle fonction outerHTML serait implémentée si jQuery en ajoutait une.
C'est très bien pour changer les éléments sur le dom mais ne fonctionne PAS pour, par exemple, quand on passe une chaîne html dans jquery comme ceci:
$('<div id="foo">Some <span id="blog">content</span></div>').find('#blog').outerHTML();
Après quelques manipulations, j'ai créé une fonction qui permet à ce qui précède de fonctionner, par exemple pour les chaînes html:
$.fn.htmlStringOuterHTML = function() {
this.parent().find(this).wrap('<div/>');
return this.parent().html();
};
Court et doux.
[].reduce($('.x'), function(i,v) {return i+v.outerHTML}, '')
ou événement plus doux avec l'aide des fonctions de flèche
[].reduce.call($('.x'), (i,v) => i+v.outerHTML, '')
ou sans jQuery du tout
[].reduce.call(document.querySelectorAll('.x'), (i,v) => i+v.outerHTML, '')
ou si vous n'aimez pas cette approche, vérifiez que
$('.x').get().reduce((i,v) => i+v.outerHTML, '')
C'est assez simple avec JavaScript vanille ...
document.querySelector('#selector')
le plugin jQuery est un raccourci pour obtenir directement l'élément HTML entier:
jQuery.fn.outerHTML = function () {
return jQuery('<div />').append(this.eq(0).clone()).html();
};
Et utilisez-le comme ceci: $(".element").outerHTML();
Je suis tombé sur cette question en cherchant une réponse à mon problème: j'essayais de supprimer une ligne de table, puis de la rajouter au bas de la table (car je créais de manière dynamique des lignes de données, mais je voulais afficher un message 'Add New Enregistrer le type de ligne en bas).
J'ai eu le même problème, en ce sens qu'il renvoyait le innerHtml et qu'il manquait les balises TR, qui contenaient l'ID de cette ligne et signifiait qu'il était impossible de répéter la procédure.
La réponse que j’ai trouvée est que la fonction jquery remove()
renvoie en fait l’élément qu’elle supprime en tant qu’objet. Donc, pour supprimer et rajouter une ligne, c'était aussi simple que cela ...
var a = $("#trRowToRemove").remove();
$('#tblMyTable').append(a);
Si vous ne supprimez pas l'objet mais souhaitez le copier ailleurs, utilisez plutôt la fonction clone()
.