success stop error data jquery

jquery - stop - Haga clic en disparador en input=archivo en ajax asincrónico hecho()



jquery ajax post (3)

Tengo un formulario con algunos datos y subir. La carga solo se puede iniciar si los datos se recibieron y procesaron correctamente. Para hacer eso, hago una llamada ajax donde

  1. enviar datos,
  2. verifica su resultado,
  3. active un clic () para abrir un cuadro de diálogo de archivo.

Lo último con click () no funciona, ya que parece que la llamada asincrónica bloquea la apertura de una ventana de carga . Solo funciona si configuro async: false .

No puedo encontrar nada en la documentación y en este sitio y quiero saber cuál es el problema allí y cómo hacerlo funcionar manteniendo la llamada asincrónica.

Ejemplo:

$.ajax({ type: "POST", url: "/Save", data: jsonText, dataType: "json", //async: false [1] }).done(function (msg) { $("#upload").click(); }); //$("#upload").click(); [2]

Demostración: http://jsfiddle.net/c2v00uxn/

Nota:

  • si descomento [1] o [2], funciona (el cuadro de diálogo del archivo aparece como se esperaba).
  • reemplazar click () con trigger (''click'') no funciona
  • reemplazar click () con live () / on () no ayuda
  • el control de carga de archivos es visible como por ejemplo (por lo que no se debe a un control oculto)
  • la configuración de tiempo de espera para ajax no ayuda.

ACTUALIZAR

No se trata de cómo hacer un "clic" en general, se trata de cómo hacer clic después de una llamada asíncrona ajax (a partir de ahora, solo funciona con una llamada no asíncrona).


En este momento no es posible abrir una ventana emergente de archivo desde una devolución de llamada asíncrona ajax debido a las características de seguridad recomendadas por w3c en los navegadores.

En el comportamiento de activación del elemento de entrada de archivo, primero verifica si el algoritmo puede mostrar una ventana emergente , si no, entonces aborta los siguientes pasos sin hacer nada más. de w3c.org

Se permite que un algoritmo muestre una ventana emergente si alguna de las siguientes condiciones es verdadera:

  1. La tarea en la que se ejecuta el algoritmo actualmente está procesando un comportamiento de activación cuyo evento de clic fue confiable (eventos confiables: eventos generados por el agente de usuario, ya sea como resultado de la interacción del usuario o como resultado directo de cambios en el DOM, el agente de usuario confía en los privilegios que no se otorgan a los eventos generados por el script a través del método DocumentEvent.createEvent("Event") , modificado mediante el método Event.initEvent() , o enviado a través de EventTarget.dispatchEvent() método. El atributo isTrusted de eventos de confianza tiene un valor de verdadero, mientras que los eventos no confiables tienen un valor de atributo isTrusted de falso. de lo contrario, http://www.w3.org/TR/2012/WD-DOM-Level-3-Events-20120614/#trusted-events ).
  2. La tarea en la que se ejecuta el algoritmo actualmente ejecuta el detector de eventos para un evento confiable cuyo tipo se encuentra en la siguiente lista:

    • cambio
    • hacer clic
    • dblclick
    • mouseup
    • Reiniciar
    • enviar
  3. La tarea en la que se ejecuta el algoritmo fue puesta en cola por un algoritmo al que se le permitió mostrar una ventana emergente, y la cadena de dichos algoritmos comenzó dentro de un marco de tiempo definido por el agente de usuario.

w3c.org

En su código, el usuario no activa el evento de clic, sino que lo activa la devolución de llamada completa de ajax. Aquí el navegador declara que no se puede confiar en el evento para abrir una ventana emergente. En algunos navegadores, puede ver un atributo isTrusted establecido en verdadero si el evento se declara como confiable. https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted

Nota

Diferentes navegadores atrapan la diferencia entre un clic activado por script y un usuario real usando diferentes métodos.

Lo que puede hacer en este escenario es deshabilitar el botón de entrada de archivo (o todo el formulario) y habilitar después de que ajax haya terminado. De esa forma, el usuario no hará clic en el botón de carga hasta que se complete la solicitud de ajax. A partir de ahora no hay otra manera de hacer ambas cosas con un solo clic, ya que también hay un límite de tiempo para abrir una ventana emergente. Cuando revisé en Chrome, el plazo es de 1000 ms. 1000 ms después de la acción del usuario, la ventana no se abrirá.


JQuery dice que el disparador no funcionará para elementos como la carga y el ancla de archivos. (fuente - https://learn.jquery.com/events/triggering-event-handlers/ )

La función .trigger () no se puede usar para imitar eventos nativos del navegador, como hacer clic en un cuadro de entrada de archivo o una etiqueta de anclaje. Esto se debe a que no hay un controlador de eventos adjunto usando el sistema de eventos de jQuery que corresponde a estos eventos.

En ese caso, es posible que deba crear eventos manualmente utilizando las siguientes funciones de JavaScript.

  • document.createEvent
  • event.initMouseEvent
  • element.dispatchEvent

Un código de muestra + definición para las funciones mencionadas anteriormente se puede encontrar en el sitio para desarrolladores de Mozilla

https://developer.mozilla.org/samples/domref/dispatchEvent.html

Tal vez, esto te ayudará.


Tengo una solución que funciona por ahora. Es un truco, por lo que puede no funcionar en el futuro cercano, ya que evita las características de seguridad mencionadas por Tkay anteriormente.

Presento un tiempo de espera que espera a que la solicitud ajax devuelva los datos que quiero verificar antes de iniciar el diálogo del navegador de archivos.

customFileUploadButton.addEventListener(''click'', function(e) { var returnValueToCheck; //Value we want to check against //reference to vanilla JS ajax function that takes callback ajax(function(ajaxData) { returnValueToCheck = ajaxData; }); setTimeout(function() { if (returnValueToCheck !== undefined) { //dummy check for example file.click(); } else { console.log("Criteria not fulfilled"); } }, 1000);//timer should be larger than AJAX timeout });

Para ser honesto, no estoy seguro de por qué exactamente esto funciona, aparte de pasar aparentemente las pruebas específicas del navegador que normalmente prohíben este tipo de comportamiento. Por eso lo considero un hack.

Mi ejemplo es vanilla JS, pero debería ser fácil crear una versión jQuery. Vea este JSFiddle para ver un ejemplo completo.

(Esta es mi primera aventura en contribuir, así que por favor comente sobre posibles errores y descuidos)