Información clasificada bajo Código

Imprimir en Opera con javascript

Publicado por Jorge Hoya el 11 enero 2012, 14:56 - Comentarios comentarios (0)
Etiquetas: ,

Hoy me he enterado, dicen que más vale tarde que nunca, que la estándar de imprimir con javascript:

window.print();

no funciona siempre en Opera. Para que en lo haga hay que tener en cuenta que la página debe estar completamente cargada. Si esto se cumple, el siguiente ejemplo funciona:

<input type="button" value="Print this page" onClick="javascript:window.print();" ID="Button1" NAME="Button1">

El problema viene cuando antes de imprimir necesitamos hacer algo sobre el HTML ( abrimos una nueva ventana, modificarlo, etc). Tomemos este ejemplo, en el que en la función ocultar() debe hacer cosas previas a la impresión.

function imprimePagina(){
    ocultar(); // funcion que necesita ocultar información que no debe ser impresa.
    window.print();
    // resto de código;
}

Este ejemplo funciona en IE, Firefox, Chrome pero no en Opera. Para solventarlo podríamos probar con:

function imprimePagina() {
    ocultar(); // funcion que necesita ocultar información que no debe ser impresa.
    window.setTimeout(function () {
        window.print();
    }, 5);
    // resto de código;
}

Que, si no he escrito mal el ejemplo, debiera funcionar. En el caso de que abriéramos una ventana hemos de recordar lo que comentamos al principio: la página, la nueva, debe estar completamente cargada antes de intentar imprimirla en Opera. Como no controlamos en qué momento sucede esto, podemos confiar en el evento load de la ventana para imprimirla.

window.onload = function () {
    window.setTimeout(function () {
        window.print();
    }, 500);
}

Espero que a alguno le valga de algo :-)

Referencia: http://stackoverflow.com/questions/3482428/window-print-not-working-with-opera-browser

Sigue leyendo 'Imprimir en Opera con javascript'

Subir

Biblioteca JavaScript para simular Windows 7

Publicado por Jorge Hoya el 19 enero 2011, 21:51 - Comentarios comentarios (0)
Etiquetas: ,

demo de la biblioteca de Soyos


Leo hoy en el boletín de Campus MVP una noticia sobre una biblioteca de JavaScript basada en jQuery que nos permite reproducir el entorno de escritorio de Windows 7 dentro de un navegador, creada por la gente de Soyos Lab. Me he quedado asustado :-)

Sigue leyendo 'Biblioteca JavaScript para simular Windows 7'

Subir

En el desarrollo de la Web de mi hermano Tomás me he visto obligado a establecer la misma altura a dos columnas. Como no fuí capaz de hacerlo mediante CSS me decidí por usar el método que ya os dejé hace tiempo, en el artículo Columnas de igual altura usando Javascript que si bien no es un lujo de programación resuelve algún que otro problema.

Como recientemente he estado enredado algo con jQuery me dije, ¿seré capaz de rehacer el código javascript usado en aquel entonces para que haga uso de jQuery? Pués dicho y hecho, aquí tenéis el nuevo código.

  var boxes = {  
    init : function(){},  
    alturaJQuery : function (){  
      al = new Array(); max = 0;  
      try  
      {  
        jQuery.each(arguments, function(c, v){  
          al[c] = $('#' + v).height();  
        })  
        max = boxes.mayorJQuery(al);  
        if(max > 0) {  
          for(i=0; i<arguments.length;i++){
            $("#" + arguments[i]).css('height', max + 'px');
          }
        };
      }
      catch (exc)
      { 
        alert('se ha producido un error en los ajustes'); 
        throw exc;
      }
    }
    , mayorJQuery : function(datos)
    {
      var salida =0;
      jQuery.each(datos, function(c, v){ v = parseInt(v); if(v> salida) salida = v; } )  
      return salida;  
    }
  }
$(document).ready(function(){ boxes.alturaJQuery('caja_uno', 'caja_dos', 'caja_tres'); } );

Sigue leyendo 'Columnas de igual altura usando Javascript con jQuery'

Subir

Nace una idea

Hace algunas semanas, por la petición de un compañero de trabajo, me surgió la necesidad de hacer una menú horizontal con doble nivel, es decir, un menú horizontal con un submenú para cada uno de sus elementos. Sé que hay muchos modos de solventar el problema pero me acordé de la propuesta de Roger Johansson, que mi amigo Marco tiene colocada en su Web, y me piqué con la idea de adaptarlo para este caso.

