2010-05-13 8 views
7

J'essaie d'éviter d'utiliser un URI de données car je ne souhaite pas que le document généré soit stocké dans l'historique du navigateur. Est-il possible de remplacer le document HTML entier sur place? J'ai essayé jQuery("html").html("<html>....</html>"), mais les informations style ne survivent pas.Remplacer le document HTML entier en place

+0

Je suis confus par votre déclaration « informations de style ne survit pas », les styles seront liés à ou inclus dans le document, donc si vous remplacez le document en entier vous le feriez attendre les styles à se perdre? Avez-vous vraiment besoin de remplacer le/whole/document? Qu'est-ce que vous essayez d'atteindre du point de vue des visiteurs? –

+0

désolé, je voulais dire que les * nouvelles * informations de style, .html ("... ..."), ne survivent pas. – james

+0

Je ne savais pas que vous parliez de * new * style info. Ce commentaire m'a fait me demander; J'ai mis à jour ma réponse un peu. –

Répondre

10

Vous voulez probablement faire ceci:

jQuery("body").html("new content"); 

... où "new content" comprendrait idéalement que le balisage qui normalement apparaître dans l'élément body et non le reste. Cela remplacera le contenu de l'élément de corps, tout en laissant tout ce que vous avez dans head (comme les informations de feuille de style) seul. Si vous souhaitez également mettre à jour le titre, vous pouvez le faire si cela pourrait fonctionner via document.title = "new title";

Modifier Je me suis demandé de remplacer tout intérieur de l'élément html, et ce qui se passerait. Alors je l'ai fait:

<!DOCTYPE HTML> 
<html> 
<head> 
<meta http-equiv="Content-type" content="text/html;charset=UTF-8"> 
<title>Test Page</title> 
<style type='text/css'> 
body { 
    font-family: sans-serif; 
    font-weight: bold; 
    color:  blue; 
} 
</style> 
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'></script> 
<script type='text/javascript'> 
(function() { 
    $(document).ready(pageInit); 
    function pageInit() { 
     $('#btnChange').live('click', changePage); 
     $('#btnHiThere').live('click', sayHi); 
    } 

    function changePage() { 
     $('html').html(
      "<head><\/head>" + 
      "<body>" + 
      "<input type='button' id='btnHiThere' value='Click for Alert'>" + 
      "<p>Note how this text now looks.<\/p>" + 
      "<\/body>" 
     ); 
    } 

    function sayHi() { 
     alert("Hi there"); 
    } 
})(); 
</script> 
</head> 
<body> 
<input type='button' id='btnHiThere' value='Click for Alert'> 
<input type='button' id='btnChange' value='Change Page'> 
<p>Note now this text current appears in a sans-serif, bold, blue font.</p> 
</body> 
</html> 

Et les résultats ont été tout à fait intéressant   — je me retrouve avec une structure DOM qui ne dispose pas d'un head ou bodydu tout, juste html avec les descendants de head et body à l'intérieur. C'est probablement ce qui gâche le (nouveau) style dans le nouveau contenu. Je reçois essentiellement le même résultat innerHTML directement (ce qui peut expliquer pourquoi cela ne fonctionne pas dans jQuery; jQuery utilise innerHTML quand il le peut, bien qu'il soit très sophistiqué de ne pas le faire quand il ne le peut pas); alors que si je fais quelque chose de similaire en créant explicitement les éléments head et body via document.createElement et document.appendChild, cela fonctionne.

Tout cela signifie presque certainement que c'est plus d'effort que cela en vaut la peine.

Mais: Notez que la modification du semble fonctionner très bien contenu des éléments head et body:

<!DOCTYPE HTML> 
<html> 
<head> 
<meta http-equiv="Content-type" content="text/html;charset=UTF-8"> 
<title>Test Page</title> 
<style type='text/css'> 
body { 
    font-family: sans-serif; 
    font-weight: bold; 
    color:  blue; 
} 
</style> 
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js'></script> 
<script type='text/javascript'> 
(function() { 
    $(document).ready(pageInit); 
    function pageInit() { 
     $('#btnChange').live('click', changePage); 
     $('#btnHiThere').live('click', sayHi); 
    } 

    function changePage() { 
     $('head').html(
      "<style type='text/css'>\n" + 
      "body { color: green; }\n" + 
      "<\/style>\n" 
     ); 
     $('body').html(
      "<input type='button' id='btnHiThere' value='Click for Alert'>" + 
      "<p>Note how this text now looks.<\/p>" 
     ); 
    } 

    function sayHi() { 
     alert("Hi there"); 
    } 
})(); 
</script> 
</head> 
<body> 
<input type='button' id='btnHiThere' value='Click for Alert'> 
<input type='button' id='btnChange' value='Change Page'> 
<p>Note now this text current appears in a sans-serif, bold, blue font.</p> 
</body> 
</html> 

Donc, si vous séparez la « page » vous chargez dans des parties de la tête et le corps , vous pouvez facilement le mettre à jour en place.

+0

il n'est donc pas possible de charger un nouveau tag ? – james

+0

@james: Cela peut être * possible *, mais si vous le faites, vous devrez vous assurer qu'il contient tout ce que vous voulez avoir (comme les références de feuille de style). Vous n'avez probablement pas à vous soucier de la maintenance des balises de script; Une fois que le script a été chargé et évalué, il n'est plus lié à l'élément qui l'a créé et la suppression de l'élément n'a aucun effet sur le script. –

+0

Je noterai (très tard, oui), que la présence de lourds JS dans la tête (grâce à Optimizely ou Ensighten, par exemple), peut rendre même le remplacement du corps intenable. –

1

Non jquery:

var newString = [ 
     "<!doctype html>" 
    , "<html>" 
    , "<head>" 
    , "</head>" 
    , "<body>" 
    , "<h1>new content</h1>" 
    , "</body>" 
    , "</html>" 
].join(""); 

document.getElementById('myIframeId').contentDocument.documentElement.outerHTML = newString; 
Questions connexes