Ottieni l'HTML esterno dell'elemento selezionato


792

Sto cercando di ottenere l'HTML di un oggetto selezionato con jQuery. Sono a conoscenza del.html() funzione; il problema è che ho bisogno dell'HTML incluso l'oggetto selezionato (una riga di tabella in questo caso, dove .html()restituisce solo le celle all'interno della riga).

Ho cercato in giro e ho trovato alcuni metodi di tipo molto "hacker" per clonare un oggetto, aggiungendolo a un div appena creato, ecc., Ecc., Ma questo sembra davvero sporco. Esiste un modo migliore o la nuova versione di jQuery (1.4.2) offre qualche tipo di outerHtmlfunzionalità?


89
È scandaloso che jQuery non abbia i mezzi per fare una cosa del genere. Ne ho bisogno anch'io.
Josef Sábl,

9
Ho pubblicato una richiesta di funzionalità, con riferimento a questa discussione, e la risposta iniziale è stata positiva. bugs.jquery.com/ticket/8142
mindplay.dk

11
Per salvare alcune persone alcuni secondi del loro tempo dal provare la soluzione di Ulhas Tuscano, non funziona.
Dave,

73
Uh, sta succedendo. $('div')[0].outerHTML.
Salman von Abbas,

24
@Tuscan significa $ ("# selectorid"). Prop ("outerHTML")
guy mograbi

Risposte:


189

Modifica 2014: la domanda e questa risposta risalgono al 2010. All'epoca non era ampiamente disponibile una soluzione migliore. Ora, molte altre risposte sono migliori: per esempio Eric Hu o Re Capcha.

Questo sito sembra avere una soluzione per te: jQuery: outerHTML | Yelotofu

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

4
L'ho visto ma stavo cercando di evitarlo perché sembrava hackerare e come se ci fosse stato un modo migliore, ma funziona bene. Grazie.
Ryan

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

25
@drogon: tenere presente che outerHTMLè supportato in Firefox solo dalla versione 11 (marzo 2012).
Blaise,

8
@PavingWays: a difesa di Firefox: outerHTMLè un attributo proprietario inventato da Microsoft, non uno standard W3C. (Curiosità: innerHTMLè standardizzato solo da HTML5 )
Blaise,

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

675

Credo che attualmente (5/1/2012), tutti i principali browser supportino la funzione outerHTML. Mi sembra che questo frammento sia sufficiente. Personalmente sceglierei di memorizzare questo:

// 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 : statistiche di supporto di base perelement.outerHTML


14
@SalmanPK FireFox non supportava questa proprietà fino all'11-11-2011. bugzilla.mozilla.org/show_bug.cgi?id=92264 Ci sono ancora molti utenti bloccati su 3.6. Penso che questo sia in realtà un esempio perfetto del motivo per cui si dovrebbe scegliere di utilizzare jQuery rispetto alla funzionalità nativa.
Lucifer Sam,

8
@LuciferSam Firefox 3.6 detiene una quota di mercato globale del 6% circa secondo gs.statcounter.com Tuttavia, filtrando i risultati negli ultimi 6 mesi (dicembre '11-maggio '12) e negli Stati Uniti lo spinge dalla loro lista dei 12 principali (sotto 3 %). Ho scelto questa finestra poiché questo articolo suggerisce che l'utilizzo di FF 3.6 è diminuito in modo significativo dopo gennaio 2012. Dato questi dati, sostengo la mia soluzione per un codice più semplice rispetto alla compatibilità con le versioni precedenti.
Eric Hu,

4
Non potrei essere più d'accordo. Questa è la risposta giusta qui, non le altre cose che la gente sta suggerendo. L'elemento su cui seleziono ha degli attributi che voglio mantenere che sono persi dalle altre risposte. Cavolo, funziona anche in IE!
Matthew Bonig,

