2010-09-28 12 views
6


¿Cómo puedo prevenir enlaces en el evento click antes de cargar jQuery?
La razón es que tengo pocos enlaces que hacen llamadas AJAX a través de funciones jQuery ajax y si el usuario hace clic antes de que se cargue jQuery framework el navegador no puede activar la función jQuery ajax y seguirá enlaces href = "..." Gracias.Prevención de enlaces antes de que se cargue jQuery

Editar: ¿Puedo usar esto?

<head> 
... 
    <script type="text/javascript"> 
    window.onload = prevCl(); 
    function prevCl() { 
    var links = document.links[]; 
    links.onclick = check(); 
    } 
    function check() { 
    if (typeof jQuery == 'undefined') { 
    return false; 
    } 
    } 
    </script> 
</head> 
+0

Puede probar un enfoque de interfaz de usuario. tal vez crear un preloader. – sheeks06

+0

He actualizado la respuesta de Sean Hogan con un ejemplo. Él tiene toda la razón sobre cómo hacer esto. –

Respuesta

9

Cuatro opciones para usted:

opción 0

ir a leer Sean Hogan's answer, que señalaron que esto se puede hacer con la delegación y yo juntos un ejemplo (DOH!) implementación.

Opción 1

Puede hacer que el href de los enlaces "#" hasta que se carga jQuery, y luego (en su caso) el cambio a lo que realmente debe ser. Puede almacenar lo que el href debe estar en un atributo data-, por ejemplo .:

<a href='javascript:;' data-href='realtarget.html'>blah</a> 

continuación:

jQuery(function($) { 
    $("a[data-href]").each(function() { 
     var $this = $(this); 
     $this.attr("href", $this.attr("data-href")); 
    }); 
}); 

vez más, que el último bit sólo si realmente necesita para tomar la href href una. Si está manejando el clic a través de JavaScript, no es necesario.

Si la validación es una parte importante de su ciclo de desarrollo, es importante tener en cuenta que los atributos en el formulario data-xyz no son válidos en HTML4 y anteriores (los navegadores no se preocupan, pero si usa la validación ...) . Se vuelven válidos a partir de HTML5.

Opción 2

uso en línea onclick atributos para interceptar el clic antes de la carga y jQuery básicamente decir "Lo siento, un momento". Así, en una etiqueta script en la parte superior de su archivo:

function sorryLoading() { 
    alert("Sorry, the page is still loading, one moment please."); 
    return false; 
} 

... y luego en los enlaces:

<a href='realtarget.html' class='sorry' onclick='return sorryLoading();'>blah</a> 

... luego retire la onclick en la carga jQuery:

jQuery(function($) { 
    $("a.sorry").removeClass('sorry').attr("onclick", "").click(yourRealClickHandler); 
}); 

(puede dejar el último bit   — la llamada click   — fuera si no lo hacen todos tienen el mismo controlador de clic.)

he utilizado una clase por encima de diferenciar entre estos circuitos y otros que podrían tener un inline onclick (de lo contrario, es sorprendente que el selector de "un [onclick ] "realmente funciona en Chrome, Opera y Firefox para Linux e IE6 e IE8 en Windows).

Opción 3

Desde que suena como desea que la página sea no funcional hasta cargas de jQuery, aquí hay otro enfoque:

  1. Asegúrese de que la etiqueta script de jQuery es en el head sección de su página (no en la parte inferior, donde normalmente recomendaría ponerlo).
  2. En la parte inferior de la página, justo antes de cerrar la etiqueta body, conectar sus manipuladores clic sin envolviéndolos en una llamada jQuery.ready (o cualquiera de sus accesos directos).

La razón es la siguiente: # 1 se asegurará de que sí jQuery se carga antes de la página que se está dictada, y # 2 será conectar los controladores tan pronto como sea posible. Google recomienda usar una etiqueta al final de la página de esa manera (en lugar de una función ready o similar) y dice que en ese punto, los elementos DOM estarán listos para ser descubiertos.


Por otro lado, por supuesto, usted quiere asegurarse de que el tiempo durante el cual los enlaces no hacen lo que el usuario espera es absolutamente lo más breve posible haciendo todas las cosas optimización de carga de páginas que poder. Hacer clic en un enlace y no hacer que funcione como lo hace hace que la experiencia del usuario sea baja.

+1

Gracias, pero es una gran manipulación de DOM y tiene problemas propios sobre SEO y la velocidad de carga de la página. :) – Ali

+0

@ Ali: Buen punto sobre el SEO. Estaba agregando otra opción como lo señaló. –

+0

gracias T. J. pero tengo enlaces feeeeeeeeeeew, creo que javascript puede hacerlo pero no soy bueno en javascript sin frameworks intenté escribir una función pero no funcionó. (¿Puedes ver esta función en mi pregunta? Lo he editado) – Ali

1

No lo he probado, pero en teoría, agrego un manejador de eventos sin jquery a todos los elementos que previenen la acción predeterminada (abrir el enlace) mientras jquery esté sin terminar.

getElementsByTagNames('a').addEventListener('click',function (event) { 
    if (typeof jQuery == 'undefined') { 
    event.preventDeafault(); 
    } 
},false) 
4

Usted podría utilizar evento de delegación: el DOM equivalente de jQuery live() y delegate() métodos.

