5 Stimmen

Inhalt von <body> </body> innerhalb einer Zeichenkette abrufen

Ich möchte das Folgende tun.

$("a").click(function (event) {

    event.preventDefault();

    $.get($(this).attr("href"), function(data) {

        $("html").html(data);

    });

});

Ich möchte, dass das Verhalten aller Hyperlinks einen Ajax-Aufruf macht und die HTML abruft.

Leider können Sie nicht einfach die aktuelle Html-Datei durch die Html-Datei ersetzen, die Sie in der Ajax-Antwort erhalten.

Wie kann man nur das greifen, was innerhalb der <body> </body> Tags der Ajax-Antwort, so dass ich die nur den Inhalt des Textkörpers in der vorhandenen HTML-Datei.

Bearbeiten: die <body> Eröffnungs-Tag wird nicht immer einfach sein <body> kann es manchmal eine Klasse haben, z. B.

<body class="class1 class2">

2 Stimmen

Was ist falsch an $("body").html() ?

4 Stimmen

Warum möchten Sie den gesamten Inhalt des BODY ersetzen? PUNKT VORHABEN

0 Stimmen

Die beste Antwort, die ich dazu gefunden habe, finden Sie hier: stackoverflow.com/questions/3628374/

11voto

Rob Raisch Punkte 16372

Wenn ich Sie richtig verstehe, müssen Sie den Inhalt zwischen den Body-Tags mit einer Regex erfassen.

$.get($(this).attr("href"), function(data) {
    var body=data.replace(/^.*?<body>(.*?)<\/body>.*?$/s,"$1");
    $("body").html(body);

});

EDIT

Basierend auf Ihren Kommentaren hier ein Update, um jedes Body-Tag, unabhängig von seinen Attributen, abzugleichen:

$.get($(this).attr("href"), function(data) {
    var body=data.replace(/^.*?<body[^>]*>(.*?)<\/body>.*?$/i,"$1");
    $("body").html(body);

});

Die Regex lautet:

^               match starting at beginning of string

.*?             ignore zero or more characters (non-greedy)

<body[^>]*>     match literal '<body' 
                    followed by zero or more chars other than '>'
                    followed by literal '>'

(               start capture

  .*?           zero or more characters (non-greedy)

)               end capture

<\/body>        match literal '</body>'

.*?             ignore zero or more characters (non-greedy)

$               to end of string

Fügen Sie den Schalter 'i' hinzu, um Groß- und Kleinschreibung abzugleichen.

Und bitte ignorieren Sie meinen Kommentar bezüglich des 's'-Schalters, in JavaScript sind alle RegExp bereits standardmäßig einzeilig, um ein mehrzeiliges Muster zu finden, fügen Sie 'm' hinzu. (Verdammt seist du, Perl, dass du mich störst, wenn ich über JavaScript schreibe :-)

1 Stimmen

Ich glaube nicht, dass Regex funktioniert, habe ich eine console.log auf die body-Variable und es war immer noch die Rückgabe der gesamten html, nicht nur, was innerhalb der body-Tags war.

0 Stimmen

Ahh... ich vergaß zu erwähnen, dass Sie bei mehrzeiligen Inhalten das Flag 's' zur Regex hinzufügen müssen, um die gesamte Zeichenkette als eine einzige Zeile zu behandeln. (Das Beispiel wurde bearbeitet.)

0 Stimmen

Mit der bearbeiteten regex im erhalten 'SyntaxError: ungültigen regulären Ausdruck Flag s' in Firebug

1voto

Peter V. Mørch Punkte 11308

Ich wollte mich nicht mit regulären Ausdrücken herumschlagen. Stattdessen habe ich eine versteckte <iframe> , lud den Inhalt hinein und extrahierte die <body> von der Seite im <iframe> in der Seite onload() .

Ich musste vorsichtig sein mit Politik der gleichen Herkunft für den iframe (dieser Artikel wies den Weg):

var iframe = document.createElement('iframe');
iframe.style.display = "none";
jQuery('body').append(iframe);
iframe.contentWindow.contents = data;
iframe.onload = function () {
    var bodyHTML = jQuery(iframe).contents()
                        .find('body').html();
    // Use the bodyHTML as you see fit
    jQuery('#error').html(bodyHTML);
}
iframe.src = 'javascript:window["contents"]';

Entfernen Sie einfach die <iframe> wenn du fertig bist...

-1voto

Chris Baker Punkte 48263

Stellen Sie sicher, dass Sie Ereignisse an das Dokument binden, gefiltert nach Klasse ( $(document).on('click', '.my-class-name', doThings); ) Wenn Sie die Html des Körpers ersetzen, werden alle direkt durchgeführten Ereignisbindungen ( $('.my-class-name').on('click', doThings); ) wird zerstört, wenn das DOM unter Verwendung des neuen html neu gezeichnet wird. Das erneute Binden wird funktionieren, aber es wird auch eine Reihe von Zeigern von den alten Ereignissen und Knoten hinterlassen, die der Garbage Collector aufräumen muss - einfacher ausgedrückt kann es die Seite schwerer und schwerer machen, je länger sie geöffnet ist.

Ich habe dies nicht auf mehreren Plattformen getestet, daher ist hier Vorsicht geboten.

// create a new html document
function createDocument(html) {
  var doc = document.implementation.createHTMLDocument('')
  doc.documentElement.innerHTML = html
  return doc;
}
$("a").click(function (event) {
    event.preventDefault();
    $.get($(this).attr("href"), function(data) {
        $("body").html($(createDocument(data)).find('body').html);
    });
});

0 Stimmen

Ich hätte mich gefreut, wenn das funktioniert hätte. Aber jQuery('<html><body>foobar</body></html>').find('body').leng‌​th == 0 :-( Aus diesem Grund stimme ich mit "down" ab.

0 Stimmen

Seltsam, jQuery('<div><span>foobar</span></div>').find('span').length == 1 , aber ich kann nicht extrahieren <body> von einer <html>

0 Stimmen

@PeterV.Mørch Ich habe dort eine Funktion hinzugefügt, um zunächst ein neues HTML-Dokument zu erstellen. Das scheint zu funktionieren - können Sie das bestätigen?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X