No. Firefox 11 non è stato rilasciato fino al 13 marzo 2012 (risolto ora), ovvero meno di un anno fa al momento della stesura di questo documento. Uno dei vantaggi di jQuery è che supporta i browser più vecchi. Penso che supportare almeno un anno sia ragionevole, e alcuni siti ne vorranno ovviamente di più (ricordate, jQuery supporta IE6).
Matthew Flaschen,

7
@EricHu statcounter afferma inoltre che IE8 ha il 9,3% della condivisione browser globale. Eppure alcuni dei miei siti Web sono vicini al 40%. È tutto relativo e varia enormemente da sito Web a sito Web, Firefox 3.6 rappresenta ancora circa il 10% su alcuni dei miei siti Web. La quota di mercato globale non significa nulla. Riguarda il pubblico del tuo sito web.
George Reith,

343

Non è necessario generare una funzione per esso. Fallo così:

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

(A proposito, la console del tuo browser mostrerà ciò che è registrato. La maggior parte dei browser più recenti dal 2009 ha questa funzione.)

La magia è questa alla fine:

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

Il clone significa che non stai effettivamente disturbando il DOM. Eseguilo senza di esso e vedrai i ptag inseriti prima / dopo tutti i collegamenti ipertestuali (in questo esempio), il che è indesiderabile. Quindi sì, usa .clone().

Il modo in cui funziona è che prende ciascuno a tag, ne fa un clone nella RAM, si avvolge con i ptag, ne ottiene il genitore (che significa il ptag) e quindi ne ottiene la innerHTMLproprietà.

EDIT : ha preso consigli e ha cambiato i divtag in ptag perché è meno digitazione e funziona allo stesso modo.


82
Mi chiedo perché il team di jQuery non aggiunga un metodo outerHtml ()?
Donny V.

1
@Derek, non avrebbe importanza. Sto usando DIV come un wrapper per ottenere qualcosa al suo interno.
Volomike,

11
.clone () involucro ( '<p>') genitore () html ()...; è più corto
Uğur Gümüşhan

1
Sì, meno sequenze di tasti e ottiene lo stesso effetto.
Volomike

14
Meglio usare DIV invece di P per una soluzione generale - non tutti gli elementi possono essere racchiusi in P come HTML valido.
Blazemonger

149

Che dire di prop('outerHTML'):?

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

E per impostare:

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

Ha funzionato per me.

PS : è stato aggiunto in jQuery 1.6 .


4
Codice molto pulito e piccolo rispetto alle altre risposte. D: Questo ha le stesse restrizioni esterne HTML indicate nelle altre risposte? Funziona con FF <11?
MacroMan

3
Funziona bene, questa potrebbe essere la migliore soluzione qui. Per quanto riguarda i browser, questo dovrebbe essere compatibile come outerHTLM. Il metodo prop () in pratica sta semplicemente ottenendo la proprietà outerHTML.
Tom Tom,

2
Questa soluzione è migliore, tuttavia Jquery 1.6.1 è stato rilasciato nel 2011. La domanda (e la mia risposta) è del 2010.
David V.

1
Per me "$ ('[selettore]') [0] .outerHTML;" non ha funzionato in ogni caso, ma "$ ('# item-to-be-selezionata'). prop ('outerHTML');" sì!
Eduardo Lucio,

2
. $ ( '# elemento-to-be-selezionato') attr ( 'outerHTML'); // ** Per precedenti jQuery
Meetai.com

91

Estendi jQuery:

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

E usalo in questo modo: $("#myTableRow").outerHTML();


8
Piccolo problema con questa soluzione: è necessario clonare () prima di avvolgere (), altrimenti si sta lasciando il wrapping aggiuntivo <div> nel documento.
mindplay.dk,

1
Grazie, mindplay.dk - Ho modificato il codice per incorporare il tuo suggerimento ... buona cattura. :)
jessica,

2
Che ne dite di invertire ciò: return $('<div>').append(this.clone()).html();è solo un po 'più preciso.
Justin Warkentin,

