2009-08-06 18 views
8

Estoy tratando de retrasar el evento predeterminado o eventos en un script jQuery. El contexto es que quiero mostrar un mensaje a los usuarios cuando realizan ciertas acciones (haga clic principalmente) durante unos segundos antes de que se active la acción predeterminada.Suspender evento predeterminado en jQuery

pseudo-código: - El usuario hace clic elemento botón de enlace// - El usuario recibe un mensaje emergente que indica 'Usted está saliendo de sitio' - mensaje permanece en la pantalla de X milisegundos - La acción por defecto (puede ser otro que el href enlace también) dispara

hasta ahora, mis intentos se ven así:

$(document).ready(function() { 
    var orgE = $("a").click(); 
    $("a").click(function(event) { 
     var orgEvent = event; 
     event.preventDefault(); 
     // Do stuff 
     doStuff(this); 

     setTimeout(function() { 
      // Hide message 
      hideMessage(); 
      $(this).trigger(orgEvent); 
     }, 1000); 
    }); 
}); 

Por supuesto, esto no funciona como se esperaba, pero pueden mostrar lo que estoy tratando de hacer.

No puedo usar complementos ya que este es un entorno alojado sin acceso en línea.

¿Alguna idea?

Respuesta

-2

Esto podría funcionar:

$(document).ready(function() { 
    $("a").click(function(event) { 
    event.preventDefault(); 
    doStuff(this); 

    setTimeout(function() { 
     hideMessage(); 
     $(this).click(); 
    }, 1000); 
    }); 
}); 

Nota: no probado totalmente

+1

¿No volvería a disparar el mismo controlador de clic, incluido el 'event.preventDefault'? – DLH

+0

No funcionará ya que este contexto será la ventana y no el ancla – redsquare

+0

necesita tomar una referencia al delimitador y usar eso dentro de setTimeout. Sin embargo sí, resultaría en un ciclo infinito. Debería desvincular el evento click para que no se ejecute. – redsquare

5

que probablemente hacer algo como esto.

$("a").click(function(event) { 
    event.preventDefault(); 
    doStuff(this); 
    var url = $(this).attr("href"); 

    setTimeout(function() { 
     hideMessage(); 
     window.location = url; 
    }, 1000); 
}); 

no estoy seguro de si url se puede ver desde el interior de la función temporizada. De lo contrario, es posible que deba declararlo fuera del controlador de clics.

Editar: Si necesita desencadenar el evento de la función de tiempo, podría utilizar algo similar a lo que sugiere karim79, aunque haría algunos cambios.

$(document).ready(function() { 
    var slept = false; 
    $("a").click(function(event) { 
    if(!slept) { 
     event.preventDefault(); 
     doStuff(this); 

     var $element = $(this); 
     // allows us to access this object from inside the function 

     setTimeout(function() { 
      hideMessage(); 
      slept = true; 
      $element.click(); //triggers the click event with slept = true 
     }, 1000); 
     // if we triggered the click event here, it would loop through 
     // this function recursively until slept was false. we don't want that. 
    } else { 
     slept = false; //re-initialize 
    } 
    }); 
}); 

Editar: Después de algunas pruebas y la investigación, no estoy seguro de que en realidad es posible disparar el evento click original de un elemento <a>. Parece ser posible para cualquier elemento que no sea <a>.

+0

Puede leer la var. – redsquare

+0

El problema con este enfoque es que no sé si la acción original es ir a una URL. Puede ser simplemente otra función de JavaScript que no tiene nada que ver con la navegación. –

2

Algo como esto debería hacer el truco. Agregue una nueva clase (presumiblemente con un nombre más sensato que el que he elegido) a todos los enlaces que desee que se vean afectados. Elimine esa clase cuando haya mostrado su ventana emergente, de modo que cuando vuelva a llamar a .click(), su código ya no se ejecutará y se producirá el comportamiento predeterminado.

$("a").addClass("fancy-schmancy-popup-thing-not-yet-shown").click(function() { 
    if ($(this).hasClass("fancy-schmancy-popup-thing-not-yet-shown")) 
     return true; 

    doStuff(); 
    $(this).removeClass("fancy-schmancy-popup-thing-not-yet-shown"); 

    var link = this; 
    setTimeout(function() { 
     hideMessage(); 
     $(link).click().addClass("fancy-schmancy-popup-thing-not-yet-shown"; 
    }, 1000); 

    return false; 
}); 
+0

Todavía no veo cómo esto preservará el evento original de ninguna manera. ¿Estoy enviando algo? –

+0

La última llamada a '$ (enlace) .click()' se comportará como si el usuario simplemente hubiera hecho clic en el enlace en cuestión. Por supuesto, su controlador de eventos para ese evento se ejecutará de nuevo, pero esta vez el enlace ya no incluirá esa clase, por lo que su controlador de eventos simplemente regresará verdadero. Cada vez que un controlador de eventos devuelve verdadero, el navegador continuará realizando otras acciones asociadas con el evento, incluido el comportamiento original (predeterminado) (por ejemplo, ir a una página nueva). – VoteyDisciple

2

Probablemente la mejor manera de hacer esto es utilizar unbind. Algo así como:

+0

Esto pareció funcionar. ¡Tan fácil! ¡Gracias! –

+1

Está usando el DOM "this" para desvincular, ese código debería ser: if (typeof event == 'undefined') { return true; } $ (esto) .unbind (evento); this.click() –