2011-04-25 7 views
5

Tengo un código para una galería de fotos simple que se ha escrito con jquery, pero creo que es excesivo cargar toda la biblioteca por una cosa tan simple. Lo quiero en JavaScript sin procesar.convirtiendo un código de jquery simple en javascript

$('#thumbs').delegate('img','click', function(){ 
    $('#largeImage').attr('src',$(this).attr('src').replace('thumb','large')); 
    $('#description').html($(this).attr('alt')); 
}); 

También me pregunto cómo puedo adjuntar un controlador de carga a este código. Gracias.

jsfiddle

+10

Hay una razón por la cual el lema de jQuery es * Escriba menos, haga más *: el código JavaScript simple equivalente a su extracto probablemente pesará al menos unas pocas docenas de líneas, más si quiere que sea de navegador cruzado. Te sugiero que evites reinventar la rueda e incluir la biblioteca, no es tan pesado. –

+10

Respuesta rápida: No es excesivo cargar jQuery. Respuesta más larga: el código que pegó está utilizando la delegación de eventos para enlazar un único evento a #thumbs que actúa sobre todos sus elementos de img secundarios. Esto es exactamente lo que las bibliotecas son buenas, elimina la necesidad de escribir una tonelada de código repetitivo para hacer esto. Este fragmento de código de 4 líneas podría terminar siendo más de 50 si lo escribió en JS nativo. Ni siquiera estoy seguro de por dónde empezar. –

+1

Estas son respuestas válidas;) ¿por qué no publicarlas? – Nix

Respuesta

9

Sin utilizar cualquier biblioteca, se ve un poco como esto, aunque, por supuesto, hay otras formas de escribir que:

(function() { 
    var largeImage = document.getElementById('largeImage'), 
     description = document.getElementById('description'); 

    document.getElementById('thumbs').onclick = handleGalleryClick; 

    function handleGalleryClick(event) { 
     var target; 

     event = event || window.event;    // Handle IE difference 
     target = event.target || event.srcElement; // Another one 
     if (target && target.tagName.toUpperCase() === "IMG") { 
      largeImage.src = target.src.replace('thumb', 'large'); 
      description.innerHTML = target.getAttribute('alt'); 
     } 
    } 
})(); 

asegurarse de que la escritura aparece en la parte inferior de la página (justo antes del elemento body de cierre) o envuélvalo en un window.onload aunque no estará contento con el tiempo que tarde en ocurrir, ya que window.onload ocurre después de que se cargan todas las imágenes.

Pero: Estoy de acuerdo con Frédéric y los comentarios de John: No es una exageración para cargar una biblioteca para esto, y en el caso de jQuery (y Prototipo y YUI) Puede load via the Google CDN y usar algo de su página de visitante, probablemente, ya tiene en su caché de todos modos.


actualización: En los comentarios a continuación, scunliffe señaló un fallo de IE que I've blogged in the past que podrían afectar a la anterior, que se trabajó en torno mágicamente para usted por jQuery. Así que pensé que podría ser útil para airear las diversas complicaciones que este pequeño y sencillo script tiene que una buena biblioteca va a clasificar para ti:

  • addEventListener vs attachEvent: IE6 a través de Internet Explorer 8 no son compatibles con el DOM2 estándar addEventListener, usando el propio attachEvent de Microsoft en su lugar. De hecho, me di cuenta de esto en el ejemplo anterior por simplicidad y acabo de utilizar el estilo DOM0 onclick = ..., pero hay una buena razón no para hacer eso: con el estilo DOM0, solo puede tener un único detector de eventos por evento por elemento y adjuntar otro separará el anterior. Por lo tanto, mi código anterior no funciona bien con otros, ya que desalojará cualquier controlador DOM0 click anterior (y será desalojado por un controlador DOM0 click adjunto después de que se ejecute el código anterior).
  • Acceso a la event objeto: El DOM standard dice que el objeto event se pasa al controlador de eventos como primer argumento. IE, en cambio, utiliza un objeto global window.event. Esa es la razón de mi primera "diferencia IE" anterior.
  • Propiedades en el event objeto: ... y del mismo modo, el DOM standard says el elemento real en la que se generó el evento será propiedad target. IE6 a IE8 usa srcElement en su lugar. (También hay otras diferencias). De ahí mi comentario "Otro uno".
  • Solución de error: Este es el conflation cosa scunliffe señaló. Lo anterior se basa en document.getElementById para funcionar correctamente, pero en IE6 e IE7, no es así. Combina varios espacios de nombres en lugar de trabajar solo con los valores id.

... así que en general, este sencillo pequeño script hace que el punto bastante bien que las bibliotecas en general   — y una buena bibliotecaen particular   — le puede ahorrar tiempo, mantener su sitio compatible con las líneas generales , y en general solo valen su pequeño costo. No sé sobre los otros, pero por ejemplo jQuery trabaja para usted en el error de combinación, pero otra biblioteca conocida y respetada, Prototype, no lo hace.

(Nota al margen:. Antes tocamos Microsoft demasiado, recordemos que attachEvent y srcElement probablemente son anteriores a la especificación DOM2; Microsoft hizo un montón de innovar en IE5.5 e IE6 [. Inventaron ajax, por ejemplo] IE6 era   — por ahora   — el mejor navegador disponible en el año 2001, las debidas disculpas a Opera. dicho esto, IE6 salió después de la norma hizo y por lo que añadir el material normas en ese momento, o varios años más tarde en IE7, podría haber sido lo que valió la pena hacer, pero IE9 corrige muchas de estas cosas.)

+0

¿No sería realmente el evento click en los elementos de img de niños de #thumbs? ... Y tampoco sería en todos los elementos img futuros de los niños ... ¿No solo existente? – scunliffe

+0

@scunliffe: para implementar 'delegate', debe escuchar en el contenedor raíz y verificar si el destino del evento fue' '(por lo que el evento funciona en elementos actuales y _future_). – Matt

+1

@scunliffe: haga clic en las burbujas de los elementos secundarios hacia arriba a través de sus padres, etc., hasta la raíz (a menos que se detenga). Así que al conectar 'click' en el contenedor' thumbs', estamos manejando todos los elementos 'img' (ahora y en el futuro cuando se agreguen otros). Así es como funciona el 'delegado' de jQuery, es simplemente (práctico) azúcar sintáctico para la delegación de eventos estándar, que es lo que he hecho anteriormente. –

4

Lo llama simple, pero está haciendo cosas algo avanzadas. Para emular delegate, debe adjuntar un detector de clics en el contenedor raíz y buscar clics en cualquier etiqueta <img>.

Por no hablar de que tiene que hacer cosas como el uso attachEvent en IE en lugar de addEventListener

El código sería algo así (no probado):

function listen(root, callback) { 
    var addEvent = 'attachEvent'; 
    if (typeof window.addEventListener === 'function') { 
     addEvent = 'addEventListener'; 
    } 

    root[addEvent](function (e) { 
     if (/img/i.test(e.target.tagName)) { 
      callback.apply(e.target); 
     } 
    }, false); 
} 

listen(document.getElementById('thumbs'), function() { 
    document.getElementById('largeImage').src = this.src.replace(/thumb/ig, 'large'); 
    document.getElementById('description').src = this.alt; 
}); 

De hecho, como el post de TJ muestra a continuación, Ni siquiera estoy manejando todas las idiosincrasias de IE. jQuery no es excesivo teniendo en cuenta todos los dolores de cabeza del navegador que resuelve para usted.

Cuestiones relacionadas