La idea que me surgió para el menú fué la de uno que se desplegase dentro de dos áreas horizontales contigüas verticalmente y de altura fija, o lo que es lo mismo, dos bandas de color de la misma altura y una encima de otra, tal y como se muestra en el siguiente esquema.

---------------------------------------------------------------------------------------------
| Zona I: zona de visualización de los elementos del menú superior                           |
---------------------------------------------------------------------------------------------
| Zona II: zona de visualización del submenú de cada uno de los elementos del nivel superior.|
---------------------------------------------------------------------------------------------

O como se ve en la siguiente imagen

Menu horizontal

Analizando la propuesta de Johansson

Roger Johansson utiliza únicamente tres elementos para crear su menú: un código HTML correcto, una hoja de estilos y un fichero JavaScript sencillo de entender y muy efectivo (no pocos lo hubieran hecho con jQuery o Mootools pero en ellos queda hacer la pertinente versión). Los submenús, de un elemento del menú padre, son desplegados y replegados mediante los consiguientes clicks del ratón: uno para desplegar y otro para replegar. Es decir, es necesaria la interacción del usuario para replegar los submenús ya desplegados.

Este comportamiento, que para muchas situaciones es válido, en nuestro caso (el doble menú horizontal en dos bandas, o zonas), no lo es. Necesitamos que estando desplegado un submenú, ocupando toda la Zona II, seleccionemos otro elemento del menú padre, de la Zona I, aquel se repliegue y se despliegue el submenú del elemento seleccionado. Buff! no sé si me estoy explicando u os estoy liando. Vayamos más despacio: si tenemos desplegado el submenú del elemento_1, llamado submenu_1, y queremos ver el submenú del elemento_2, llamado submenu_2 tendremos que:

  1. pinchar en elemento_2
  2. replegar submenu_1
  3. desplegar submenu_2

Es decir: antes de desplegar un nuevo submenú hemos de replegar el que esté desplegado o, lo que es lo mismo, antes de desplegar un nuevo submenú hemos de replegarlos todo.

El código JavaScript

Manos a la obra

Llevando esta idea al código JavaScript, lo que vamos a hacer es modificar el método toggle(), de la clase toggleMenuH() (llamada así para diferenciarla de la original toggleMenu()), para que sea capaz de replegar todos los submenús.

Código original:

toggle : function(el, sHiddenClass) {
  var oRegExp = new RegExp("(^|\\s)" + sHiddenClass + "(\\s|$)");
  el.className = (oRegExp.test(el.className)) ? el.className.replace(oRegExp, '') : el.className + ' ' + sHiddenClass;
}

Código modificado:

toggle : function(el, sHiddenClass, bHide) {
  if(bHide == true) this.hideAll(el, sHiddenClass)
  var oRegExp = new RegExp("(^|\\s)" + sHiddenClass + "(\\s|$)");
  el.className = (oRegExp.test(el.className)) ? el.className.replace(oRegExp, '') : el.className + ' ' + sHiddenClass;
}

Lo único que hemos hecho es incluir una variable para saber si hemos de ocultar todos los elementos del menú (la presencia de esta nueva variable obligará a modificar todas las llamadas que se hagan a esta función para tenerla en cuenta), y crear la función, llamada hideAll(), que se encargará de ocultar todos los submenús cuando sea necesario.

hideAll : function(el, sHiddenClass){
  for(i = 0; i < arrMenus.length; i++){
    arrSubMenus = arrMenus[i].getElementsByTagName('ul');
    for (var j = 0; j < arrSubMenus.length; j++) {
      oSubMenu = arrSubMenus[j];
      if(el !== oSubMenu){
        var oRegExp = new RegExp("(^|\\s)" + sHiddenClass + "(\\s|$)");
        if(!oRegExp.test(oSubMenu.className)) {oSubMenu.className = oSubMenu.className + ' ' + sHiddenClass;}
      }
    }
  }
}
Vamos un poco más allá

En cuanto le envié el nuevo menú a mi gurú del CSS, el Sr. Marco Giacomuzzi, me retó a darle una vuelta de tuerca más y dotarle de alguna nueva funcionalidad. De las que comentaba las más destacables fueron:

  • Encerrar cada uno de los enlaces dentro de una etiqueta HTML, lo que permitiría un mejor control sobre el elemento a la hora de maquetar el menú.
  • Resaltar la opción del menú superior asociada al submenú desplegado.

