2010-05-13 16 views
7

Estoy tratando de evitar el uso de un URI de datos porque no quiero que el documento generado se almacene en el historial del navegador. ¿Es posible reemplazar todo el documento HTML en el lugar?Reemplazar todo el documento HTML en contexto

Intenté jQuery("html").html("<html>....</html>"), pero la información style no sobrevive.

+0

Estoy confundido por su estado de "información de estilo no sobrevive", los estilos estarán ligados a, o incluidas en el documento, por lo que si se reemplaza todo el documento que esperar que los estilos se pierdan? ¿Realmente necesita reemplazar el/todo/documento? ¿Qué intentas lograr desde el punto de vista de los visitantes? –

+0

lo siento, quise decir que la * nueva información de estilo, .html ("... ..."), no sobrevive. – james

+0

No me di cuenta de que estabas hablando de información de estilo * new *. Ese comentario me hizo preguntarme; He actualizado mi respuesta un poco. –

Respuesta

10

es probable que desee hacer esto:

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

... donde "new content" lo ideal sería incluir sólo el margen de beneficio que normalmente aparecería dentro del elemento body y no el resto. Eso reemplazará el contenido del elemento del cuerpo, dejando todo lo que tenga en head (como la información de la hoja de estilo) solo. Si también desea actualizar el título, puede hacerlo a través document.title = "new title";

Editar llegué a preguntarse sobre la sustitución de todo dentro del elemento html, ya que quiere trabajar, y lo que sucedería. Así que hice esto:

<!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> 

y los resultados fueron bastante interesante   — termino con una estructura DOM que no tenga un head o body en absoluto, simplemente html con los descendientes de head y body dentro. Esto es probablemente lo que está arruinando el (nuevo) estilo en el nuevo contenido. Obtengo esencialmente el mismo resultado innerHTML configuración (que puede ser por qué no funciona en jQuery; jQuery usa innerHTML cuando puede, aunque es muy sofisticado sobre no hacerlo cuando no puede); mientras que si hago algo similar creando explícitamente los elementos head y body a través de document.createElement y document.appendChild, funciona.

Todo lo cual, casi con certeza, significa que esto representa más esfuerzo de lo que vale.

Pero: Tenga en cuenta que al cambiar el contenido de de los elementos head y body parece funcionar muy bien:

<!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> 

Así que si se separa la "página" que está cargando en partes de cabeza y cuerpo , puedes actualizarlo fácilmente en su lugar.

+0

por lo que no es posible cargar una nueva etiqueta ? – james

+0

@james: Es * posible * posible, pero si lo hace, deberá asegurarse de que tiene todo lo que aún desea (como las referencias de la hoja de estilo). Probablemente no tengas que preocuparte por mantener etiquetas de script; una vez que se ha cargado y evaluado el guión, ya no está vinculado al elemento que lo creó y la eliminación del elemento no tiene ningún efecto en el guión. –

+0

Notaré (muy tardíamente, sí), que la presencia de JS pesado en la cabeza (a través de Optimizely o Envelop, por ejemplo), puede hacer que incluso reemplazar solo el cuerpo sea insostenible. –

1

Sin jQuery:

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

document.getElementById('myIframeId').contentDocument.documentElement.outerHTML = newString; 
Cuestiones relacionadas