2011-10-11 14 views
35

Esta pregunta tiene el propósito de desarrollar complementos de jQuery y otros fragmentos de código JavaScript independientes que no requieren la modificación de otros archivos de guiones para garantizar la compatibilidad.¿Existe una forma [universal] de invocar una acción predeterminada después de llamar a event.preventDefault()?

Todos sabemos que event.preventDefault() evitará el evento predeterminado para que podamos ejecutar una función personalizada. Pero, ¿y si queremos simplemente demorar el evento predeterminado antes de invocarlo? He visto varios trucos ninja específicos de casos y soluciones para volver a invocar la acción predeterminada, pero como dije, mi interés está en una forma universal de volver a activar el valor predeterminado, y no tratar los desencadenantes predeterminados en un caso- por caso.

$(submitButton).click(function (e) { 

    e.preventDefault(); 

    // Do custom code here. 

    e.invokeDefault(); // Imaginary... :(
}); 

Incluso para algo tan simple como el envío de formularios, parece que no hay una respuesta universal. La solución $(selector).closest("form").submit() supone que la acción predeterminada es un envío de formulario estándar y no es algo raro como una función __doPostBack() en ASP.NET. Para el final de la invocación de devoluciones de llamada ASP.NET, esto es lo más cerca que he llegado a una solución universal, set-él-y-olvidar-es:

$(submitButton).click(function (e) { 

    e.preventDefault(); 

    // Do custom code here. 

    var javascriptCommand = e.currentTarget.attributes.href.nodeValue; 
    evalLinkJs(javascriptCommand); 
}); 


function evalLinkJs(link) { 
    // Eat it, Crockford. :) 
    eval(link.replace(/^javascript:/g, "")); 
} 

supongo que podría empezar a escribir casos especiales para manejar enlaces normales con un redireccionamiento window.location, pero luego estamos abriendo una nueva lata de gusanos: acumular más y más casos para la invocación de eventos predeterminados crea más problemas que las soluciones.

¿Qué tal? ¿Quién tiene la bala mágica que he estado buscando?

+1

Realmente no entiendo lo que estás tratando de hacer ... no lo hace el evento código de controlador ejecute * antes * la acción predeterminada ocurre (por ejemplo, se ejecutará un código del controlador de evento 'submit' antes de que se envíe el formulario ... ¿no es eso lo que intenta lograr?) –

+2

¿Su código personalizado es asincrónico? esto podría explicar por qué sientes que necesitas tal método, pero incluso tener ese método imaginario no resolverá tu problema. – agradl

+1

Definitivamente debe ser más claro sobre lo que quiere. Si desea ejecutar código dentro del controlador, ese código se ejecuta antes del comportamiento "predeterminado" de todos modos. –

Respuesta

8

Tome un vistazo a esto:

Usted podría intentar

if(!event.mySecretVariableName) { 
    event.preventDefault(); 
} else { 
    return; // do nothing, let the event go 
} 

// your handling code goes here 
event.originalEvent.mySecretVariableName = "i handled it"; 

if (document.createEvent) { 
    this.dispatchEvent(event.originalEvent); 
} else { 
    this.fireEvent(event.originalEvent.eventType, event.originalEvent); 
} 

Usando esta respuesta: How to trigger event in JavaScript? y la referencia de evento jQuery: http://api.jquery.com/category/events/event-object/

Tag objeto de evento que usted recibe por lo que si recíbalo de nuevo, no lo hagas.

1

No es posible, como JamWaffles ya ha demostrado. Explicación simple de por qué es imposible: si vuelves a disparar la acción predeterminada, tu oyente de eventos interceptará nuevamente y tendrás un ciclo infinito.

Y esto

click(function (e) { 
    e.preventDefault(); 
    // Do custom code here. 
    e.invokeDefault(); // Imaginary... :(
}); 

es lo mismo como esto (con su función imaginaria).

click(function (e) { 
    // Do custom code here. 
}); 

Parece que desea manipular la url de su elemento cliqueado. Si lo haces así, simplemente funciona bien. Example.

5

En primer lugar, no llame al preventDefault(). Entonces la acción predeterminada ocurrirá después de su controlador de eventos.

+9

Este es el respuesta correcta siempre que no necesite realizar el manejo predeterminado de forma asincrónica después de su manejo personalizado. – Jacob

4

Esto debería funcionar. Aunque solo he probado en Firefox.

<html> 
<head> 
<script> 
    window.addEventListener("click",handleClick,false); 
    function handleClick(e){ 
     if (e.useDefault != true){ 
      alert("we're preventing"); 
      e.preventDefault(); 
      alert(e.screenX); 
      //Firing the regular action 
      var evt = document.createEvent("HTMLEvents"); 
      evt.initEvent(e.type,e.bubbles,e.cancelable); 
      evt["useDefault"] = true; 
      //Add other "e" attributes like screenX, pageX, etc... 
      this.dispatchEvent(evt); 
     } 
     else{ 
      alert("we're not preventing"); 
     } 
    } 
</script> 
</head> 
<body> 

</body> 
</html> 

Por supuesto, también debe copiar todos los atributos de las variables de eventos anteriores. Simplemente no codifiqué esa parte, pero debería ser lo suficientemente fácil.

+2

+1 Este es el enfoque correcto. Debe intentar crear el tipo correcto de evento; consulte https://developer.mozilla.org/en-US/docs/DOM/document.createEvent – chowey

0

que necesitaba para desactivar un botón después de clic y luego disparar el evento predeterminado, esto es mi solución

$(document).on('click', '.disabled-after-submit', function(event) { 
    event.preventDefault(); 
    $(event.currentTarget).addClass('disabled'); 
    $(event.currentTarget).removeClass('disabled-after-submit'); 
    $(event.currentTarget).click(); 
    $(event.currentTarget).prop('disabled', true); 
}); 
Cuestiones relacionadas