La implementación de estas dos nuevas cualidades provocaron una serie de cambios en el código JavaScript, que a continuación veremos. La introducción de un elemento HTML para que contenga a los enlaces provoca una cambio en la ruta de acceso, vía DOM, desde el nodo del enlace hasta el elemento de la lista que lo contiene. Es decir, que en la función toggleMenuH.ini() pasamos de tener:

oLink.onclick = function(){
  toggleMenuH.toggle(this.parentNode.getElementsByTagName('ul')[0], sHiddenClass, sTag, sOverParent, true);
  return false;
}

a tener esto otro (fijaros en la palabra en negrita).

oLink.onclick = function(){
  toggleMenuH.toggle(this.parentNode.parentNode.getElementsByTagName('ul')[0], sHiddenClass, sTag, sOverParent, true);
  return false;
}

Sencillo, ¿no? Veamos ahora qué necesitamos para poder resaltar la opción de menú asociada al submenú desplegado. Intuitivamente vemos que lo que necesitamos es cambiar el estilo del elemento del menú del primer nivel cada vez pinchemos sobre él. O lo que es lo mismo, necesitamos cambiar el estilo del elemento del menú del primer nivel cada vez que que despleguemos o repleguemos su submenú asociado. Es decir, que hemos de modificar el método, o función, que ejecuta esta última idea, que no es otro que el método toggleMenuH.toggle(), para localizar el elemento padre y aplicarle, o quitarle, el estilo que se encargue del resalte (estilo que debemos pasar a la clase toggleMenuH y que debe ser incorporado a todo los métodos que hagan uso de él). Al implementarlo esta idea en el código se pasa de tener:

toggle : function(el, sHiddenClass, bHide) {
  if(bHide == true) this.hideAll(el, sHiddenClass)
  var oRegExp = new RegExp("(^|\\s)" + sHiddenClass + "(\\s|$)");
  el.className = (oRegExp.test(el.className)) ? el.className.replace(oRegExp, '') : el.className + ' ' + sHiddenClass;
 }

A tener:

toggle : function(el, sHiddenClass, sTag, sOverParent, bHide) {
  if(bHide == true) this.hideAll(el, sHiddenClass, sOverParent)
  var oRegExp = new RegExp("(^|\\s)" + sHiddenClass + "(\\s|$)");
  var oRegExpParent = new RegExp("(^|\\s)" + sOverParent + "(\\s|$)");
  eval("t = el.parentNode.getElementsByTagName('"+sTag+"')[0].getElementsByTagName('a')[0]");
  if(oRegExp.test(el.className)){
    el.className = el.className.replace(oRegExp, '');
    t.className = t.className + ' ' + sOverParent;
  }
  else{
    el.className = el.className + ' ' + sHiddenClass;
    t.className = t.className.replace(oRegExpParent, '');
  }
}

Fijaros en las líneas en negrita, son las encargadas de hacer lo que antes comentábamos sobre identificar al padre y modificarlo con un nuevo estilo.

El código CSS

El modo de presentar los elementos en la página depende ámpliamente de la persona que lo haga; en nuestro caso la hoja de estilos intenta ceñirse a nuestro planteamiento inicial (un menú horizontal de dos niveles con los elementos del primer nivel en la Zona I y los del segundo nivel en la Zona II) así que veréis que la hoja de estilos está muy adaptada a las necesidades del problema y que no es fácilmente utilizable en otras situaciones.

Ya casi acabamos

Como no podía ser menos, en cuanto aplicamos la hoja de estilos y probamos todo junto nos damos cuenta que nuestro amigo Internet Explorer 6 tenía problemas para interpretar nuestro código y no ajusta correctamente el tamaño del submenú desplegado (en lugar de ajustarlo al 100%, como fija la clase second_menu de la hoja de estilos, .lo ajustaba al ancho del mayor de los textos incluidos en alguno de los elementos del submenú). A la vista del problema, y ya que vía CSS no pude solventarlo, decidí usar JavaScript para hacerlo.

La idea de lo que se tiene que hacer era clara: hay que que asignar al submenú la anchura del menú principal. Para ello creamos un nuevo método para la clase toggleMenuH llamado equalWidth que realiza lo establecido: busca el primero de los elementos, del tipo dado por la variable oElm, que tengan la clase strClassFather y establece su anchura de diseño, dada por su propiedad offsetWidth, como la anchura de su submenú asociado.

