2010-05-10 29 views
42

Quiero generar un diseño html con áreas (divs, spans) que se pueden mostrar/ocultar condicionalmente. Estas áreas están ocultas por defecto.¿Cómo ocultar elementos con jQuery antes de que se procesen?

Si llamo al método .hide() con jquery en document.ready estas áreas pueden parpadear (los navegadores renderizan parcialmente los documentos cargados). Entonces aplico el estilo "display: none" en el diseño html.

Me pregunto cuál es la mejor práctica para evitar el parpadeo, porque al aplicar "display: none" se rompe la regla de encapsulado - sé lo que hace jquery con hide/show y lo uso. Si la ocultación/muestra de la implementación de jquery cambiará un día, haré que todo el sitio sea inviable.

gracias de antemano

Respuesta

0

No hay absolutamente nada malo en establecer una propiedad de presentación intial de un elemento, especialmente si encapsular en una clase css.

+23

Si va por este camino, un navegador con javascript deshabilitado nunca representará estos elementos –

+8

Nunca, nunca, nunca, nunca. Esta es una mala práctica. – Marko

+1

No existe la "clase css". –

3

I general establecer una clase Js a mi elemento para establecer la propiedad adecuada cuando esté activado Javascript.

Luego puedo configurar el CSS dependiendo de si javascript está presente o no.

ejemplo:

<html class="js"> 
<body> 
<div id="foo"></div> 
</body> 
</html> 

mi css:

html.js #foo 
{ 
    display: none; 
} 

y javascript

$(document).ready(
    function() 
    { 
    $(html).addClass('js'); 
    } 
); 
+0

Gracias, pero decidí detener mi elección en simple-css y encontré este enfoque mixto (css + javascript) sobreescrito para mis tareas. –

+1

El interés es mantener la usabilidad y la accesibilidad para las personas que no tienen javascript, si combina su bloque con su id, es probable que esté oculto para las personas que no tienen javascript habilitado. Querías conocer las mejores prácticas, ** ES ** una mejor práctica. –

1

puede aplicar "display: none" en una clase de CSS.

Porque la orden que tiene un navegador para leer algunos códigos HTML para que el JavaScript encuentre el Elemento. Debe marcar el elemento oculto, ya que el navegador lee su HTML.

Como siempre, también puede insertar el código HTML en su JavaScript, y puede llamar a hide antes de que se represente.

+0

Gracias, decidí aplicar "pantalla: ninguna" con CSS –

31

@ Andrew,

sé la respuesta ya ha sido aceptado, pero utilizando display: none; será una pesadilla para usuarios sin Javascript

Usando Javascript en línea, puede ocultar un elemento sin que parpadee. Los usuarios sin Javascript todavía podrán verlo.

Considere unos pocos divs que deberían ocultarse cuando se carga la página.

<head> 
    <script type="text/javascript" src="jQuery.js"></script> 
</head> 
<body> 
    <div id="hide-me"> 
     ... some content ... 
    </div> 
    <script type="text/javascript"> 
     $("#hide-me").hide(); 
    </script> 

    <div id="hide-me-too"> 
     ... some content ... 
    </div> 
    <script type="text/javascript"> 
     $("#hide-me-too").hide(); 
    </script> 
</body> 

El Javascript en línea se ejecutará tan pronto como se represente el elemento, ocultándolo así al usuario.

+12

Que esto funcionará sin parpadear (en todos los navegadores, para cualquier página) es simplemente falso ... Diferentes navegadores, dependiendo de su implementación exacta y el tamaño de la página, puede terminar "parpadeando" o incluso mostrando el contenido por un tiempo. Ejemplo de EG (1 MB) que se muestra durante un tiempo en Chrome: http://www.architectshack.com/as/BlinkTest.ashx?2 – Tao

+0

Tao acordado: esto NO funciona en algunos navegadores, incluido Chrome. – jimasp

5

Estoy de acuerdo con Boris Guéry en que no se trata de una sobre-ingeniería, sino de una mejor práctica estándar. Me gustaría ir un poco diferente a Boris, al agregar una clase no-js al html inicialmente y luego eliminarlo con JavaScript.

De esta manera no está esperando que el documento esté listo para ocultar el contenido, y sin JavaScript todavía puede ver el contenido. Asumir que el usuario no tiene JavaScript está más en línea con la filosofía de la mejora progresiva.

ejemplo:

<html class="no-js"> 
<body> 
<div id="foo"></div> 
</body> 
</html> 

mi css:

#foo { 
    display: none; 
} 
html.no-js #foo { 
    display: block; 
} 

y javascript

$(document).ready(
    function() 
    { 
    $('html').removeClass('no-js'); 
    } 
); 

********* O en un caso por cada base ***********

ejemplo:

<div class="no-js" id="foo">foobar and stuff</div> 

css:

.no-js { 
    display:none; 
} 
#foo { 
    display: block; 
} 
#foo.no-js { 
    display: none; 
} 

JS:

$(document).ready(function(){ 
    // remove the class from any element that has it. 
    $('.no-js').removeClass('no-js'); 
}); 
+0

+1 Me gusta mucho la idea de esto. Sin embargo, al usar un CMS, no puedo simplemente editar la etiqueta html. Me pregunto si hay otra solución. – Tom

+0

