Mejor práctica para mostrar contenido dinámicamente?

Iniciado por @XSStringManolo, 7 Enero 2020, 23:37 PM

0 Miembros y 1 Visitante están viendo este tema.

@XSStringManolo

Lo que quiero hacer:
-Embeber unas 4 o 5 páginas al pinchar en un href sin necesidad de navegar a otro sitio.
Un ejemplo popular son las típicas web que tienen varias pestañas tipo:
[Home] [About] [Latest] [Support]
Aquí el contenido.
..............................
..............................
..............................

Según vás pinchando en las distintas pestañas, va cambiando solo el contenido. La funcionalidad es sencilla, y por eso mismo no sé de que forma debería implementarlo, ya que tengo muchas opciones y no sé cual es la más adecuada.

Formas que se me ocurren:
1. Crear un nodo con js y hacer append dentro de una tag main, un div, o culquier otra.

2. Tener todas las páginas en el contenedor de antemano y cambiar el contenido mostrado con un evento usando display: none; visibility: hidden y mostrar con display: block; visibility: visible. O mandando todo a un -9999px e ir trayéndolo y sacándolo.

3. Tener todo y cambiar el z-index.

4. Crear dinámicamente el código con createElement.

5. Al cargar la página chequear si se puede usar el domStorage y guardar ahí el contenido de las páginas.

6. Hacer una petición por xhr al pinchar el link.

7. Usar Iframes u otros marcos.

8. Tener el contenido en literales ` ` con un pre tag.

Las páginas van a ser estáticas. Por ejemplo una muy sencilla (tipo documento de texto) para reportar los bugs de la web con un text area y hacer menciones a quien los reporte. Otra con una descarga de un .ova. Otra con un link al github del proyecto. Otra con avisos legales... Cosas de ese tipo.

engel lex

la tecnica clasica es un iframe, aunque muchos frameworks de js para "pestañas" usan es cargar todo el contenido y ocultar o mostrar a voluntad (lo que te permite precargar las imagenes en segundo plano)
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

AlbertoBSD

Cita de: @?0!,5^34 en  7 Enero 2020, 23:37 PM
4. Crear dinámicamente el código con createElement.

6. Hacer una petición por xhr al pinchar el link.

Estas 2 se me hacen aceptables puedes crear borran el contenido del div principal y hacer la petición, cuando se resuelva pues solo colocas el contenido en el div

Si lo que quieres es que el cambio sea instantáneo, podrías optar solo solo por ocultar y mostrar div y no depender de ningún framework, ademas el javascript sin tanto adorno es mucho mas rápido.

Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

@XSStringManolo

#3
Voy a optar por el iframe. Me va a permitir tener las páginas y el código bien organizado. Me apunto el async js para otros proyectos.

Ando buscando truquillos y me encontré algo curioso:
https://jakearchibald.com/2016/fun-hacks-faster-content/
No lo voy a usar pero es digno de comentar!


No recomiendo Iframe:
Parece que el iframe da problemas con Android. Al pinchar en un input text dentro de un iframe, el iframe se desplaza. Tras ajustarlo par hacerlo inmovil, pasa algo curioso, como no se puede mover, el teclado tapa el campo donde vas a escribir. Si escribes; o no ves lo que escribes o el iframe se mueve de forma inadecuada para dejarte ver el texto. Igual se puede arreglar, pero no me gusta la idea de hacer un arreglo con truquillos porque no sabes como va a funcionar en todas las resoluciones y distintos navegadores.

Recomendado:
Al final opté por la opción de incluir directamente el propio código de las diversas páginas dentro de la página página principal ya que no va a ser mucho y cambiar los estilos con javascript. Si ya manejas no hace falta que leas más.

El iframe daba bastantes problemas en Android y no quería comportmientos imprevisibles en distintas plataformas y navegadores. Era mi opción favorita pero lo descarté tras tenerlo implementado.

Entonces pensé en "importar" las diversas páginas de la misma forma que se importan el js y el css para después parsearlo. Buscando una buena forma de hacerlo, me encontré con HTML5 imports. Tras buscar en la página de Mozilla, lo descarté también. Parece que es una tecnología obsoleta, o se intenta no darle soporte.