El siguiente podría funcionar:

<head> 

<script> 
function linkMatcher(node) { // modify this if not all links are disabled 
if (node.href) return true; 
else return false; 
} 

document.onclick = function(e) { 
e = e || window.event; 
var target = e.target || e.srcElement; 
for (var node=target; node!=document; node=node.parentNode) { 
    if (node.tagName == "A") return !linkMatcher(node); 
} 
} 
</script> 
</head> 

EDIT: Esto desactiva los enlaces de forma permanente. Se pueden volver a habilitar eliminando el controlador de eventos, p. document.onclick = null.


El complete, live example siguiente funciona en Chrome, Opera y Firefox para Linux, así como IE6 e IE8 para Windows. Evita los clics en los enlaces con la clase "esperar" (en su lugar, podría hacer todos los enlaces si lo desea) y recuerda el primer enlace en el que se hizo clic. Luego simula un retraso de carga larga (cinco segundos) y luego conecta manejadores jQuery en los enlaces y elimina el manejador a nivel de documento que impedía clics, y luego activa el manejador jQuery en el enlace en el que se hizo clic (tenga en cuenta que esto solo desencadena el controlador, no el comportamiento por defecto subyacente   —, pero como desea activar sus cosas de ajax, creo que está bien).   — T.J.Crowder

HTML:

<!DOCTYPE html> 
<html> 
<head> 
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> 
<meta charset=utf-8 /> 
<title>Link Click Delay Test Page</title> 
<!--[if IE]> 
    <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> 
<![endif]--> 
<style> 
    article, aside, figure, footer, header, hgroup, 
    menu, nav, section { display: block; } 
    body { 
    font-family: sans-serif; 
    } 
    p { 
    margin: 0px; 
    } 
</style> 
<script type='text/javascript'> 
    // A scoping function to avoid creating global symbols 
    (function() { 
    // Figure out what to hook clicks on 
    var container = 
     document.body || 
     document.documentElement || 
     document; 

    // Hook clicks that reach the bottom level 
    hookClicks(); 
    function hookClicks() { 
     if (container.attachEvent) { 
     container.attachEvent("onclick", handleClick); 
     } 
     else if (document.addEventListener) { 
     container.addEventListener("click", handleClick, false); 
     } 
    } 

    // Set up an unhook function for jQuery to call 
    window.unhookClicks = unhookClicks; 
    function unhookClicks() { 
     if (container.attachEvent) { 
     container.detachEvent("onclick", handleClick); 
     } 
     else if (document.addEventListener) { 
     container.removeEventListener("click", handleClick, false); 
     } 
    } 

    // Handle clicks 
    function handleClick(event) { 
     var target; 

     // Handle Microsoft vs. W3C event passing style 
     event = event || window.event; 

     // Get the target (again handling Microsoft vs. W3C style) 
     target = event.target || event.srcElement; 

     // Do we have a target that's an A with the class "wait"? 
     if (target && 
      target.tagName.toUpperCase() === "A" && 
      (" " + target.className + " ").indexOf(" wait ") >= 0 
     ) { 
     // It's a link we want to prevent for the moment 
     // Remember the element that was clicked if there 
     // isn't already one (or replace it, depends on the 
     // UX you want to provide 
     if (!window.pendingLink) { 
      window.pendingLink = target; 
     } 

     // Prevent it from being processed 
     if (event.preventDefault) { // If W3C method... 
      event.preventDefault(); 
     } 

     // This should work if preventDefault doesn't 
     return false; 
     } 
    } 
    })(); 
</script> 
</head> 
<body> 
    <p><a href='http://www.google.com' class='wait'>Google</a> 
    - This one waits 
    <br><a href='http://news.bbc.co.uk' class='wait'>BBC News</a> 
    - This one also waits 
    <br><a href='http://www.cnn.com'>CNN</a> 
    - This one doesn't wait, it goes immediately 
    </p> 
</body> 
</html>​ 

Javascript (jQuery donde quiera que su manejador ready es):

jQuery(function($) { 

    // Use setTimeout to fake a long delay loading 
    setTimeout(function() { 

    // Hook up our proper click handling 
    // Obviously, replace this with whatever does the ajax 
    $("a.wait").click(function(event) { 
     alert("The jQuery handler for " + this.href + " link was triggered."); 
    }); 

    // If we have clicks disabled, enable them 
    if (window.unhookClicks) { 
     window.unhookClicks(); 
     window.unhookClicks = undefined; 
    } 

    // Do we have a pending link to follow? 
    if (window.pendingLink) { 
     // Yes, grab it and clear it 
     var $link = $(window.pendingLink); 
     window.pendingLink = undefined; 

     // Trigger any jQuery event handlers on it. 
     // Note that this will NOT follow the link, 
     // just trigger jQuery event handlers that 
     // are on the link. 
     $link.click(); 
    } 

    // We've loaded! 
    $("<p>Finally loaded!</p>").appendTo(document.body); 

    // End of fake delay function 
    }, 5000); 

});​ 
+0

** Doh! ** Por supuesto, capturar los clics en el nivel del documento mientras se está procesando la página es la manera de hacerlo. Me he tomado la libertad de agregar un ejemplo completo y vivo (y usar 'attachEvent' /' addEventListener' en lugar de 'onclick'). –

Cuestiones relacionadas