equalWidth : function (oElm, strClassFather, strClassChild){
  arrMenus = this.getElementsByClassName(document, oElm, strClassFather);
  if(arrMenus[0]){
    var dWidth = parseInt(arrMenus[0].offsetWidth);
    arrSubMenus = this.getElementsByClassName(document, oElm, strClassChild);
    for(var j=0; j<arrSubMenus.length;j++){
      oSubMenu = arrSubMenus[j];
      oSubMenu.style.width = dWidth + 'px';
    }
  }
}

Para que esta corrección de dimensiones tenga en cuenta todas las posibilidades de actuación del usuario debe ser incluida en los eventos onload y resize de la página.

Resultado final

Las modificaciones que han sido incorporadas provocan que sean necesarios más datos a la hora de iniciar el proceso (recordad que se hace con la última línea del documento JavaScript hmenu.js). El significado de las siguientes líneas de código es establecer que en el momento de finalización de la carga de la página se pongan en marcha las funciones de preparación del menú y de corrección de las anchuras (la misma que se pone en marcha también en el momento de redimensionar la página).

toggleMenuH.addEvent(window, 'load', function(){
  toggleMenuH.init('first_menu', 'hidden', 'span', 'select');
  toggleMenuH.equalWidth('ul','first_menu', 'second_menu');
})
toggleMenuH.addEvent(window, 'resize', function(){
  toggleMenuH.equalWidth('ul','first_menu', 'second_menu');
})

Los argumentos que se le deben pasar a la función toggleMenuH.init, tal y como vemos en el ejemplo, son:

  • first_menu: el nombre de la clase que se aplicará a la lista, etiqueta <ul>, de elementos del primer nivel del menú.
  • hidden: el nombre de la clase que se aplicará a cada uno de los submenús, o listas del segundo nivel, para ocultarlos.
  • span: la etiqueta HTML que será usada para encerrar cada uno de los enlaces del menú y dar así mayor versatilidad a la hora de maquetar el menú.
  • select: el nombre de la clase que se aplicará al elemento del primer nivel que tenga su submenú desplegado, es decir, el elemento activo.

Así mismo, los argumentos para la función toggleMenuH.equalWidth, tal y como vemos en el ejemplo, son:

  • ul: el elemento HTML sobre el que buscaremos aquellos que tengan las clases dadas por los demás parámetros.
  • first_menu: el nombre de la clase que se ha establecido en el elemento HTML, <ul>, del menú principal.
  • second_menu: el nombre de la clase que se ha establecido en el elemento HTML, <ul>, del menú secundario.

No sé si la explicación ha quedado clara o no, así que mejor será que os proporcione una demostración de lo que os he estado contando. Los ficheros que necesitas para reproducir el ejemplo son el código JavaScript y el código CSS

A petición popular

Como varios de vosotros me habéis preguntado por el modo de conseguir que al cargar la página una de las opciones del menú superior ya esté desplegada, he modificado el código JavaScript del menú para que lo tenga en cuenta. Lo único que he hecho es incluir un parámetro más en toggleMenuH.init() para indicar qué elemento del menú superior queremos desplegar. Así, pasamos de tener

init : function(sContainerClass, sHiddenClass, sTag, sOverParent)

a tener

init : function(sContainerClass, sHiddenClass, sTag, sOverParent, iViewIndex)

donde, si consideramos las opciones del menú superior como los elementos de un array, iviewIndex indica el elemento del array de opciones de menú superior que queremos desplegar.

Si ahora volvéis al ejemplo del doble menú horizontal veréis que automáticamente se muestra la opción 2 (Seires de televisión), teniendo en cuenta que los indices de los arrays en Javascript comienzan en 0

Avisos y consideraciones

No podemos finalizar el texto sin poner de manifiesto que tanto la programación en JavaScript como la hoja de estilos están adaptadas para un menú horizontal de doble nivel. En el caso de menús de mayor profundidad u horientación sería necesario readaptarlo todo a las nuevas situaciones. Este menú nunca pretendió ser la respuesta a todos los menús horizontales, esa es otra batalla, pero esperamos que a alguien le pueda ser útil. En lo referente a la compatibilidad con navegadores, el menú responde a las espectativas de correcta visualización con IE6, IE7, Firefox 2.0.* y Opera 9.* (en WINDOWS XP Prof. SP2).

Sigue leyendo 'Menu horizontal basado en el de Roger Johansson'