A continuación valoré usar Fetch con un polyfill, xhr o ajax. Al ser poco contenido, decidí no utilizar este método por los siguientes motivos:
-El tiempo del envio de petición y la solicitud de respuesta.
-Requiere post-procesado ya que va a descargar páginas independientes para integrarlas.
-Añade un vector de ataque a la página o a sus usuarios que puedo evitar.
-Al ser común que se repitan peticiones a la misma página, requiere que las guarde tras descargarse al principio para no hacer una petición cada vez que se pinche un enlace.
-El contenido de las páginas externas es muy poco probable que vaya a ser modificado durante el uso de la página principal. Y en caso de cambiar el contenido, no va a afectar al usuario.

Puede que al hacer las descargas de forma asíncrona no sea un método tan lento en comparación.

Se cargan toda las páginas y se les cambia el display a cada id y el visibility. En el botón blanco encima del header se abre la ventana con los diversos links. Le añadí así por encima un form, texto y alguna etiqueta para que se vea que se cambia el contenido. Con la ventana hago lo mismo de no mostrarla para ese efecto de que se cierra al pulsar un link.
http://stringmanolo.byethost12.com/dhunter/indexBUENO.html


En el HTML añadí el código de las páginas en varios articles dentro de una sección de páginas. Agregué un id a cada uno por ahorrarme un bucle y lios si añado más sections o articles dentro de cada article.
Código (html4strict) [Seleccionar]
<article id="HowTo">
 <h2>Welcome To DHunter.</h2>
 <list><h3>HOW TO:</h3>
   <li>Hunt A Domain</li>
   <li>Shoot A Dictionary</li>
         ...
 </list>
</article>
<article id="Github">
Aquí abra algo de github
</article>
<article id="Download">
Aqui links de descarga.
</article>
<article id="Bugs">
 <h2>Please! Help us make this site more secure toward our users.</h2>
 <list>TOP HUNTERS:
   <li>Be the first!</li>
 </list>
...


En el CSS los pongo como invisibles desde el principio, para que no se vean al cargar la página:
Código (css) [Seleccionar]
 #HowTo, #Github, #Download, #Bugs {
 display: none;
 visibility: hidden;
}


En el javascript hago lo siguiente:
Obtengo los elementos a href de los hipervínculos.
Le añado EventListeners a la espera de un click en el enlace a todos ellos.
Declaré un par de funciónes para ser llamadas en cada click que le aplica los estilos a cada elemento:
Código (javascript) [Seleccionar]
function doNotShow(arrayElements) {

 for(var i = 0; i < arrayElements.length; ++i) {

   arrayElements[i].style.display="none";
   arrayElements[i].style.visibility="hidden";

 }

}



function Show(arrayElements) {

 for(var i = 0; i < arrayElements.length; ++i) {

   arrayElements[i].style.display="block";
   arrayElements[i].style.visibility="visible";

 }

}


La expresión final es esta:
Código (javascript) [Seleccionar]
LINK5.addEventListener("click", function(){DefStyle();doNotShow([MAIN, Download, Bugs, Github]);Show([HowTo])});
LINK5 es un getElementById a uno de los a href. (El "HowTo")

Todo lo que hay dentro de los corchetes de function (cuerpo de la función anónima), son las expresiones que se evaluan al hacer click en el link (el elemento al que referencia el objeto).
DefStyle son estilos que aplico por defecto para ocultar el modal/ventana y los links mostrados en ella.(Para dar la sensación de que se cierra la ventana al abrir el link) Y mostrar el botón que abre la ventana.
A la función doNotShow le paso por parámetro un array con todos los elementos que quiero esconder. Y con Show lo mismo para los elementos que quiero mostrar.
En el caso de LINK5 que es un <a href="#HowTo"> oculto todas las páginas (articles) menos la de HowTo.

La sintaxis se puede reducir mucho. Yo lo he echo así por mayor versatilidad a la hora de introducir cambios.

Para reducir el código:
Modificando LINK1 LINK2 LINK3... Por el array devuelto de la expresión LINKS = getElementsByTagName("articles"); O className también vale.

Obteniendo los elementos en un array PAGINA de la misma forma que LINKS.

Haciendo un contador estático intermitente para las llamadas, o pasando un booleano para saber cuando mostrar o esconder utilizando la misma función. U otra opción es esconder todos los elementos en la función y trás la llamada mostrar el elemento.

Añadiendo la llamada a DefStyle() dentro de la otra función. Entonces quedaría:

Código (javascript) [Seleccionar]
for(var i = 0; i < LINKS.length; ++i) {

 LINKS[i].addEventListener("click", function(){OcultarTodo();Mostrar(ArArr[i])});

}

Siendo ArArr[] un array con los article.
Así la expresión queda fácilmente por debajo de las 80 líneas de código que se suele recomendar no propasar para facilitar la lectura de código.