2
Dovresti prima cercare il codice HTML esterno e utilizzarlo solo per i browser che lo supportano
James Westgate,

Questo è ottimo per le persone come me a cui piace costruire HTML nelle risposte AJAX usando gli oggetti jQuery e le funzioni .appendTo () e .append (). .outerHTML non funziona per quelle istanze da quello che ho visto nei miei test. Qualcun altro potrebbe voler controllare di più, ma non ho tempo.
Sean Kendle,

43

Concordo con Arpan (13 dicembre 10 5:59).

Il suo modo di farlo è in realtà un modo MOLTO migliore di farlo, poiché non usi il clone. Il metodo clone richiede molto tempo, se si hanno elementi figlio e a nessun altro sembra importare che IE abbia effettivamente ilouterHTML attributo (sì IE ha effettivamente ALCUNI utili trucchi nella manica).

Ma probabilmente creerei la sua sceneggiatura un po 'diversa:

$.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
Ha funzionato perfettamente per me. A causa di un bug con clone()e textarea, avevo bisogno di una soluzione non clone, e questo era perfetto.
Shpigford,

5
+1 per l'utilizzo nativo outerHTMLove disponibile, poiché supportato da Chrome oltre a Internet Explorer.
Andy E

9
if (! ('outerHTML' in $ t [0])) alert ('god dammit, aggiorna il tuo browser');
psicopatico,

19

Per essere veramente jQuery, potresti voler outerHTML()essere un getter e un setter e avere un comportamento il più simile html()possibile:

$.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;
}

Demo funzionante: http://jsfiddle.net/AndyE/WLKAa/

Questo ci consente di passare un argomento a outerHTML, che può essere

  • una funzione cancellabile - function (index, oldOuterHTML) { }- in cui il valore restituito diventerà il nuovo HTML per l'elemento (a meno chefalse venga restituito).
  • una stringa, che verrà impostata al posto dell'HTML di ciascun elemento.

Per ulteriori informazioni, consultare i documenti jQuery per html().


Questo dovrebbe essere aggiunto al core jQuery in modo che le persone non debbano pensarci. La mia unica domanda è se è probabile che wrap () / unwrap () abbia prestazioni migliori o peggiori di clone ()?
IMSoP

1
IMSoP: in genere, il wrapping / unwrap sarà più veloce perché il clone deve copiare tutti gli elementi figlio e gli attributi dell'elemento. wrap () crea solo un singolo elemento e unwrap () lo distrugge, tutti gli altri elementi vengono semplicemente spostati, il che è un'operazione abbastanza veloce per la maggior parte del tempo.
Andy E

16

Puoi anche usare get (Recupera gli elementi DOM corrispondenti all'oggetto jQuery.).

per esempio:

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

Come metodo di estensione:

jQuery.fn.outerHTML = function () {
  return this.get().map(function (v) {
    return v.outerHTML
  }).join()
};

O

jQuery.fn.outerHTML = function () {
  return $.map(this.get(), function (v) {
    return v.outerHTML
  }).join()
};

Scelta multipla e restituisce l'html esterno di tutti gli elementi corrispondenti.

$('input').outerHTML()

ritorno:

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

11

Per creare un plugin jQuery COMPLETO come .outerHTML, aggiungi il seguente script a qualsiasi file js e includi dopo jQuery nella tua intestazione:

aggiornamento La nuova versione offre un controllo migliore e un servizio più selettivo per 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);

Ciò ti consentirà non solo di ottenere l'HTML esterno di un elemento, ma anche di ottenere un ritorno Array di più elementi contemporaneamente! e può essere utilizzato in entrambi gli stili standard jQuery in quanto tale:

$.outerHTML($("#eleID")); // will return outerHTML of that element and is 
// same as
$("#eleID").outerHTML();
// or
$.outerHTML("#eleID");
// or
$.outerHTML(document.getElementById("eleID"));

Per più elementi

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

