Ver Mensaje Individual
  #6 (permalink)  
Antiguo 08/10/2011, 11:04
Avatar de Panino5001
Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años, 6 meses
Puntos: 834
Respuesta: Extender elementos de formulario

Cita:
Iniciado por h2swider Ver Mensaje
No es posibles extender nativos en JS. :)
Sí y no. Depende. Primera aclaración: los objetos que supuestamente no se pueden extender son los objetos host (document, window, frames. etc). Los objetos nativos (Date, Math, etc) pueden extenderse modificando su prototipo (prototype) sin problemas si uno sabe lo que hace.
Los objetos host pueden extenderse de varias maneras, algunas más correctas que otras. Algunos navegadores permiten modificar su prototipo, para otros ni siquiera tienen prototipo (y ambas posturas son correctas de acuerdo al estandar, ya que no es necesario que respondan a las características de los objetos tradicionales javascript).
Una manera un tanto incorrecta de extender objetos host sería esta:
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>Untitled Document</title>
<
script type="text/javascript">

var 
ej=(
    function(){
        var 
mp={
            
addEvent: function(typefn ) {
            if ( 
this.addEventListener ) {
                
this.addEventListenertypefnfalse );
            } else if(
this.attachEvent){
                var 
_this=this;
                var 
f= function(){fn.call(_this,window.event);}
                
this.attachEvent'on'+typef);
            }else{
                throw new 
Error('Estás navegando en una balsa agujereada: es hora de cambiar de navegador!');
            }
            return 
this;
            },
            
customFocus:function(){
                
this.style.background='pink';
                return 
this;
            },
            
customBlur:function(){
                
this.style.background='white';
                return 
this;
            },
            
extendido:1
            
        
};
        return {
            
extend:function(el,obj){
                if(
el.extendido && el!=mp)return el;
                for(var 
i in obj)
                    
el[i]=obj[i];
                return 
el;
            },
            
get:function(id){
                if(!
document.getElementById(id))return false;
                return 
ej.extend(document.getElementById(id),mp);
            },
            
geto:function(obj){
                return 
ej.extend(obj,mp);
            }
        };
    }    
)();
var $=
ej.get,_$=ej.geto;
_$(window).addEvent('load',function(){$('pp').addEvent('focus',function(){this.customFocus();}).addEvent('blur',function(){this.customBlur();});});
</script>
</head>

<body>
<form action="" method="get">
<input id="pp" name="" type="text" />
</form>
</body>
</html> 
Es un tanto incorrecta porque agrega métodos y propiedades a objetos host aprovechando que se comportan como un objeto javascript Object, pero el problema es que aunque ahora funciona en todos los navegadores, esto puede cambiar en el futuro y además puede ocasionar cconflictos y problemas de rendimiento si no se sabe muy bien lo que se hace. No obstante esto, Frameworks conocidos utilizan esta técnica.

Una mejor aproximación es usar un wrapper: envolver el objeto host en otro. Ese objeto envoltorio es el que tiene las propiedades y métodos que extienden de manera indirecta las propiedades del objeto host. Pero la ventaja es que nunca se agrega nada al objeto host: el que hace todo el trabajo es el wrapper:
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>Untitled Document</title>
<
script type="text/javascript">

var 
ej=(
    function(){
        var 
extendidos={};
        var 
mp={
            
addEvent: function(typefn ) {
                var 
_this=this;
                if ( 
this[0].addEventListener ) {
                    var 
f= function(){fn.call(_this);};
                    
this[0].addEventListenertypeffalse );
                } else if(
this[0].attachEvent){
                    var 
f= function(){fn.call(_this,window.event);};
                    
this[0].attachEvent'on'+typef);
                }else{
                    throw new 
Error('Estás navegando en una balsa agujereada: es hora de cambiar de navegador!');
                }
                return 
this;
            },
            
customFocus:function(){
                
this[0].style.background='pink';
                return 
this;
            },
            
customBlur:function(){
                
this[0].style.background='white';
                return 
this;
            }
            
        };
        return {
            
extend:function(el,obj){
                if(
el[0]!==document && el!==mp){
                    
el[0].id=el[0].id || '____'+(+new Date())+Math.random();
                }
                if( 
el!==mp && extendidos.hasOwnProperty(el[0].id || 'document'))
                    return 
extendidos[(el[0].id || 'document')];    
                for(var 
i in obj)
                    
el[i]=obj[i];
                if(
el!==mp)
                    
extendidos[(el[0].id || 'document')]=el;
                return 
el;
            },
            
get:function(id){
                if(!
document.getElementById(id))
                    return 
false;
                var 
el=[];
                
el[0]=document.getElementById(id);
                return 
ej.extend(el,mp);
            },
            
geto:function(obj){
                var 
el=[];
                
el[0]=obj;
                return 
ej.extend(el,mp);
            }
        };
    }    
)();
var $=
ej.get,_$=ej.geto;
_$(window).addEvent('load',function(){$('pp').addEvent('focus',function(){this.customFocus();}).addEvent('blur',function(){this.customBlur();});});
</script>
</head>

<body>
<form action="" method="get">
<input id="pp" name="" type="text" />
</form>
</body>
</html> 
Son sólo ejemplos. Hay que agregar varias optimizaciones para poder usarlos en un ambiente real.