Subir

La elegancia del lenguaje

Publicado por Jorge Hoya el 13 mayo 2007, 15:06 - Comentarios comentarios (4)
Etiquetas: ,

En cientos de documentos web se habla sobre la creación de código correcto y las posibles razones para hacerlo. En ellos se intenta dar razones sociales, véase como ejemplo los beneficiones para la accesibilidad, o razones comerciales, como el efecto positivo para la indexación por los motores de búsqueda. Pero hoy, viendo el código de un sencillo documento web, me ha surgido otra posible razón: el ego del programador

Muchas veces, debido a causas ajenas (como pueda ser el apretado tiempo de desarrollo, a los contínuos cambios que se suelen producir una vez comenzado el proceso de desarrollo, etc) o a las propias del programador (vagancia, poco interés, etc) los proyectos que inicialmente cumplían ciertas espectativas acaban siendo 'una merienda de negros' (que nadie malinterprete esta frase hecha).

Una medida para intentar que esto no suceda es hacer ver al programador/maquetador que el código HTML generado habla sobre su personalidad. Cualquiera que haya programado sabe lo que siente al ver el código escrito por otra persona, el experimentar esa sensación de profesor corrigiendo exámenes al revisarlo. Ninguno podemos negar el haber calificado a otro programador o maquetador al ver la calidad de su código (esta es una realidad que he visto en todos los trabajos por los que ido pasando).

Así que desde aquí apelo a ese ser vanidoso que todo programador esconde para que intentemos hacer las cosas mejor, porque se tarda lo mismo en hacerlo mal que en hacerlo bien. Veámoslo con el código que ha motivado este artículo.

El documento en cuestión es un sencillo buscador al que se quiere añadir un pie con más opciones de búsqueda. Este es el código original, usado en el documento, para generar el pie:

<table border="0" width="100%" id="table2" bgcolor="#E3AE64">
  <tr>
	<td colspan="3"><b><font face="Verdana" size="2">Otras búsquedas</font></b></td>
  </tr>
  <tr>
  <td valign="top" width="33%">
	<b><font face="Verdana, Arial, Helvetica, sans-serif" size="1">
	<a class="p" target="_top" xhref="http://www.sitioweb.com/compras/"
mce_href="http://www.sitioweb.com/compras/">
	<span style="background-color: #E3AE64">Compras:<br>
	Coches, Motos, Perros, </span></a></font></b><br>
  </td>
  <td valign="top" width="33%">
	<font face="Verdana, Arial, Helvetica, sans-serif" size="1">
	<b><a class="D" target="_top" 
xhref="http://www.sitioweb.com/directorio" mce_href="http://www.sitioweb.com/directorio">
	<span style="background-color: #E3AE64">
	Buscador de personas:Teléfonos y Direcciones</span>
	</a>
       </b></font><br>
  </td>

  <td valign="top" width="33%">
	<b>	<font face="Verdana, Arial, Helvetica, sans-serif" size="1">
	<a class="D" target="_top" 
xhref="http://www.sitioweb.com" mce_href="http://www.sitioweb.com">
	<span style="background-color: #E3AE64">Catálogo de Libros</span></a></font></b>
  </td>
</tr>
</table>

Este código, en mi modesta opinión, duele con solo mirarlo. A simple vista se aprecia

  • código HTML obsoleto, lo que pudiera indicar esa misma cualidad en el creador
  • falta de eficiencia; imaginad el coste de tiempo y esfuerzo en el caso de tener esa misma tabla con 5 veces más opciones (15 filas) y que se desea cambiar el tipo de fuente en todas ellas.
  • falta de respeto por la estructuración lógica del documento y poco control sobre las diferentes entidades HTML y sus funciones

Alternativas a este código hay tantas como programadores, todas ellas dependiendo contexto donde se enmarque este fragmento de código, de los conocimientos de HTML y CSS. Esta es una de las mias en la que, básicamente, me ocupo del apartado estético:

<style type='text/css'>
#table2{width:100%;background-color:#E3AE64;border:0;}
#table2 td{font-family:Arial,Helvetica,sans-serif;font-size:0.7em;
        font-weight:bold;vertical-align:top; width:33%;}
