2011-01-23 6 views
7

He intentado añadir una clase serializada a cada uno de un conjunto de objetos de esta manera:¿El método "each()" de jQuery es un ciclo for?

jQuery('#preload img').each(function(){ 
    jQuery('#thumbs').append('<img class="index' + index + '" src="' + source + '" />'); 
    index = ++index; 
    }); 

y funcionó. Lo que resultó fue un conjunto de imágenes, cada una con una clase image1, image2, y así sucesivamente. Es exactamente lo que quería. Pero, ¿es esto realmente un método confiable para recorrer un conjunto de objetos? ¿O es posible que, si esta función anónima tardó más en ejecutarse, la función podría comenzar en el siguiente objeto antes de que se incremente index?

¿Alguien sabe lo que está sucediendo realmente?

+4

FWIW un enfoque más eficaz sería inicializar una cadena en blanco antes de ese ciclo, concatenarlo cada vez que pasa el ciclo, luego '$ (...). Anexar' la cadena una sola vez después de que termine el ciclo. DOM es notoriamente lento. –

Respuesta

8

Este es el funcionamiento interno de la función each (1.4.4):

// args is for internal usage only 
each: function(object, callback, args) { 
    var name, i = 0, 
     length = object.length, 
     isObj = length === undefined || jQuery.isFunction(object); 

    if (args) { 
     if (isObj) { 
      for (name in object) { 
       if (callback.apply(object[ name ], args) === false) { 
        break; 
       } 
      } 
     } else { 
      for (; i < length;) { 
       if (callback.apply(object[ i++ ], args) === false) { 
        break; 
       } 
      } 
     } 

    // A special, fast, case for the most common use of each 
    } else { 
     if (isObj) { 
      for (name in object) { 
       if (callback.call(object[ name ], name, object[ name ]) === false) { 
        break; 
       } 
      } 
     } else { 
      for (var value = object[0]; 
       i < length && callback.call(value, i, value) !== false; value = object[++i]) {} 
     } 
    } 

    return object; 
} 

Puede ver aquí que tiene algunos casos diferentes pero todos ellos usan los bucles for y llaman a la función de devolución de llamada. Entonces tu código debería estar bien.

Puede buscarlo en la versión de desarrollo de jQuery (cambie el botón de opción en el sitio principal de jQuery o haga clic en here).

+0

+1 - El código dice mucho. Buena respuesta. – jmort253

+0

++ 1 :) ........ –

5

.each() es de hecho esencialmente un bucle y también se ha construido en un índice Puede usar si pasa un argumento como ese:

jQuery('#preload img').each(function(i){ 
    jQuery('#thumbs').append('<img class="index' + i + '" src="' + source + '" />'); 
}); 

EDIT: aplicación de experiencia con concatenación de cadenas sugerencia de Ken Franqueiro:

var thumbsAppend = ""; 
jQuery('#preload img').each(function(i){ 
    thumbsAppend += '<img class="index' + i + '" src="' + source + '" />'; 
}); 
jQuery('#thumbs').append(thumbsAppend); 

editar # 2: Y de Rahul gama empuje sugerencia:

var thumbsAppend = []; 
jQuery('#preload img').each(function(i){ 
    thumbsAppend.push('<img class="index' + i + '" src="' + source + '" />'); 
}); 
thumbsAppend = thumbsAppend.join(''); 
jQuery('#thumbs').append(thumbsAppend); 
+0

Es mejor utilizar una matriz de inserción en lugar de cadena de concatenación. – rahul

+1

@rahul, solo para IE7 y más bajo, en otros navegadores ambos métodos son más o menos iguales, excepto en safari donde los concatetos son más rápidos. –

+0

ah el maravilloso mundo de la evaluación comparativa. A decir verdad, la diferencia entre 'strcat' y' arr.push' es insignificante en comparación con la diferencia entre cualquiera de ellos y el ajuste de DOM. Si funciona en una computadora razonablemente lenta (netbook?), Deberías estar bien. – zzzzBov

Cuestiones relacionadas