¿Podemos usar window.location.replace
para evitar el historial y apuntar a anclajes en la página sin recargar páginas, pero no en iframes?
El problema es una violación de CSP (política de seguridad de contenido), que los estados script-src 'unsafe-inline'
deben estar habilitados. Excepto que no tengo un CSP definido, e incluso si defino uno y lo permito script-src 'unsafe-inline'
, todavía aparece el mismo error de violación. Mismo resultado en ie11 / chrome / ff.
Iframe en el mismo dominio (en el mismo directorio).
- Apunte al iframe en la consola y úselo en la
window.location.replace('/samepage.html#onpage_anchor')
consola. - funciona. Se dirige al ancla en la página sin volver a cargar la página y sin historial.
- Ponga el mismo código en línea en los enlaces de anclaje y funciona.
- Use el mismo código en un script externo, obtenga el error de violación de csp. Esto funciona bien si no en un iframe.
Intenté crear un CSP para permitir la acción, pero ni siquiera las políticas de seguridad de contenido más permisivas posibles lo permitirían.
Editar: así que reuní ejemplos en plunker que permiten múltiples archivos para poder usar hrefs adecuados que hacen referencia a las páginas padre / hijo.
Notas sobre los ejemplos de plunker:
El problema no se reproduce en estos ejemplos. El guión funciona perfectamente, incluso en el iframe. Sin embargo, el mismo código no funciona en mi servidor local, o cuando lo ejecuto en vivo en un VPS.
Sospecho que la violación de CSP no se activa en plunker porque plunker presenta contenido al navegador a través de una especie de capa de abstracción de algún tipo.
La primera vez que hace clic en los enlaces de acordeón en el padre, se actualiza. Esto se debe a que la forma en que la página se carga inicialmente no hace referencia a index.html. Los clics posteriores funcionan como se espera sin recargar la página. No es un problema en el iframe porque inicialmente hace referencia a child.html
Estos son buenos ejemplos para mostrar el código sin requerir modificaciones para que funcione (como en la necesidad de cambiar los hrefs para que funcionen en fragmentos de stackoverflow, mencionados a continuación). También es bueno, ya que muestra que JavaScript funciona como debería. Pero no muestra el problema real. Aún tendrá que cargarlo en su editor y ejecutarlo en un servidor local o entorno de alojamiento en vivo para ver el problema real.
Ejemplos de Plunker
Con guión: Sin historia
Sin guión: Con historia
Ejemplo de código simplificado
Acordeón simple con una entrada. Suficiente para reproducir el problema.
Al hacer clic en abrir / cerrar se ampliará / colapsará el acordeón, no se requiere JS. El JS debería hacer exactamente lo mismo pero sin historia. Funciona bien, pero no en un iframe.
Notas de fragmentos de código:
Puede ejecutar el fragmento para tener una idea de lo que estoy describiendo, pero en realidad no demuestra el problema.
El fragmento no se comporta como lo haría en un navegador real, el javascript no funciona.
El fragmento muestra el código, pero debe ejecutarse en un iframe para ver el problema. Ejecútelo fuera de un iframe para ver la diferencia y cómo debería funcionar.
- Debido a cómo funcionan los enlaces con el JS (reemplazando la url completa), en realidad deben ser así en
href="https://stackoverflow.com/thispage.html#ac1"
lugar de solohref="#ac1"
como aparecen en el fragmento (no pueden orientar la página html real en el fragmento). Entonces, si intenta esto en su editor (por favor hágalo), recuerde cambiar los enlaces a este formatothis_document.html#anchor
para que sigan siendo los mismos anclajes de página, pero el page.html está incluido en el enlace.
La secuencia de comandos
$(document).ready(function() {
// anchor links without history
$.acAnch = function(event) {
event.preventDefault();
var anchLnk = $(event.target);
var anchTrgt = anchLnk.attr('href');
window.location.replace(anchTrgt);
}
// listen for anchor clicks
$('.accordion').on('click', 'a', $.acAnch);
});
Esto es muy simple:
1. La función acAnch toma el href
atributo y lo coloca en window.location.replace()
.
2. Escuche los clics en las anclas dentro del acordeón para ejecutar la función acAnch.
Entonces todo lo que hace el script es ejecutar window.location.replace('/this_same_page.html#on_page_anchor')
Si pones eso en la consola, funciona, no hay violación de CSP. Pero ejecutarlo desde un script externo no funciona.
Inline en los enlaces funciona bien:
onclick="event.preventDefault();window.location.replace('/thispage.html#acc0');"
onclick="event.preventDefault();window.location.replace('/thispage.html#acc1');"
Poner eso en los enlaces respectivos funciona perfectamente , pero realmente prefiero no usar un script en línea como ese. Debe haber una manera de hacer esto con un script externo.
Intenté ejecutar el javascript en padre en lugar de en el iframe (con modificaciones para seleccionar los enlaces dentro del niño, por supuesto). El mismo resultado de error CSP.
¿Por qué estoy haciendo esto?
Bueno, el sitio es mucho más complejo que el ejemplo. Las anclas en iframes funcionan bien pero agregan historia. Si ejecuta el código anterior sin el javascript (o simplemente ejecuta el fragmento), abra y cierre el acordeón varias veces y use el botón Atrás, volverá a los estados de cierre abierto.
No me importaría el historial, pero si está en un iframe, cuando abandonas la página principal y luego vuelves a él, el historial en el iframe está roto. Retroceder ya no atraviesa los estados de acordeón, sino que solo sigue recargando el iframe. Inicialmente, los anclajes no causan recargas de iframe, sino que solo atraviesan el historial del estado del acordeón, que funciona bien, hasta que abandonas la página y vuelves. Luego, atrás ya no pasa por los estados de acordeón, sino que pasa por una pila de recargas de iframe idénticas. Es un comportamiento muy hostil para el usuario.
No necesito usar location.replace si hay otro método que funcione. Sin embargo, he probado muchos otros enfoques, y he descubierto que los métodos que pueden lograr el mismo resultado, generalmente dan como resultado el mismo error.
El objetivo es simplemente activar los enlaces de anclaje en la página sin recargar, y sin historial, dentro de un iframe.
El guión en línea funciona. ¿Podemos hacer que funcione en un archivo externo .js?
fuente
<a href="#ac0" class="ac-close">Close</a>
debería funcionar.Respuestas:
sí, puede usar iframe con -window-location-replace como referencia, puede usar este enlace de referencia JavaScript location.replace e iframe
fuente
puede usar CSS en lugar de la etiqueta iframe html porque la etiqueta iframe se elimina en html
fuente