.tdTit{font-family:Verdana, sans-serif;size:1em;}
.fondo{background-color: #E3AE64}
</style>
<table id="table2">
  <th>
    <td class='tdTit' colspan="3">Otras búsquedas</td>
  </th>
  <tr>
    <td>
 	  <a class="p" target="_top" xhref="http://www.sitioweb.com/compras/">
	  <span class='fondo'>Compras:<br>Coches, Motos, Perros, </span></a>
    </td>
    <td>
      <a class="D" target="_top" xhref="http://www.sitioweb.com/directorio">
      <span class='fondo'>Buscador de personas:Teléfonos y Direcciones</span></a>
    </td>
    <td>
      <a class="D" target="_top" xhref="http://www.sitioweb.com">
      <span class='fondo'>Catálogo de Libros</span></a>
    </td>
  </tr>
</table>

Si a parte de retocar el apartado estético, metemos mano a la estructura lógica del documento, podríamos hacer:

<style type='text/css'>
#table2{width:100%;background-color:#E3AE64;border:0;}
#table2 li{font-family:Arial,Helvetica,sans-serif;
font-size:0.7em;font-weight:bold;vertical-align:top;width:33%;}
#table2 li a{background-color: #E3AE64}
.tdTit{font-family:Verdana, sans-serif;size:1em;}
</style>
<p class='tdTit'>Otras búsquedas</p>
<ul id="table2">
  <li>
    <a class="p" target="_top" 
xhref="http://www.sitioweb.com/compras/">Compras: Coches, Motos, Perros</a>
  </li>
  <li>
    <a class="D" target="_top"
xhref="http://www.sitioweb.com/directorio">
	Buscador de personas: Teléfonos y Direcciones
	</a> 
  </li>

  <li>
    <a class="D" target="_top" 
xhref="http://www.sitioweb.com">Catálogo de Libros</a>
  </li>
</ul>

Como véis, hay tantas posibilidades como maquetadores, sólo he querido mostrar que el hacer bien las cosas o hacerlas mal lleva el mismo tiempo.

Sigue leyendo 'La elegancia del lenguaje'

Subir

Columnas de igual altura usando Javascript

Publicado por Jorge Hoya el 3 agosto 2006, 00:10 - Comentarios comentarios (21)
Etiquetas: ,

