div - wrap javascript
Consejos y trucos de jQuery (30)
Controladores de eventos en vivo
Configure un controlador de eventos para cualquier elemento que coincida con un selector, incluso si se agrega al DOM después de la carga de la página inicial:
$(''button.someClass'').live(''click'', someFunction);
Esto le permite cargar contenido a través de ajax, o agregarlos a través de javascript y hacer que los controladores de eventos se configuren correctamente para esos elementos automáticamente.
Asimismo, para detener el manejo del evento en vivo:
$(''button.someClass'').die(''click'', someFunction);
Estos manejadores de eventos en vivo tienen algunas limitaciones en comparación con los eventos regulares, pero funcionan muy bien en la mayoría de los casos.
Para más información vea la documentación de jQuery .
ACTUALIZACIÓN: live()
y die()
están en desuso en jQuery 1.7. Consulte http://api.jquery.com/on/ y http://api.jquery.com/off/ para obtener una funcionalidad de reemplazo similar.
ACTUALIZACIÓN2: live()
ha estado en desuso por mucho tiempo, incluso antes de jQuery 1.7. Para las versiones jQuery 1.4.2+ anteriores a 1.7, use delegate()
y undelegate()
. El ejemplo de live()
( $(''button.someClass'').live(''click'', someFunction);
) se puede reescribir usando delegate()
así: $(document).delegate(''button.someClass'', ''click'', someFunction);
.
Sintaxis
- Taquigrafía para el evento listo por roosteronacid
- Roturas de línea y encadenabilidad por roosteronácido.
- Filtros de anidamiento de Nathan Long
- Almacene en caché una colección y ejecute comandos en la misma línea por roosteronacid
- Contiene selector por roosteronacid
- Definiendo propiedades en la creación de elementos por roosteronacid
- Acceda a las funciones de jQuery como lo haría con una matriz de roosteronacid
- La función noConflict - Liberar la variable $ de Oli
- Aísla la variable $ en modo noConflicto por nickf
- Modo sin conflicto por roosteronacid
Almacenamiento de datos
- La función de datos - vincular datos a elementos por TenebrousX
- Soporte de atributos de datos HTML5, en los esteroides! por roosteronacid
- El complemento de metadatos de jQuery por Filip Dupanović
Mejoramiento
- Optimizar el rendimiento de los selectores complejos por roosteronacid
- El parámetro de contexto por lupefiasco.
- Guarda y reutiliza búsquedas de Nathan Long
- Crear un elemento HTML y mantener una referencia, verificar si existe un elemento, escribir sus propios selectores por Andreas Grech
Diverso
- Compruebe el índice de un elemento en una colección por redsquare
- Controladores de eventos en vivo por TM
- Reemplace funciones anónimas con funciones nombradas por ken
- Microsoft AJAX framework y jQuery bridge by Slace
- jQuery tutorials por egyamado
- Eliminar elementos de una colección y preservar la capacidad de encadenamiento por roosteronacid
- Declare $ esto al comienzo de las funciones anónimas por Ben
- FireBug lite, complemento de Hotbox, informa cuándo se ha cargado una imagen y Google CDN por Color Blend
- Uso juicioso de guiones de jQuery de terceros por harriyott
- La función de cada uno por Jan Zich
- Complemento de extensiones de formulario por Chris S
- Asincrónica cada función por OneNerd.
- El complemento de la plantilla jQuery: implementando lógica compleja usando funciones de renderizado por roosteronacid
Filtros de anidación
Puedes anidar filtros (como se muestra aquí ).
.filter(":not(:has(.selected))")
Guardar objetos jQuery en variables para su reutilización
Guardar un objeto jQuery en una variable le permite reutilizarlo sin tener que buscar a través del DOM para encontrarlo.
(Como sugirió @Louis, ahora uso $ para indicar que una variable contiene un objeto jQuery).
// Bad: searching the DOM multiple times for the same elements
$(''div.foo'').each...
$(''div.foo'').each...
// Better: saving that search for re-use
var $foos = $(''div.foo'');
$foos.each...
$foos.each...
Como ejemplo más complejo, supongamos que tiene una lista de alimentos en una tienda y desea mostrar solo los que coinciden con los criterios de un usuario. Tiene un formulario con casillas de verificación, cada una con un criterio. Las casillas de verificación tienen nombres como organic
y bajo en lowfat
, y los productos tienen las clases correspondientes: .organic
, etc.
var $allFoods, $matchingFoods;
$allFoods = $(''div.food'');
Ahora puedes seguir trabajando con ese objeto jQuery. Cada vez que se hace clic en una casilla de verificación (para marcar o desmarcar), comience desde la lista maestra de alimentos y filtre hacia abajo según las casillas marcadas:
// Whenever a checkbox in the form is clicked (to check or uncheck)...
$someForm.find(''input:checkbox'').click(function(){
// Start out assuming all foods should be showing
// (in case a checkbox was just unchecked)
var $matchingFoods = $allFoods;
// Go through all the checked boxes and keep only the foods with
// a matching class
this.closest(''form'').find("input:checked").each(function() {
$matchingFoods = $matchingFoods.filter("." + $(this).attr("name"));
});
// Hide any foods that don''t match the criteria
$allFoods.not($matchingFoods).hide();
});
Revisar el índice
jQuery tiene .index, pero es una molestia utilizarlo, ya que necesita la lista de elementos, y pase el elemento sobre el que desea el índice:
var index = e.g $(''#ul>li'').index( liDomObject );
Lo siguiente es mucho más fácil:
Si desea conocer el índice de un elemento dentro de un conjunto (por ejemplo, elementos de lista) dentro de una lista no ordenada:
$("ul > li").click(function () {
var index = $(this).prevAll().length;
});
¡Ooooh, no olvidemos los metadatos de jQuery ! La función data () es excelente, pero debe completarse mediante llamadas jQuery.
En lugar de romper el cumplimiento de W3C con atributos de elementos personalizados como:
<input
name="email"
validation="required"
validate="email"
minLength="7"
maxLength="30"/>
Use metadatos en su lugar:
<input
name="email"
class="validation {validate: email, minLength: 2, maxLength: 50}" />
<script>
jQuery(''*[class=validation]'').each(function () {
var metadata = $(this).metadata();
// etc.
});
</script>
Actualizar:
Solo incluye este script en el sitio y obtendrás una consola Firebug que se abre para la depuración en cualquier navegador. No es tan completo, pero sigue siendo muy útil! Recuerda quitarlo cuando hayas terminado.
<script type=''text/javascript'' src=''http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js''></script>
Echa un vistazo a este enlace:
Actualización: encontré algo nuevo; Es el JQuery Hotbox.
Google alberga varias bibliotecas de JavaScript en Google Code. Cargarlo desde allí ahorra ancho de banda y se carga rápidamente porque ya se ha almacenado en caché.
<script src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
// Load jQuery
google.load("jquery", "1.2.6");
google.setOnLoadCallback(function() {
// Your code goes here.
});
</script>
O
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script>
También puede usar esto para saber cuándo una imagen está completamente cargada.
$(''#myImage'').attr(''src'', ''image.jpg'').load(function() {
alert(''Image Loaded'');
});
La "console.info" de firebug, que puede usar para volcar mensajes y variables en la pantalla sin tener que usar cuadros de alerta. "console.time" le permite configurar fácilmente un temporizador para envolver un montón de código y ver cuánto tiempo lleva.
console.time(''create list'');
for (i = 0; i < 1000; i++) {
var myList = $(''.myList'');
myList.append(''This is list item '' + i);
}
console.timeEnd(''create list'');
El método data()
jQuery es útil y poco conocido. Le permite enlazar datos a elementos DOM sin modificar el DOM.
En la función jQuery principal, especifique el parámetro de contexto además del parámetro selector. Especificar el parámetro de contexto permite que jQuery comience desde una rama más profunda en el DOM, en lugar de hacerlo desde la raíz del DOM. Dado un DOM suficientemente grande, la especificación del parámetro de contexto debería traducirse en ganancias de rendimiento.
Ejemplo: busca todas las entradas de tipo radio en el primer formulario del documento.
$("input:radio", document.forms[0]);
Referencia: http://docs.jquery.com/Core/jQuery#expressioncontext
En lugar de usar un alias diferente para el objeto jQuery (cuando utilizo noConflict), siempre escribo mi código jQuery envolviéndolo todo en un cierre. Esto se puede hacer en la función document.ready:
var $ = someOtherFunction(); // from a different library
jQuery(function($) {
if ($ instanceOf jQuery) {
alert("$ is the jQuery object!");
}
});
alternativamente puedes hacerlo así:
(function($) {
$(''...'').etc() // whatever jQuery code you want
})(jQuery);
Me parece que este es el más portátil. He estado trabajando en un sitio que utiliza tanto Prototype Y jQuery simultáneamente y estas técnicas han evitado todos los conflictos.
Hablando de consejos y trucos y también algunos tutoriales. Encontré que estas series de tutoriales ( Serie de videos “jQuery for Absolute Beginners”) de Jeffery Way son MUY ÚTILES.
Se dirige a aquellos desarrolladores que son nuevos en jQuery. Muestra cómo crear muchas cosas geniales con jQuery, como animación, Creación y eliminación de elementos y más ...
Aprendí mucho de eso. Él muestra cómo es fácil usar jQuery. Ahora me encanta y puedo leer y entender cualquier script de jQuery incluso si es complejo.
Aquí hay un ejemplo que me gusta " Resizing Text "
1- jQuery ...
<script language="javascript" type="text/javascript">
$(function() {
$(''a'').click(function() {
var originalSize = $(''p'').css(''font-size''); // get the font size
var number = parseFloat(originalSize, 10); // that method will chop off any integer from the specified variable "originalSize"
var unitOfMeasure = originalSize.slice(-2);// store the unit of measure, Pixle or Inch
$(''p'').css(''font-size'', number / 1.2 + unitOfMeasure);
if(this.id == ''larger''){$(''p'').css(''font-size'', number * 1.2 + unitOfMeasure);}// figure out which element is triggered
});
});
</script>
2- Estilo CSS ...
<style type="text/css" >
body{ margin-left:300px;text-align:center; width:700px; background-color:#666666;}
.box {width:500px; text-align:justify; padding:5px; font-family:verdana; font-size:11px; color:#0033FF; background-color:#FFFFCC;}
</style>
2- HTML ...
<div class="box">
<a href="#" id="larger">Larger</a> |
<a href="#" id="Smaller">Smaller</a>
<p>
In today’s video tutorial, I’ll show you how to resize text every time an associated anchor tag is clicked. We’ll be examining the “slice”, “parseFloat”, and “CSS” Javascript/jQuery methods.
</p>
</div>
Recomiendo altamente estos tutoriales ...
http://blog.themeforest.net/screencasts/jquery-for-absolute-beginners-video-series/
Me gusta declarar a $this
variable al comienzo de las funciones anónimas, así que sé que puedo hacer referencia a jQueried this.
Al igual que:
$(''a'').each(function() {
var $this = $(this);
// Other code
});
No solo realmente jQuery, pero hice un bonito puente para jQuery y MS AJAX:
Sys.UI.Control.prototype.j = function Sys$UI$Control$j(){
return $(''#'' + this.get_id());
}
Es realmente bueno si está haciendo un montón de ASP.NET AJAX, ya que jQuery es compatible con MS. Ahora, tener un buen puente significa que es muy fácil hacer las operaciones de jQuery:
$get(''#myControl'').j().hide();
Por lo tanto, el ejemplo anterior no es excelente, pero si está escribiendo controles de servidor AJAX de ASP.NET, facilita tener jQuery dentro de la implementación de control del lado del cliente.
Parece que la mayoría de los consejos interesantes e importantes ya se han mencionado, por lo que este es solo un pequeño agregado.
El pequeño consejo es la función jQuery.each (objeto, devolución de llamada) . Probablemente todos jQuery.each(callback) utilizando la función jQuery.each(callback) para iterar sobre el objeto jQuery en sí mismo porque es natural. La función de utilidad jQuery.each (objeto, devolución de llamada) itera sobre objetos y matrices. Durante mucho tiempo, de alguna manera no vi lo que podría ser, aparte de una sintaxis diferente (no me importa escribir todos los bucles de moda), y me siento un poco avergonzado de que me di cuenta de su fuerza principal recientemente.
El problema es que dado que el cuerpo del bucle en jQuery.each (objeto, devolución de llamada) es una función , se obtiene un nuevo alcance cada vez en el bucle, lo cual es especialmente conveniente cuando se crean cierres en el bucle.
En otras palabras, un error común típico es hacer algo como:
var functions = [];
var someArray = [1, 2, 3];
for (var i = 0; i < someArray.length; i++) {
functions.push(function() { alert(someArray[i]) });
}
Ahora, cuando invocas las funciones en la matriz de functions
, recibirás una alerta tres veces con el contenido undefined
que probablemente no sea lo que querías. El problema es que solo hay una variable i
, y los tres cierres se refieren a ella. Cuando el bucle finaliza, el valor final de i
es 3, y algo someArrary[3]
undefined
está undefined
. Podría solucionarlo llamando a otra función que crearía el cierre para usted. O utiliza la utilidad jQuery, que básicamente lo hará por usted:
var functions = [];
var someArray = [1, 2, 3];
$.each(someArray, function(item) {
functions.push(function() { alert(item) });
});
Ahora, cuando invoca las funciones, obtiene tres alertas con el contenido 1, 2 y 3 como se esperaba.
En general, no es nada que no puedas hacer tú mismo, pero es bueno tenerlo.
Realmente no soy fanático del acceso directo $(document).ready(fn)
. Seguro que reduce el código, pero también reduce la legibilidad del código. Cuando ves $(document).ready(...)
, sabes lo que estás viendo. $(...)
se usa en muchas otras formas para que tenga sentido de inmediato.
Si tiene varios marcos puede usar jQuery.noConflict();
Como dices, pero también puedes asignarle una variable diferente como esta:
var $j = jQuery.noConflict();
$j("#myDiv").hide();
Muy útil si tiene varios marcos que pueden reducirse a llamadas de estilo $x(...)
.
Reemplace funciones anónimas con funciones nombradas. Esto realmente reemplaza el contexto de jQuery, pero entra en juego más, parece que cuando se usa jQuery, debido a su dependencia de las funciones de devolución de llamada. Los problemas que tengo con las funciones anónimas en línea, son que son más difíciles de depurar (mucho más fácil de ver en una pila de llamadas con funciones claramente nombradas, en lugar de 6 niveles de "anónimo"), y también el hecho de que múltiples funciones anónimas dentro de la misma jQuery-chain puede volverse difícil de leer y / o mantener. Además, las funciones anónimas normalmente no se reutilizan; por otro lado, la declaración de funciones nombradas me anima a escribir código que es más probable que se reutilice.
Una ilustración; en lugar de:
$(''div'').toggle(
function(){
// do something
},
function(){
// do something else
}
);
Yo prefiero:
function onState(){
// do something
}
function offState(){
// do something else
}
$(''div'').toggle( offState, onState );
Syntactic shorthand-sugar-thing - Guarda en caché una colección de objetos y ejecuta comandos en una línea:
En lugar de:
var jQueryCollection = $("");
jQueryCollection.command().command();
Hago:
var jQueryCollection = $("").command().command();
Un caso de uso un tanto "real" podría ser algo como esto:
var cache = $("#container div.usehovereffect").mouseover(function ()
{
cache.removeClass("hover").filter(this).addClass("hover");
});
Use métodos de filtrado sobre pseudo selectores cuando sea posible para que jQuery pueda usar querySelectorAll (que es mucho más rápido que el chisporroteo). Considere este selector:
$(''.class:first'')
La misma selección se puede hacer usando:
$(''.class'').eq(0)
Que es más rápido porque la selección inicial de ''.class'' es compatible con QSA
Accede a las funciones de jQuery como lo harías con un array.
Agregar / eliminar una clase basada en un booleano ...
function changeState(b)
{
$("selector")[b ? "addClass" : "removeClass"]("name of the class");
}
Es la versión más corta de ...
function changeState(b)
{
if (b)
{
$("selector").addClass("name of the class");
}
else
{
$("selector").removeClass("name of the class");
}
}
No hay tantos casos de uso para esto. Sin embargo; Creo que está limpio :)
Actualizar
En caso de que no sea del tipo de lectura de comentarios, ThiefMaster señala que toggleClass acepta un valor booleano , que determina si una clase debe agregarse o eliminarse. En lo que respecta a mi código de ejemplo anterior, este sería el mejor enfoque ...
$(''selector'').toggleClass(''name_of_the_class'', true/false);
Cada función asíncrona ()
Si tiene documentos realmente complejos en los que ejecutar la función jquery cada () bloquea el navegador durante la iteración, y / o Internet Explorer muestra el mensaje " ¿desea continuar ejecutando este script? ", Esta solución lo salvará.
jQuery.forEach = function (in_array, in_pause_ms, in_callback)
{
if (!in_array.length) return; // make sure array was sent
var i = 0; // starting index
bgEach(); // call the function
function bgEach()
{
if (in_callback.call(in_array[i], i, in_array[i]) !== false)
{
i++; // move to next item
if (i < in_array.length) setTimeout(bgEach, in_pause_ms);
}
}
return in_array; // returns array
};
jQuery.fn.forEach = function (in_callback, in_optional_pause_ms)
{
if (!in_optional_pause_ms) in_optional_pause_ms = 10; // default
return jQuery.forEach(this, in_optional_pause_ms, in_callback); // run it
};
La primera forma en que puedes usarlo es como cada ():
$(''your_selector'').forEach( function() {} );
Un segundo parámetro opcional le permite especificar la velocidad / retraso entre las iteraciones que puede ser útil para las animaciones ( el siguiente ejemplo esperará 1 segundo entre las iteraciones ):
$(''your_selector'').forEach( function() {}, 1000 );
Recuerde que dado que esto funciona de forma asíncrona, no puede confiar en que las iteraciones se completen antes de la siguiente línea de código, por ejemplo:
$(''your_selector'').forEach( function() {}, 500 );
// next lines of code will run before above code is complete
Escribí esto para un proyecto interno, y aunque estoy seguro de que se puede mejorar, funcionó para lo que necesitábamos, así que espero que algunos de ustedes lo encuentren útil. Gracias -
Cambiar el tipo de un elemento de entrada
Me encontré con este problema cuando intentaba cambiar el tipo de un elemento de entrada que ya estaba adjunto al DOM. Debe clonar el elemento existente, insertarlo antes del elemento anterior y luego eliminar el elemento antiguo. De lo contrario no funciona:
var oldButton = jQuery("#Submit");
var newButton = oldButton.clone();
newButton.attr("type", "button");
newButton.attr("id", "newSubmit");
newButton.insertBefore(oldButton);
oldButton.remove();
newButton.attr("id", "Submit");
Creando un elemento HTML y manteniendo una referencia.
var newDiv = $("<div />");
newDiv.attr("id", "myNewDiv").appendTo("body");
/* Now whenever I want to append the new div I created,
I can just reference it from the "newDiv" variable */
Comprobando si existe un elemento
if ($("#someDiv").length)
{
// It exists...
}
Escribiendo tus propios selectores
$.extend($.expr[":"], {
over100pixels: function (e)
{
return $(e).height() > 100;
}
});
$(".box:over100pixels").click(function ()
{
alert("The element you clicked is over 100 pixels height");
});
Definiendo propiedades en la creación de elementos.
En jQuery 1.4 puede usar un objeto literal para definir propiedades cuando cree un elemento:
var e = $("<a />", { href: "#", class: "a-class another-class", title: "..." });
... Incluso puedes agregar estilos:
$("<a />", {
...
css: {
color: "#FF0000",
display: "block"
}
});
Aquí hay un enlace a la documentación .
Eliminar elementos de una colección y preservar la capacidad de encadenamiento.
Considera lo siguiente:
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
</ul>
$("li").filter(function()
{
var text = $(this).text();
// return true: keep current element in the collection
if (text === "One" || text === "Two") return true;
// return false: remove current element from the collection
return false;
}).each(function ()
{
// this will alert: "One" and "Two"
alert($(this).text());
});
La función filter()
elimina elementos del objeto jQuery. En este caso: Se eliminarán todos los elementos-li que no contengan el texto "Uno" o "Dos".
Optimizar el rendimiento de los selectores complejos.
Consultar un subconjunto del DOM cuando se utilizan selectores complejos mejora drásticamente el rendimiento:
var subset = $("");
$("input[value^='''']", subset);
Saltos de línea y encadenamiento
Al encadenar múltiples llamadas en colecciones ...
$("a").hide().addClass().fadeIn().hide();
Puede aumentar la legibilidad con linebreaks. Me gusta esto:
$("a")
.hide()
.addClass()
.fadeIn()
.hide();
Soporte de atributos de datos HTML5, en los esteroides!
La función de datos ha sido mencionada anteriormente. Con él, puedes asociar datos con elementos DOM.
Recientemente, el equipo de jQuery ha agregado soporte para los atributos de datos * personalizados de HTML5 . Y como si eso no fuera suficiente; han alimentado a la fuerza la función de datos con esteroides, lo que significa que puede almacenar objetos complejos en forma de JSON, directamente en su marca.
El HTML:
<p data-xyz = ''{"str": "hi there", "int": 2, "obj": { "arr": [1, 2, 3] } }'' />
El JavaScript:
var data = $("p").data("xyz");
data.str // "hi there"
typeof data.str // "string"
data.int + 2 // 4
typeof data.int // "number"
data.obj.arr.join(" + ") + " = 6" // "1 + 2 + 3 = 6"
typeof data.obj.arr // "object" ... Gobbles! Errrghh!
Taquigrafía para el evento listo
La forma explícita y detallada:
$(document).ready(function ()
{
// ...
});
La taquigrafía:
$(function ()
{
// ...
});
Usar funciones anónimas autoejecutables en una llamada de método tal como .append()
iterar a través de algo. ES DECIR:
$("<ul>").append((function ()
{
var data = ["0", "1", "2", "3", "4", "5", "6"],
output = $("<div>"),
x = -1,
y = data.length;
while (++x < y) output.append("<li>" + info[x] + "</li>");
return output.children();
}()));
Uso esto para recorrer cosas que serían grandes e incómodas para romper mi encadenamiento para construir.
Uso juicioso de scripts jQuery de terceros, como la validación de campos de formulario o el análisis de URL. Vale la pena ver de qué se trata para saber cuándo será el próximo requisito de JavaScript.
Utilice .stop (verdadero, verdadero) cuando desencadene una animación que le impida repetir la animación. Esto es especialmente útil para animaciones de rollover.
$("#someElement").hover(function(){
$("div.desc", this).stop(true,true).fadeIn();
},function(){
$("div.desc", this).fadeOut();
});