Esempi di snippet:


9

puoi anche farlo in questo modo

document.getElementById(id).outerHTML

dove id è l'id dell'elemento che stai cercando


4
$("#" + id).attr("id")è incredibilmente ridondante. Se hai già l'id in una variabile, perché stai usando un selettore jquery per estrarre l'elemento dal dom, quindi interrogare il suo attributo ID?
Sam Dufel,

7

Ho usato la soluzione di Jessica (che è stata modificata da Josh) per far funzionare il file HTML esterno su Firefox. Il problema tuttavia è che il mio codice si stava rompendo perché la sua soluzione ha avvolto l'elemento in un DIV. L'aggiunta di un'altra riga di codice ha risolto il problema.

Il codice seguente fornisce l'HTML esterno lasciando invariato l'albero 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;
    }
}

E usalo così: $ ("# myDiv"). OuterHTML ();

Spero che qualcuno lo trovi utile!


1
Usa .clone come suggerisce @mindplay nel suo commento - è più facile
Yarin


4

Se lo scenario aggiunge una nuova riga in modo dinamico, è possibile utilizzare questo:

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

.myrowè il nome della classe di <tr>. Crea una copia dell'ultima riga e la inserisce come nuova ultima riga. Questo funziona anche in IE7 , mentre il [0].outerHTMLmetodo non consente assegnazioni in ie7


3

node.cloneNode () sembra quasi un hack. È possibile clonare il nodo e aggiungerlo a qualsiasi elemento genitore desiderato e anche manipolarlo manipolando le singole proprietà, anziché dover ad esempio eseguire espressioni regolari su di esso o aggiungerlo al DOM, quindi modificarlo dopo le parole.

Detto questo, puoi anche iterare sugli attributi dell'elemento per costruire una rappresentazione di stringa HTML di esso. Sembra probabile che questo sia il modo in cui verrebbe implementata qualsiasi funzione outerHTML se jQuery ne aggiungesse una.


3

Ho usato la soluzione di Volomike aggiornata da Jessica. Ho appena aggiunto un segno di spunta per vedere se l'elemento esiste e lo ha reso vuoto in caso contrario.

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

Naturalmente, usalo come:

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

3

Puoi trovare una buona opzione .outerHTML () qui https://github.com/darlesson/jquery-outerhtml .

A differenza di .html () che restituisce solo il contenuto HTML dell'elemento, questa versione di .outerHTML () restituisce l'elemento selezionato e il suo contenuto HTML o lo sostituisce come metodo .replaceWith () ma con la differenza che consente di ereditare il HTML sostitutivo con il concatenamento.

Alcuni esempi possono anche essere visualizzati nell'URL sopra.


2

Nota che la soluzione di Josh funziona solo per un singolo elemento.

Probabilmente, l'HTML "esterno" ha davvero senso solo quando hai un singolo elemento, ma ci sono situazioni in cui ha senso prendere un elenco di elementi HTML e trasformarli in markup.

Estendendo la soluzione di Josh, questa gestirà più elementi:

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

Modifica: un altro problema con la soluzione di Josh risolto, vedi commento sopra.


1
La maggior parte dei metodi "getter" di jQuery restituisce dati solo per il primo elemento, quindi sarebbe più logico abbinare questo comportamento.
Andy E

Penso di aver affermato chiaramente perché funziona in questo modo? Sarebbe un brutto / complicato codice quando si dispone di un elenco di elementi - se per qualche motivo si desidera il markup solo per il primo elemento, basta usare: primo nel selettore.
mindplay.dk,

Certo, proprio come potresti usare la mappa con la soluzione di tutti gli altri per ottenere l'HTML di più elementi. Tutto quello che stavo dicendo è che è più coerente abbinare il comportamento dei metodi jQuery standard.
Andy E


2

Ho fatto questo semplice test con outerHTML come soluzione tokimon (senza clone) e outerHTML2 come soluzione 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");