Hoy mismo, en el trabajo, un compañero me ha preguntado por el método CSS para hacer que dos divs adyacentes tengan la misma altura. Como siempre, comencé a rascar en lo más hondo de mi cerebro, elucubrar teorías chorra, buscar en Internet, etc para, al final, reconocerle que no tenía ni idea :-(

Estuve leyendo, no mucho tiempo os lo reconozco, sobre si había una propiedad de las hojas de estilo que hiciera esto y no encontré la fórmula mágica que buscaba. Encontraba soluciones utilizando JavaScript pero las desechabamos por la, quizas erronea, idea que el uso de Javascript no es compatible con la creación de páginas accesibles (no estoy del todo seguro de esto pero lo dejaremos para otra charla). Dentro de estas soluciones, otro compañero me remitió al código fuente de la página de inicio personalizada de Google del que os pongo las primeras líneas:

<style>
.modbox .el {display:;}
.modbox .csl, .modbox .es {display:none;}
.modbox_e .el {display:none;}
.modbox_e .csl, .modbox .es {display:;}
.dm {position:relative;width:1px;height:1px;}
.fres {width:expression(_gel("ffresults").offsetWidth+"px");overflow:hidden;}
</style>

Fijaros en la última línea, donde pone: width:expression(). Os lo reconozco, jamás había oido hablar de la utilización de Javascript, dentro de las hojas de estilo, para dar valor a ciertas propiedades (según tengo entendido está disponible desde IE5). Alucinado por el descubrimiento (¿con qué poco me contento, eh?) me decido a probarlo pero descubro que el método en cuestión no me funciona en Firefox y si en IE6.

Levemente decepcionado decido tirar por la calle de enmedio y acabar el proceso aunque sea utilizando Javascript. Y diréis, ¿por qué no utiliza alguna de las soluciones existentes? Y yo os digo, ¿por qué no usar una mia? Tras ver en el ejemplo de Google el uso de la propiedad offsetWidth, supongo que exista la equivalente offsetHeight, [1] y [2], decido crearlas sencillas funciones que se encargarán de igualar la altura de los divs que desee.

La función que se encarga de igualar los divs es altura(), que recibe como argumento los nombre -separados por comas- de los divs a tratar. Ló único que hace es averiguar cual es el div con mayor altura, y ese valor asignarselo a los demás.

 

function altura(){
  al = new Array(); max = 0;
	try{
	  if(document.getElementById){
		  for(i=0;i<arguments.length;i++){
			if(document.getElementById(arguments[i]))
			  al[i] = document.getElementById(arguments[i]).offsetHeight;
		  }
		  max = mayor(al);
		  if(max > 0){
			for(i=0;i<arguments.length;i++){
			  if(document.getElementById(arguments[i]))
				document.getElementById(arguments[i]).style.height = max + 'px';
			  }
		  }
	  }
	}
	catch (exc) {
	  alert("Se ha producido un error en la carga del CSS.");
	  throw exc;
	}
}

Y la función mayor() que calcula el mayor de entre los valores de una array.

 function mayor(datos){  
  salida = 0;  
  for(i=0;i<datos.length;i++){  
	  if(parseInt(datos[i]) > salida )  
	  	  salida = datos[i];  
  }  
  return salida;
}

Un ejemplo del uso de estas funciones sería, para el caso de querer igular dos divs llamados 'izq' y 'der':

<script type='text/javascript'>altura('izq', 'der');</script>

Para los que queráis ver todo esto en acción aquí tenéis un ejemplo


[1] http://msdn.microsoft.com/en-us/library/ms534199(VS.85).aspx
[2] http://developer.mozilla.org/en/docs/DOM:element.offsetHeight

Sigue leyendo 'Columnas de igual altura usando Javascript'

Subir

Detección del navegador con php: checkBrowser

Publicado por Jorge Hoya el 21 junio 2006, 17:34 - Comentarios comentarios (7)
Etiquetas: ,

La detección del navegador que utiliza el usuario viene existiendo desde que el mundo es mundo. La había probado con JavaScript, sin mayor problema, pero nunca en PHP.... hasta ahora.

Para la realización de un proyecto he necesitado de dicha detección del navegador y, como la idea del proyecto es la de respetar lo más posible las pautas de Accesibilidad de la W3C, no debía ser con Javascript. Así que me dije, pués vale, la hago en PHP

Inocente de mi, y debido a que estoy 'mal acostumbrado' por los chicos de php.net, pensé que habría una función que hiciese el trabajo por mi pero me equivoqué. Lo más cercano que tenía, en la documentación de php.net, era la función get_browser() que intenta determinar las capacidades del navegador del usuario. Lo malo de esta función es que necesita tener disponible en el servidor el fichero browscap.ini

Ante este revés no deseperé, navegué por esos mundos de Internet, y no encontré nada que me resolviera la duda. Así qeu obté por fabricarme una ayuda :-) Utilizando un poco de cabeza, algo de expresiones regulares y cierto tiempo llegué a este solución.

La función ha sido comprobada para los siguiente navegadores:

Supongamos que tenemos este Array de cabeceras, reales pero reducidas por motivos de espacio, producidas para lo navegadores antes indicados (fijaros que las claves del Arrays indican el navegador usado en cada uno de los casos):

$Arr_ag = array();
$Arr_ag['firefox'] = 'Mozilla/5.0 (Windows; rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4';
$Arr_ag['msie'] = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0;';
$Arr_ag['opera'] = 'Opera/9.00 (Windows NT 5.0; U; en)';
$Arr_ag['amaya'] = 'amaya/9.51 libwww/5.4.0';
$Arr_ag['maxthon'] = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Maxthon;)';
$Arr_ag['lynx'] = 'Lynx/2.8.3.rel.1 libwww-FM/2.14FM';
$Arr_ag['epiphany'] = 'Mozilla/5.0 (X11; U; Linux686; en-US; rv:1.7.8) Epiphany/1.4.8';
$Arr_ag['galeon'] = 'Mozilla/5.0 (X11; U; Linux686; en-US; rv:1.7.8) Galeon/1.3.20';
$Arr_ag['safari'] = 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/417.9';

Para saber a qué navegador corresponde, aplicamos a cada elemento del Array la función chekcBrowser()

while(list($c,$v) = each($Arr_ag)){
	$tmp[] = checkBrowser($v);
}

Vemos que la salida producida por la detección del navegador, indicada a continuación, corresponde con los valores esperados.

Array
(
    [0] => Firefox/1.5.0.4
    [1] => Msie 6.0
    [2] => Opera/9.00
    [3] => Amaya/9.51
    [4] => Maxthon
    [5] => Lynx/2.8.3.rel.1
    [6] => Epiphany/1.4.8
    [7] => Galeon/1.3.20
    [8] => Applewebkit/417.9
)

