2010-01-12 11 views
7

Tengo un formulario con un atributo onsubmit. Necesito vincular un nuevo evento de envío y necesito que este se ejecute antes de cualquier función de envío existente.¿Es posible vincular una función submit() antes de cualquier envío/envío existente?

El siguiente código demuestra el problema.

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <title>Test</title> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
    <script type="text/javascript"> 
     jQuery(function($) { 
     // a plugin 
     $('form').submit(function() { 
      alert("Second"); 
     }); 
     // an other plugin 
     $('form').submit(function() { 
      alert("Third"); 
     }); 

     // this event must always be executed as first event 
     $('form').submit(function() { 
      alert("Always First"); 
     }); 
     }); 
    </script> 
    </head> 
    <body> 
    <form onsubmit="javascript:alert('Fourth');"> 
     <p> 
     <input type="submit"> 
     </p> 
    </form> 
    </body> 
</html> 

Si ejecuta el script, primero obtendrá "Segundo", luego "Primero".

¿Es posible vincular un nuevo evento de envío y especificar si se debe invocar la función antes de cualquier evento existente?

Restricciones:

  • eventos existentes deben ser preservados.
  • no puede eliminar eventos existentes debido a que el contenido del atributo onsubmit contiene una lógica bastante complejo escrito por rieles
  • (Añadido): el evento siempre debe ser ejecutado antes de cualquier evento onsubmit existente y eventos ya binded (quizás binded por otro complemento)

¿Alguna idea?

Respuesta

14

La línea presentar activa el evento de primera, se puede obtener una referencia a él, anular el atributo onsubmit en el elemento form, y luego unirse a su nuevo evento presentará, éste se ejecutará su edad presentar manejador:

jQuery(function($) { 
    var form = $('form'), oldSubmit = form[0].onsubmit; 
    form[0].onsubmit = null; 

    $('form').submit(function() { 
     alert("First"); 
     oldSubmit.call(this); // preserve the context 
    }); 
    }); 

Nota que utilizo el método call para invocar el controlador de presentar de edad, esto es para preservar la palabra clave this dentro de esa función, será el elemento form sí.

Si el controlador original de onsubmit tiene un comportamiento de validación, puede obtener su valor de retorno por var ret = oldSubmit.call(this);

Comprobar el ejemplo anterior here.

+0

Esta solución funciona genial. Me olvidé de mencionar que otros complementos ya podrían haber agrupado otros eventos en la misma forma. ¿Es posible enlazar el evento antes de cualquier evento onsubmit/binded? Intenté usar unbind/bind (también leyendo la implementación de la función clon) pero no pude obtener una solución razonable. –

+0

Puede probar la función die() ya que muchos complementos usan live() para capturar el evento submit. http://api.jquery.com/live/ – xijo

3

Tome el controlador existente submit y guárdelo en una variable.

Luego en su nuevo controlador, llame a la función que almacenó desde el controlador anterior submit, y vuelva a asignar su nuevo al oyente.

Ejemplo:

jQuery(function($) { 

    $('form').submit(function() { 
     var first = this.onsubmit; 
     //... 
     first.call(this); 
    }); 
    }); 

... o algo por el estilo. : =)

+0

'unbind' no funcionará para eliminar el controlador de eventos' onsubmit' en línea, y el enfoque del constructor 'Function' podría no funcionar en algunos navegadores ya que depende del método' Function.prototype.toString', (para pasa el argumento 'functionBody' como String) ese método depende de la implementación, creo que es más seguro usar referencias y evitar el * evaling * hecho por el constructor' Function' – CMS

+2

Confirmo que la desvinculación no funciona. –

0

Creo que this es una forma mejor si funciona correctamente porque el OP lo ha aceptado.

Cuestiones relacionadas