Foros del Web » Programando para Internet » Javascript »

Eventos prototipados en elementos HTML

Estas en el tema de Eventos prototipados en elementos HTML en el foro de Javascript en Foros del Web. Veamos... A menudo suelo hacer uso del prototype que proporciona DOM para añadir funciones internas y variables globales de los elementos HTML aparte de las ...
  #1 (permalink)  
Antiguo 28/04/2011, 16:26
 
Fecha de Ingreso: enero-2011
Ubicación: Palma
Mensajes: 49
Antigüedad: 13 años, 4 meses
Puntos: 0
Pregunta Eventos prototipados en elementos HTML

Veamos... A menudo suelo hacer uso del prototype que proporciona DOM para añadir funciones internas y variables globales de los elementos HTML aparte de las nativas. Pues bien, haciendo uso de este método me he encontrado con un caso en el que parece que no actúa cómo se hacía esperar.

Es el caso de los eventos. Supuse que podría declarar eventos sobreescribiendo sus funciones de la siguiente manera (p. ej.):
Código:
HTMLImgElement.prototype.onload = function() { alert('La imagen '+this.alt+' ha sido cargada.') }
Y por lo visto no es así. Lo único que hace JavaScript es crear una función como si fuera nueva, despreciando si es o no la función propia de un evento en particular. (En este caso concreto, se crearía una especie de estándar de carga para todas las imágenes del documento).

¿Sabéis alguna manera de conseguir esto?
  #2 (permalink)  
Antiguo 01/05/2011, 09:46
 
Fecha de Ingreso: enero-2011
Ubicación: Palma
Mensajes: 49
Antigüedad: 13 años, 4 meses
Puntos: 0
Desacuerdo Respuesta: Eventos prototipados en elementos HTML

Como era de esperar: Gracias por la ayuda.
  #3 (permalink)  
Antiguo 01/05/2011, 10:13
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años
Puntos: 834
Respuesta: Eventos prototipados en elementos HTML

En primer lugar, esa forma de extender un objeto DOM es inválida en navegadores como Explorer. En segundo, intenta explicar mejor tu objetivo y recibirás la ayuda adecuada si es que a alguien le interesa dártela, ya que como sabrás, nadie aquí está obligado a responder.
  #4 (permalink)  
Antiguo 01/05/2011, 10:18
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: Eventos prototipados en elementos HTML

buenas mikeliu...

¡no seas necio! ¿crees que nadie ha leido el tema? nada mas mira el numero de visitas. yo fui uno de los primeros en leer el tema y desgraciadamente no te puedo responder como es debido porque no encuentro una solucion. de hecho, me tomo por sorpresa que no funcionara con el prototipo de la clase del elemento. de momento, la unica explicacion que encuentro es que los elementos no heredan los eventos desde su propia clase sino desde otro constructor. ¿cual? aun no lo se.
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #5 (permalink)  
Antiguo 01/05/2011, 14:30
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años
Puntos: 834
Respuesta: Eventos prototipados en elementos HTML

Lo que sucede es que HTMLImageElement (no HTMLImgElement) no es un objeto javascript normal (nativo o definido por el usuario) sino un objeto de tipo host (los objetos pueden ser nativos, host o definidos por el usuario). Los objetos de tipo host no tienen la obligación de comportarse como objetos normales y depende de cada navegador la forma de implementarlos. Por eso es una pésima idea alterar su prototipo. Este enlace quizá pueda dar una idea más clara acerca de esto: http://perfectionkills.com/whats-wro...nding-the-dom/
  #6 (permalink)  
Antiguo 01/05/2011, 15:20
Avatar de IsaBelM
Colaborador
 
Fecha de Ingreso: junio-2008
Mensajes: 5.032
Antigüedad: 15 años, 10 meses
Puntos: 1012
Respuesta: Eventos prototipados en elementos HTML

aunque ya lo ha dicho panino , pero como me ha llevado casi que una hora en encontrar una respuesta por que busca por el término HTMLImageElement, la publico
Cita:
Modifying the prototype of a Host object is not guaranteed by ECMAScript specification. Moreover, no specification guarantees that there will be a globally available HTMLImageElement, or that such object will be the constructor for any arbitrary image's [[Prototype]].
referencia
  #7 (permalink)  
Antiguo 02/05/2011, 05:34
Avatar de _cronos2
Colaborador
 
Fecha de Ingreso: junio-2010
Mensajes: 2.062
Antigüedad: 13 años, 10 meses
Puntos: 310
Respuesta: Eventos prototipados en elementos HTML