El código encargado de la la detección es el siguiente:

function checkBrowser($valor){
	$Arr_c = array('maxthon','msie','firefox','galeon',
	'epiphany','applewebkit','opera','amaya','lynx','mozilla');
	$valor = ' ' . strtolower($valor);
	while(list($c, $v) = each($Arr_c)){
	if(strpos($valor, $v, 0)){return dimeVersion($v, $valor);}
	}
}
function dimeVersion($val, $cadena){
	$pat = '@('.$val.'(.[^ ]*))@i';
	preg_match_all($pat, $cadena, $arg);
	if(isset($arg[0][0])){
		return ucfirst(ereg_replace('(;)', '', $arg[0][0]));
	}
}

Sé que hay tantas soluciones a este problema como gente se haya encontrado con él, sencillamente, esta es la mía :-)

Sigue leyendo 'Detección del navegador con php: checkBrowser'

Subir

Esta semana, en el trabajo, me pasaron un diseño 'sencillo y rápido' que cuanto más miraba más degradados, esquinas redondeadas y 'detallitos varios' veía.

Hasta la fecha las dichosas esquinas las he hecho con imágenes (bien incluyendolas en celdas, como fondo de las mismas, o dentro de algún elemento HTML) pero debido a la cantidad de ellas que tenía el diseño, me decidí por buscar algo en Internet.

Por casualidad, estaba mirando el correo :-) y vi un mensaje en la Lista de Ovillo que hablaba precisamente del tema de las esquinas redondeadas. Entre todos los mensaje unos se decantaban por utilizar imágenes para hacerlas, y CSS para posicionarlas, y otros por CSS y Javascript. Como no veía muy clara la diferencia me puse a leer un rato sobre el tema, y trás un rato, me decanté por este último.

¿Por qué? Porque utilizando el método de las imágenes + CSS tienes que crear un número de imágenes igual a cuatro veces el número de elementos cuyas esquinas quieras redondear. Porque para hacer el posicionamiento, el primero método, utilizaba bastante elementos HTMl 'sin cerrar', produciendo con ello errores en la semántica del documento, como:

	<p class='clase'><b class='clase2'></b></p>

Y, porque después de reflexionar, me acordé que de el método CSS+Javascript ya me había hablado mi gurú personal en esto del CSS y la accesibilidad, Marco Giacomuzzi

El método de creación de esquinas redondeadas con CSS+Javascript ha sido desarrollado por Alessandro Fulciniti y os remito a ella para ver toda la potencia del método. No lo dudéis y visitadla.

A pesar de que os voy a dar un ejemplo sencillo del uso del método de Alessandro, que él llama Nifty Corners, os recomiento encarecidamente que visitéis su web.

En el ejemplo vamos a redondear un div, llamado 'box'. Lo primero que hacemos es declarar el div a redondear:

	<div id="box">
		<h1>Nifty Corners Cube&trade;</h1>
		<p>Se acabaran las ñapas</p>
	</div>

El siguiente paso es incluir la llamada a la función que se encargará del redondeo del div (para ver las opciones visita la página del autor). Recuerda que antes de hacer la llamada, a la función que realiza el redondeo, has de incluir el fichero javascript que con tiene a dicha función, Nifty().

	<script type="text/javascript">
		window.onload=function(){
			Nifty("div#box");
		}
	</script>

Para acabar el proceso, dale un color de fondo al elemento a redondear desde la hoja de estilos.

	div#box{
		width: 18em;
		padding: 20px;
		margin:0 auto;
		background:#FFA509;
		color:#000;
	}

Desde este momento debieras estar viendo un div en medio de la pantalla con las esquinas redondeadas. Si por cualquier motivo no funcionase, verifica que las rutas de los ficheros que se incluyen -requiren- estén bien. Además, has de vigilar que el fichero niftyCorners.CSS esté donde indican las líneas de la función AddCSS(), que tienes en la línea 32 del fichero niftycube.js

Recuerda, con estos tres sencillos pasos has redondeado un elemento HTML:

  1. Creación del elemento a redondear.
  2. Llamada a la función de redondeo, Nifty()
  3. Definición el estilo del elemento a redondear.

Espero que el método os sea tan útil como me ha sido a mi

Sigue leyendo 'Esquinas redondeadas, o como hacer fácil lo dificil'

Subir

  • 1