No tiene que ser la etiqueta html, simplemente arroja la red más amplia. ¿Puedes agregar clases a algo? Si es así, puede hacerlo caso por caso, luego, en javascript, elimine la clase .no-js de todos los objetos que la tengan. Actualizaré mi respuesta con una sugerencia. –

+0

para que funcione, mi archivo de script terminó así, por lo que removeClass() se activa temprano y el show() se dispara tarde: $ ('html'). RemoveClass ('no-js'); $ (function() {$ (ventana) .load (function() {$ ('# foo') show();. }); }); – jimasp

0

siempre usaría Modernizr.js http://modernizr.com/ para manejar esto.

Con Mondernizr, se agrega una clase 'js' o 'no-js' a la etiqueta HTML de su página.

Desde aquí puede ocultar sus elementos solo si la etiqueta html tiene la clase js.

Modernizr es ideal para muchas otras aplicaciones y vale la pena leer sobre si no has usado antes: http://modernizr.com/docs/

2

Por qué no hacer precisamente esto ?:

// Hide HTML element ASAP 
$('html').hide(); 

// DOM-ready function 
$(function() { 
    // Do stuff with the DOM, if needed 
    // ... 

    // Show HTML element 
    $('html').show(); 
} 

Parece que funciona bien !

Atentamente.

+4

El problema con este enfoque es que causa que toda la página parpadee en una página recargada. Es más notable si tienes un fondo oscuro. – meesern

0

Lo que siempre hago es crear un div vacío. Y si es necesario mostrar algunos datos dentro de ese componente, cargo de forma asíncrona los datos (es decir, html) con $ .ajax().

No hay necesidad de una lib adicional.

0

Esta es mi sugerencia. Utiliza this solution a create una nueva regla de CSS. Lo principal: se creará una clase de CSS que oculte algunos html si JS está disponible; de ​​lo contrario, no. Y esto sucede antes de ¡el contenido principal (con las partes html que deberían estar ocultas inicialmente) se procesa!

<html> 
<head> 
    <style> 
     /* This class gets overwritten if JS is enabled. If a css file (bootstrap, ...) 
     gets loaded with such a class this would be also overwritten. This solution does 
     not require the class. It is here just to show that it has no effect 
     if JS is activated.*/ 
     .hidden { 
      display: block; 
      background: red; 
     } 
    </style> 
    <script> 
     // this is copied from the linked stackoverflow reply: 
     function setStyle(cssText) { 
      var sheet = document.createElement('style'); 
      sheet.type = 'text/css'; 
      /* Optional */ 
      window.customSheet = sheet; 
      (document.head || document.getElementsByTagName('head')[0]).appendChild(sheet); 
      return (setStyle = function (cssText, node) { 
       if (!node || node.parentNode !== sheet) 
        return sheet.appendChild(document.createTextNode(cssText)); 
       node.nodeValue = cssText; 
       return node; 
      })(cssText); 
     } 

     // And now: This class only gets defined if JS is enabled. Otherwise 
     // it will not be created/overwritten. 
     setStyle('.hidden { display: none; }'); 

     // Attention: Now that the class is defined it could be overwritten 
     // in other CSS declarations (in style tags or with loaded CSS files). 
    </script> 
</head> 
<body> 

    <button>Show/Hide</button> 

    <div class="">before</div> 
    <div class="my-element hidden"> 
     Content that should be initially hidden if possible. 
     You may want to multiply this div by some thousands 
     so that you see the effect. With and without JS enabled. 
    </div> 
    <div class="">after</div> 

    <script src="https://code.jquery.com/jquery-2.2.3.min.js"></script> 
    <script> 
     // Here is some 'normal' JS code. Very likely loaded as a JS file: 
     $('button').click(function() { 
      $('.my-element').toggleClass('hidden'); 
      // or setting display directly: 
      // $('.my-element').toggle() 
      // but well, having class hidden though it is not 
      // hidden makes is not so nice... 
     }) 
    </script> 

</body> 
</html> 

Un poco más complicado, pero creo que esta es una solución adecuada. La ventaja es que se evita el parpadeo y que funciona si JS no está habilitado. Y no requiere jQuery.

0

Después de un tiempo de pensar, tengo la idea de la siguiente solución.En comparación con mi other solution he reducido a lo esencial (y utilizado this para agregar una clase de JS):

<html> 
<head> 
    <style> 
     /* This could be also part of an css file: */ 
     .container-with-hidden-elements .element { 
      display: none; 
     } 
    </style> 
</head> 
<body> 
    <div class="container"> 
     <script> 
      document.getElementsByClassName('container')[0] 
        .className += ' container-with-hidden-elements'; 
     </script> 

     <div class="element">Content that should be initially hidden if possible.</div> 
    </div> 
</body> 
</html> 

La etiqueta script se ejecuta inmediatamente y agrega una clase a un contenedor. Dentro de este contenedor hay algunos elementos anidados que ahora se ocultan porque el contenedor tiene la clase especial y hay una regla CSS que ahora tiene un efecto.

De nuevo, esto sucede antes de que se procese el html restante (evita el parpadeo). Y también, si JS está desactivado, todos los elementos están visiblemente por defecto, lo que se puede llamar Progressive enhancement.

No estoy seguro de si esto funciona en todos los navegadores. Pero IMO sería una solución simple y ordenada.

Cuestiones relacionadas