e il risultato nel mio browser chromium (Versione 20.0.1132.57 (0)) era

outerHTML: 81ms
outerHTML2: 439ms

ma se utilizziamo la soluzione tokimon senza la funzione native HTML esterna (che ora è supportata probabilmente in quasi tutti i browser)

noi abbiamo

outerHTML: 594ms
outerHTML2: 332ms

e ci saranno più loop ed elementi negli esempi del mondo reale, quindi la combinazione perfetta sarebbe

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

quindi il metodo clone è in realtà più veloce del metodo wrap / unwrap
(jquery 1.7.2)


2

Ecco un plugin HTML esterno molto ottimizzato per jquery: ( http://jsperf.com/outerhtml-vs-jquery-clone-hack/5 => gli altri 2 frammenti di codice rapido non sono compatibili con alcuni browser come 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 => Non sono d'accordo con te. outerHMTL non ha bisogno di un getter E di un setter: jQuery ci dà già 'sostituisci con' ...

@mindplay => Perché ti unisci a tutto l'HTML esterno? jquery.html restituisce solo il contenuto HTML del PRIMO elemento.

(Mi dispiace, non ho abbastanza reputazione per scrivere commenti)


2

Breve e dolce

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

o evento più dolce con l'aiuto delle funzioni freccia

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

o senza jQuery

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

o se non ti piace questo approccio, controlla quello

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

2

Questo è abbastanza semplice con JavaScript vaniglia ...

document.querySelector('#selector')

1

Questo è ottimo per cambiare elementi sul dom ma NON funziona per esempio quando si passa una stringa html in jquery in questo modo:

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

Dopo alcune manipolazioni ho creato una funzione che consente a quanto sopra di funzionare in ie per stringhe HTML:

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

1

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


0

Mi sono imbattuto in questo mentre cercavo una risposta al mio problema che era che stavo provando a rimuovere una riga della tabella per poi aggiungerla nuovamente in fondo alla tabella (perché stavo creando dinamicamente righe di dati ma volevo mostrare un 'Aggiungi nuovo Record 'digitare la riga in basso).

Ho avuto lo stesso problema, in quanto restituiva innerHtml e quindi mancavano i tag TR, che contenevano l'ID di quella riga e significava che era impossibile ripetere la procedura.

La risposta che ho trovato è stata che la remove()funzione jquery in realtà restituisce l'elemento, che rimuove, come oggetto. Quindi, per rimuovere e aggiungere nuovamente una riga era semplice come questo ...

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

Se non stai rimuovendo l'oggetto ma vuoi copiarlo da qualche altra parte, usa clone()invece la funzione.


0

Plugin jQuery come scorciatoia per ottenere direttamente l'intero elemento HTML:

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

E usalo in questo modo: $(".element").outerHTML();


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

Dove 'x' è il numero del nodo, che inizia con 0 come primo, dovrebbe ottenere il nodo giusto che desideri, se stai cercando di ottenerne uno specifico. Se hai nodi figlio, dovresti davvero inserire un ID su quello che vuoi, per concentrarti solo su quello. Usando quella metodologia e nessuna 'x' ha funzionato bene per me.


1
Le persone hanno votato in basso, ti va di lasciare un commento? Sto facendo in modo che il codice vada SU al GENITORE, quindi ottenga l'HTML del contenuto, non solo facendo un .html()elemento specifico. QUESTO FUNZIONA e vorrei una spiegazione del perché non funziona.
vapcguy,

-4

Soluzione semplice.

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

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

Forse non capisco bene la tua domanda, ma questo otterrà l'html dell'elemento genitore dell'elemento selezionato.

È quello che stai cercando?


25
Altrimenti no, perché se quel genitore ha altri figli otterrà anche quell'html.
David V.

1
...cosa ha detto. Sto cercando l'elemento stesso, non esso e tutti gli altri figli dei suoi genitori. In che modo ha ottenuto due voti positivi ???
Ryan
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.