Cita:
Iniciado por Panino5001 Ver Mensaje
Lo que sucede es que HTMLImageElement (no HTMLImgElement) no es un objeto javascript normal (nativo o definido por el usuario) sino un objeto de tipo host (los objetos pueden ser nativos, host o definidos por el usuario). Los objetos de tipo host no tienen la obligación de comportarse como objetos normales y depende de cada navegador la forma de implementarlos. Por eso es una pésima idea alterar su prototipo. Este enlace quizá pueda dar una idea más clara acerca de esto: http://perfectionkills.com/whats-wro...nding-the-dom/
Qué buen link @Panino! Sin embargo no entendí eso de:
Cita:
One of the most common alternatives to this whole mess of DOM extension is object wrappers. This is the approach jQuery has taken from the start, and few other libraries followed later on. The idea is simple. Instead of extending elements or events directly, create a wrapper around them, and delegate methods accordingly. No collisions, no need to deal with host objects madness, easier to manage leaks and operate in dysfunctional MSHTML DOM, better performance, saner maintenance and painless scaling.

And you still avoid procedural approach.

Saludos (:
__________________
" Getting older’s not been on my plans
but it’s never late, it’s never late enough for me to stay. "
Cigarettes - Russian Red
  #8 (permalink)  
Antiguo 02/05/2011, 06:14
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 3 meses
Puntos: 845
Respuesta: Eventos prototipados en elementos HTML

mmm, lo que esta diciendo es que en vez de extender, utilices el patrón Adapter/Wrapper, es la base de jQuery junto con Composite y Facade.

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #9 (permalink)  
Antiguo 02/05/2011, 07:33
Avatar de _cronos2
Colaborador
 
Fecha de Ingreso: junio-2010
Mensajes: 2.062
Antigüedad: 13 años, 10 meses
Puntos: 310
Respuesta: Eventos prototipados en elementos HTML

Cita:
Iniciado por masterpuppet Ver Mensaje
mmm, lo que esta diciendo es que en vez de extender, utilices el patrón Adapter/Wrapper, es la base de jQuery junto con Composite y Facade.

Saludos.
Gracias por los links, pero si ya me suele costar entender a la Wikipedia en español, imagínate en inglés Estuve buscando y lo que encontré fue esto mismo para Java, un par de sitios que decían que el objeto String era un wrapper para los strings, y un post de Ben Nadel sobre un problema que tuvo con window y jQuery XD
Saludos (:
__________________
" Getting older’s not been on my plans
but it’s never late, it’s never late enough for me to stay. "
Cigarettes - Russian Red
  #10 (permalink)  
Antiguo 02/05/2011, 08:04
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años
Puntos: 834
Respuesta: Eventos prototipados en elementos HTML

En tu framework vos lo que hacés es tomar un elemento dom y pasarlo por un bucle para agregarle métodos y propiedades copiados de un objeto plantilla. En lugar de eso, la idea es crear un objeto envoltorio, del cual el objeto DOM sea un propiedad o se obtenga con un getObjetoDom, y en lugar de extender el objeto DOM extiendas su envoltorio, invocando al objeto DOM sólo cuando sea necesario. Por ejemplo, cuando creás el método addEvent, en lugar de hacer referencia a this, harías referencia a this.getObjetoDom. Hay que tener cuidado con eso y hay que saber bien lo que uno está haciendo porque es muy fácil crear referencias circulares entre el mundo de los objetos DOM y el mundo de los objetos javascript, cosa que puede redundar en problemas de memoria (jQuery los tuvo y los fue solucionando).
  #11 (permalink)  
Antiguo 02/05/2011, 11:08
Avatar de _cronos2
Colaborador
 
Fecha de Ingreso: junio-2010
Mensajes: 2.062
Antigüedad: 13 años, 10 meses
Puntos: 310
Respuesta: Eventos prototipados en elementos HTML

Eerm, bueno gracias, espero poder entender todo esto dentro de un par de años
Saludos (:
__________________
" Getting older’s not been on my plans
but it’s never late, it’s never late enough for me to stay. "
Cigarettes - Russian Red
  #12 (permalink)  
Antiguo 02/05/2011, 11:47
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años
Puntos: 834
Respuesta: Eventos prototipados en elementos HTML

Con esto te darás cuenta:
Código PHP:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html xmlns="http://www.w3.org/1999/xhtml">
<
head>
<
meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<
title>Documento sin t&#237;tulo</title>
<script type="text/javascript">
var 
pp=(function(){
/* ---- métodos privados ---- */
    
var extendidos={};
    var 
metodosPrivados={
         
css:function(propiedad,valor){
             if(!
valor)
                return 
this[0].style[propiedad];
            
this[0].style[propiedad]=valor;
            return 
this;
         },
         
addEvent: function(typefn ) {
            if ( 
this[0].addEventListener ) {
                
this[0].addEventListenertypefnfalse );
            } else if(
this[0].attachEvent){
                var 
_this=this[0];
                var 
f= function(){fn.call(_this,window.event);}
                
this[0].attachEvent'on'+typef);
                
this[0][fn.toString()+type]=f;
            }else{
                
this[0]['on'+type]=fn;
            }
            var 
ev={_obj:this[0],_evType:type,_fn:fn};
            
window.EvRegister=window.EvRegister || [];
            
window.EvRegister.push(ev);
            return 
this;
        }
    };
/* ---- métodos públicos ---- */
    
return{
        
extend:function(el,obj){
            if( 
extendidos.hasOwnProperty(el[0]) && el!=metodosPrivados )return extendidos[el[0]];
            for(var 
i in obj)
                
el[i]=obj[i];
            
extendidos[el[0]]=el;
            return 
el;
        },
        
get:function(id){
            if(!
document.getElementById(id))return false;
            var 
el=[];//wrapper
            
el[0]=document.getElementById(id);
            return 
pp.extend(el,metodosPrivados);
        }
        
    }    
})();
var $=
pp.get;
onload=function(){
   $(
'algo').css('cursor','pointer').css('background','red').addEvent('click',function(){alert(this.id);});
   $(
'algo').css('color','#FFF');
}
</script>

</head>

<body>
<div id="algo">test</div>
</body>
</html> 
Si ahora intentás hacer algo como esto:
Código PHP:
document.getElementById('algo').css('color','#FFF');//error 
obtendrás un error ya que css no es un método añadido al elemento DOM (host object) sino a su wrapper (objeto definido por usuario que tiene al objeto DOM como uno de sus miembros)

Última edición por Panino5001; 02/05/2011 a las 12:43
  #13 (permalink)  
Antiguo 02/05/2011, 12:10
Avatar de _cronos2
Colaborador
 
Fecha de Ingreso: junio-2010
Mensajes: 2.062
Antigüedad: 13 años, 10 meses
Puntos: 310
Respuesta: Eventos prototipados en elementos HTML

Ok, pero, ¿qué ventajas tiene hacerlo así? O sea, ¿cuál es la diferencia entre hacerlo como lo hago yo y de esta manera?
Eso es lo que no entiendo
Saludos (:
__________________
" Getting older’s not been on my plans
but it’s never late, it’s never late enough for me to stay. "
Cigarettes - Russian Red
  #14 (permalink)  
Antiguo 02/05/2011, 12:24
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años
Puntos: 834
Respuesta: Eventos prototipados en elementos HTML

La ventaja es que si el día de mañana Firefox decide que lo que un elemento DOM (como por ejemplo el retorno de document.getElementById) ya no sea de tipo object, cosa que puede hacer tranquilamente sin salir de lo indicado por los estandares ecma y w3c, igualmente en ese caso tu framework seguiría funcionando si usaste un wrapper. También si en el futuro la w3c crea un método llamado css para los objetos DOM, tu framework seguiría funcionando sin problemas sin que sobreescribas un método nativo, cosa que ya pasó con algunos frameworks y getElementByClass.

Última edición por Panino5001; 02/05/2011 a las 12:45
  #15 (permalink)  
Antiguo 02/05/2011, 13:03
Avatar de _cronos2
Colaborador
 
Fecha de Ingreso: junio-2010
Mensajes: 2.062
Antigüedad: 13 años, 10 meses
Puntos: 310
Respuesta: Eventos prototipados en elementos HTML

Ok, ahora sí, muchas gracias por la explicación (:
__________________
" Getting older’s not been on my plans
but it’s never late, it’s never late enough for me to stay. "
Cigarettes - Russian Red
  #16 (permalink)  
Antiguo 05/05/2011, 15:25
 
Fecha de Ingreso: enero-2011
Ubicación: Palma
Mensajes: 49
Antigüedad: 13 años, 4 meses
Puntos: 0
Pregunta Respuesta: Eventos prototipados en elementos HTML

Cita:
Iniciado por Panino5001 Ver Mensaje
...intenta explicar mejor tu objetivo y recibirás la ayuda adecuada...
¿Qué es lo que no has entendido?
  #17 (permalink)  
Antiguo 05/05/2011, 15:29
 
Fecha de Ingreso: enero-2011
Ubicación: Palma
Mensajes: 49
Antigüedad: 13 años, 4 meses
Puntos: 0
Respuesta: Eventos prototipados en elementos HTML

Gracias por las respuestas.

Lo de la imagen era sólo un pequeño ejemplo. Lo que intentaba era ahorrarme el trabajo de ir objeto tras objeto (del elemento que fuera) declarando eventos y propiedades, cuando podría ahorrármelo definiendo tan sólo la propia clase DOM, pero veo que no es posible. Una lástima.

Etiquetas: elementos, eventos, html
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 03:00.