Posts tagged JavaScript
jQuery: .css(“background-position”) falla en Internet Explorer
1Me iba a poner a explicar porque falla y todo lo que tuve que hacer hasta darme cuenta del problema y la forma de solucionarlo, pero prefiero por esta vez simplemente dejarles la función que hice para arreglar el problema:
El siguiente método se acopla a jQuery por lo que lo pueden cargar justo después de jQuery y usarlo normalmente.
/**
* Devuelve un array con la posicion X e Y respectivamente.
*/
$.fn.bgPosition = function() {
var bgp = "background-position";
return $.browser.msie ? [parseInt($(this).css(bgp + "-x").split(" ")[0]), parseInt($(this).css(bgp + "-y").split(" ")[0])] : [parseInt($(this).css(bgp).split(" ")[0]), parseInt($(this).css(bgp).split(" ")[1])];
}
Y como mencione, el uso es bastante sencillo.
//Para usarlo:
alert("las posiciónes X e Y del fondo son: " + $("#cajaConFondo").bgPosition()); //muestra [posX, posY]
alert("La posición X del fondo es: " + $("#cajaConFondo").bgPosition()[0]); //muestra posX
alert("La posición Y del fondo es: " + $("#cajaConFondo").bgPosition()[1]); //muestra posY
Para cerrar el post el problema en resumen es que internet explorer no reconoce la propiedad “background-position” del metodo .css(). En su lugar hay que usar “background-position-x” y “background-position-y”
Y una cosita mas: el método solo funciona con pixeles porque es lo que me hacía falta, porcentajes y demases yerbas quedan excluidas salvo que alguien quiera aportar esa parte
Drupal: Porque usar Drupal.behaviors en lugar de $(document).ready();
2Durante mucho tiempo estuve usando $(document).ready(); para poner mi js en Drupal, y funcionaba la mar de bien. Esto me permitía ejecutar javascript inmediatamente después que el DOM estuviera cargado evitando así errores de referencias a objetos que todavía no existieran al querer manipularlos.
Ahora bien, hay un problema que vamos a encontrar por medio de un ejemplo simple:
Si tuviéramos un listado de nodos y a ese listado hiciéramos que al pinchar sobre sus enlaces hiciera un alert de su atributo “title” usando jQuery:
jQuery(document).ready(function($) {
$("#listado_de_nodos a").click(function(e) {
alert($(this).attr("title"));
});
});
¿Qué pasa si por medio de AJAX se agregaran nuevos nodos? te lo digo, que no reaccionarían al hacer click sobre ellos, y es por que el método .click() de jQuery se ejecuta una sola vez en busca de elementos que macheen con su criterio y una vez finalizado ya está, no hace mas. Es un comportamiento de lo mas entendible ya que imaginemos que estuviera escaneando constantemente por nuevos elementos ese selector mas los otros 50 que estemos usando para hacer mas cosas…. Google Chrome lo soportaría sin apenas darle carga al procesador y RAM, pero piensen en la basura de IE…..
Perdonen que me vaya por las ramas, como les decía, dado el problema que se planteo para el listado de nodos que di como ejemplo, se implemento una solucion (bueno cubre mas problemas pero este es de los mas comunes) la solución fue usar al objeto Drupal.behaviors a modo de controlador. Drupal.behaviors relanza todas las funciones que almacena por cada vez que se lance una petición AJAX, dándonos la oportunidad de re procesar cosas. Así pues en el ejemplo anterior lo podemos poner dentro de un behavior para poder aplicar nuestra funcionalidad incluso a los nuevos elementos provenientes de la petición:
Drupal.behaviors.alertarEnlaces = function(context) {
$("#listado_de_nodos a").click(function(e) {
alert($(this).attr("title"));
});
}
Como ven lo único que hay que reemplazar en nuestros actuales ficheros de javascript es jQuery(document).ready(function($) {}) por Drupal.behaviors.alertarEnlaces = function(context) {} y no se preocupen por el hecho de que su código este ahora asignado dentro de una función(“Drupal.behaviors.alertarEnlace() ”), porque esta se ejecuta solita, y veanlo incluso como una ventaja, pueden invocarla ustedes mismos cuando quieran ademas.
jQuery.height() calcula distintos tamaños entre navegadores [solución]
0Este es un tip rápido pero útil.
Escenario:
Tenes un div con el id “elDiv” con el siguiente CSS:
#elDiv {
border: 1px solid #336699;
float: right;
padding: 20px;
width: 500px;
}
Y en Firefox/Chrome/Safari/Opera al hacer $(“#elDiv”).height(); te entrega 400px por decir algo (el tamaño depende de lo que tenga dentro).
Pero curiosamente en Internet explorer te da un tamaño raro… de menos, unos 358px en nuestro ejemplo.
¿Qué pasa?
Pasa que no le especificaste un modo de renderizado al HTML por medio del DOCTYPE, y por culpa de ello Internet explorer va a renderizar el contenido en modo “Quirks Mode” http://es.wikipedia.org/wiki/Quirks_Mode.
Si no queres leer el articulo de Wikipedia te comento que lo único que tenes que hacer es poner lo siguiente por encima del tag <html>:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/DTD/strict.dtd">
PD: el valor de 358px en mi ejemplo viene de que en modo quirks, IE toma el tamaño del tamaño real menos el padding y el borde: 400 – 40 – 2 = 358.
JS: Como saber si un objeto undefined está undefined
0Suena a boludez:
if (objetoso == undefined) {
alert("objetoso no está definido.");
}
Pero lo anterior no te va a funcionar porque al querer comparar un objeto que está indefinido, el navegador va a arrojarte un error :S
La forma correcta de hacer esta comprobación entonces es:
if (typeof(objetoso) === "undefined") {
alert("objetoso no está definido.");
}
Y ya nos evitamos que se rompa todo por culpa de un objeto indefinido…
Bye.
