Trucs et astuces jQuery

507

Syntaxe

Stockage de données

Optimisation

Divers

roosteronacid
la source

Réponses:

252

Créer un élément HTML et conserver une référence

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 */


Vérifier si un élément existe

if ($("#someDiv").length)
{
    // It exists...
}


Écrire vos propres sélecteurs

$.extend($.expr[":"], {
    over100pixels: function (e)
    {
        return $(e).height() > 100;
    }
});

$(".box:over100pixels").click(function ()
{
    alert("The element you clicked is over 100 pixels height");
});
Andreas Grech
la source
93
Écrire vos propres sélecteurs est assez
simple
22
De plus, si cela peut vous aider, vous pouvez réellement faire $ ("<div />") et réaliser la même chose que $ ("<div> </div>")
Hugoware
4
J'adore la nouvelle partie sélecteur, je n'en savais rien.
Pim Jager
5
Puisque je ne peux pas encore éditer les wikis de la communauté: Combinez l'affectation et le contrôle d'existence avecif ((var someDiv = $("#someDiv")).length) { /* do stuff with someDiv... */ }
Ben Blank
4
@Ben: La raison pour laquelle j'évite de tels idiomes en JavaScript est parce que je ne veux pas donner l'illusion d' someDivavoir une portée dans la ifdéclaration, car ce n'est pas le cas; JavaScript ne prend en charge que la portée des fonctions
Andreas Grech
111

La data()méthode de jQuery est utile et peu connue. Il vous permet de lier des données aux éléments DOM sans modifier le DOM.

clawr
la source
4
data () est en effet d'une grande aide.
Pim Jager
3
J'ai remarqué que cela ne fonctionne pas avec des éléments sans ID défini.
Penseur
20
@ Thinker: Oui, c'est le cas.
Alex Barrett
Utilisez data () au lieu de déclarer des variables globales js, imo.
Johan
95

Filtres d'imbrication

Vous pouvez imbriquer des filtres (comme l' a montré nickf ici ).

.filter(":not(:has(.selected))")
Nathan Long
la source
3
Bien que soyez prudent avec ceci ...: a effectué une recherche approfondie, donc cela peut devenir assez cher.
harpo
80

Je ne suis vraiment pas fan du $(document).ready(fn)raccourci. Bien sûr, cela réduit le code, mais cela réduit également la lisibilité du code. Quand vous voyez $(document).ready(...), vous savez ce que vous regardez. $(...)est utilisé de beaucoup trop de façons pour avoir immédiatement un sens.

Si vous avez plusieurs frameworks, vous pouvez utiliser jQuery.noConflict();comme vous le dites, mais vous pouvez également lui affecter une variable différente comme ceci:

var $j = jQuery.noConflict();

$j("#myDiv").hide();

Très utile si vous disposez de plusieurs frameworks qui peuvent être réduits à $x(...)des appels de style.

Oli
la source
1
@Oli: À propos du document en raccourci; vous avez raison. Mais jamais le moins: c'est un truc / astuce. Celui que j'utilise dans tout mon code uniquement parce que je pense qu'il "regarde" mieux. Une question de préférence personnelle, je suppose :)
cllpse
Chaque jour, je parcours des fichiers XML / XLS / XLST inutiles, des sites écrits avec beaucoup trop de couches d'abstraction, des systèmes de basculement complexes sur des sites qui ne dépasseront jamais le plus humble des serveurs ... et les gens se plaignent encore de la différence entre $ ( <chaîne>) & $ (<fonction>). Ça me donne envie de pleurer :)
JoeBloggs
Quand je vois $ (function () {...}) je sais ce qui se passe. Les choses les plus habituelles devraient être plus courtes. C'est pourquoi nous transformons les fragments de code fréquemment appelés en fonctions.
luikore
77

Ooooh, n'oublions pas les métadonnées jQuery ! La fonction data () est géniale, mais elle doit être remplie via des appels jQuery.

Au lieu de briser la conformité W3C avec des attributs d'élément personnalisés tels que:

<input 
  name="email" 
  validation="required" 
  validate="email" 
  minLength="7" 
  maxLength="30"/> 

Utilisez plutôt des métadonnées:

<input 
  name="email" 
  class="validation {validate: email, minLength: 2, maxLength: 50}" />

<script>
    jQuery('*[class=validation]').each(function () {
        var metadata = $(this).metadata();
        // etc.
    });
</script>
Filip Dupanović
la source
7
les attributs de données html5 rendent cela moins problématique; il y a une discussion en cours sur la mise en ligne des attributs de données html5 avec la fonction data () de jquery
Oskar Austegard
10
@Oskar - oui, cela a été implémenté dans jQuery 1.4.3 - les data-*attributs sont automatiquement disponibles via les appels à.data()
nickf
73

Gestionnaires d'événements en direct

Définissez un gestionnaire d'événements pour tout élément qui correspond à un sélecteur, même s'il est ajouté au DOM après le chargement initial de la page:

$('button.someClass').live('click', someFunction);

Cela vous permet de charger du contenu via ajax, ou de les ajouter via javascript et de configurer les gestionnaires d'événements correctement pour ces éléments automatiquement.

De même, pour arrêter la gestion des événements en direct:

$('button.someClass').die('click', someFunction);

Ces gestionnaires d'événements en direct ont quelques limitations par rapport aux événements réguliers, mais ils fonctionnent très bien dans la majorité des cas.

Pour plus d'informations, consultez la documentation jQuery .

MISE À JOUR: live()et die()sont obsolètes dans jQuery 1.7. Voir http://api.jquery.com/on/ et http://api.jquery.com/off/ pour des fonctionnalités de remplacement similaires.

UPDATE2: live()est obsolète depuis longtemps, même avant jQuery 1.7. Pour les versions jQuery 1.4.2+ avant 1.7, utilisez delegate()et undelegate(). L' live()exemple ( $('button.someClass').live('click', someFunction);) peut être réécrite en utilisant delegate()comme ça: $(document).delegate('button.someClass', 'click', someFunction);.

TM.
la source
1
Ouais, j'adore les nouveaux trucs live. Notez que cela ne fonctionne qu'à partir de jQuery 1.3.
Nosredna
4
+ 1..vous m'avez épargné beaucoup de maux de cœur .. Je viens de lire votre entrée et pendant que je prenais une pause - je résolvais pourquoi mon événement ne se déclenchait pas. Merci
Luke101
2
pour tous les autres retardataires de cet article, vous pouvez également consulter delegate (): api.jquery.com/delegate Similaire à live, mais plus efficace.
Oskar Austegard
2
N'oubliez pas que des bulles vivent jusqu'au corps afin que l'événement en direct lié puisse être déclenché. Si quelque chose sur le chemin annule cet événement, l'événement en direct ne se déclenchera pas.
nickytonline
1
live () et die () sont des méthodes obsolètes depuis la sortie de jQuery 1.7 le 3 novembre. Remplacé par on (), api.jquery.com/on et off (), api.jquery.com/off
Johan
46

Remplacez les fonctions anonymes par des fonctions nommées. Cela remplace vraiment le contexte jQuery, mais il entre plus en jeu, il semble que lorsque vous utilisez jQuery, en raison de sa dépendance à l'égard des fonctions de rappel. Les problèmes que j'ai avec les fonctions anonymes en ligne sont qu'ils sont plus difficiles à déboguer (beaucoup plus faciles à regarder une pile d'appels avec des fonctions distinctes, au lieu de 6 niveaux "anonymes"), et aussi le fait que plusieurs fonctions anonymes au sein de la même La chaîne jQuery peut devenir difficile à lire et / ou à entretenir. De plus, les fonctions anonymes ne sont généralement pas réutilisées; d'autre part, déclarer des fonctions nommées m'encourage à écrire du code plus susceptible d'être réutilisé.

Une illustration; au lieu de:

$('div').toggle(
    function(){
        // do something
    },
    function(){
        // do something else
    }
);

Je préfère:

function onState(){
    // do something
}

function offState(){
    // do something else
}

$('div').toggle( offState, onState );
ken
la source
Malheureusement, parce que jQuery transmet la cible d'événement en tant que this, vous ne pouvez pas obtenir une OO "correcte" sans utiliser de boîtiers. Je préfère généralement un compromis:$('div').click( function(e) { return self.onClick(e) } );
Ben Blank
3
Je suis désolé Ben, mais je ne vois pas en quoi votre commentaire a un rapport avec mon message. Peux-tu élaborer? Vous pouvez toujours utiliser 'self' (ou toute autre variable) en utilisant ma suggestion; cela ne changera rien de tout cela.
ken
Ouais, Ben, qu'est-ce que tu veux dire exactement?
James
2
Je dois mentionner: toujours la variable fur et les fonctions dans l'espace de noms pas dans root !!
jmav
45

Définition des propriétés lors de la création de l'élément

Dans jQuery 1.4, vous pouvez utiliser un littéral objet pour définir des propriétés lorsque vous créez un élément:

var e = $("<a />", { href: "#", class: "a-class another-class", title: "..." });

... Vous pouvez même ajouter des styles:

$("<a />", {
    ...
    css: {
        color: "#FF0000",
        display: "block"
    }
});

Voici un lien vers la documentation .

roosteronacid
la source
43

au lieu d'utiliser un alias différent pour l'objet jQuery (lors de l'utilisation de noConflict), j'écris toujours mon code jQuery en enveloppant le tout dans une fermeture. Cela peut être fait dans la fonction document.ready:

var $ = someOtherFunction(); // from a different library

jQuery(function($) {
    if ($ instanceOf jQuery) {
        alert("$ is the jQuery object!");
    }
});

vous pouvez également le faire comme ceci:

(function($) {
    $('...').etc()    // whatever jQuery code you want
})(jQuery);

Je trouve que c'est le plus portable. J'ai travaillé sur un site qui utilise simultanément Prototype ET jQuery et ces techniques ont évité tous les conflits.

nickf
la source
Le deuxième exemple est sympa pour les yeux :)
cllpse
25
Il y a une différence cependant, le premier exemple attendra le déclenchement de l'événement document.ready (), tandis que le second ne le fera pas.
SamBeran
1
@SamBeran: Vrai, le deuxième exemple s'exécutera immédiatement; cependant, si vous encapsulez un littéral objet, vous pouvez utiliser $ (document) .ready (...) à l'intérieur du littéral objet, ce qui signifie que vous pouvez spécifier quand vous souhaitez exécuter chaque morceau de code.
Wil Moore III
4
instanceOfne fonctionnera pas, seulement instanceof. Et ça ne marchera pas de toute façon, car ça jQuery instanceof jQueryreviendra false. $ == jQueryest la bonne façon de le faire.
nyuszika7h
@ Nyuszika7H: Oui, vous avez raison, mais ce n'est pas vraiment le but de l'exemple de code.
nickf
39

Vérifiez l'index

jQuery a .index mais c'est difficile à utiliser, car vous avez besoin de la liste des éléments, et passez l'élément dont vous voulez l'index:

var index = e.g $('#ul>li').index( liDomObject );

Ce qui suit est beaucoup plus facile:

Si vous voulez connaître l'index d'un élément dans un ensemble (par exemple des éléments de liste) dans une liste non ordonnée:

$("ul > li").click(function () {
    var index = $(this).prevAll().length;
});
redsquare
la source
Quel est le problème avec la méthode core index ()? Il est au cœur depuis au moins 1.2. docs.jquery.com/Core/index
ken
Ok, oui je jouais un peu l'avocat du diable, car en examinant l'index de jQuery (), j'ai réalisé que c'était une sorte de douleur dans le cul. Merci pour la clarification!
ken
4
C'est cool, mais il est important de savoir que cela ne fonctionne pas très bien si vous aviez des frères et sœurs précédents qui ne faisaient pas partie de la sélection.
TM.
2
Je suis assez sûr que depuis jQuery 1.4, vous pouvez simplement utiliser index()et obtenir l'index de son parent.
alex
@alex - bien sûr, mais notez la date de cet article - c'était 5 mois avant la version 1.4!
redsquare
23

Sténographie pour le prêt-événement

La manière explicite et verbeuse:

$(document).ready(function ()
{
    // ...
});

La sténographie:

$(function ()
{
    // ...
});
cllpse
la source
22

Sur la fonction jQuery principale, spécifiez le paramètre de contexte en plus du paramètre de sélecteur. La spécification du paramètre de contexte permet à jQuery de démarrer à partir d'une branche plus profonde dans le DOM, plutôt qu'à partir de la racine du DOM. Étant donné un DOM suffisamment grand, la spécification du paramètre de contexte devrait se traduire par des gains de performances.

Exemple: recherche toutes les entrées de type radio dans le premier formulaire du document.

$("input:radio", document.forms[0]);

Référence: http://docs.jquery.com/Core/jQuery#expressioncontext

lupefiasco
la source
10
Une note: $(document.forms[0]).find('input:radio')fait la même chose. Si vous regardez la source jQuery, vous verrez: si vous passez un deuxième paramètre à $, il appellera en fait .find().
nyuszika7h
Et ... $('form:first input:radio')?
daGrevis
Paul Irish a souligné dans paulirish.com/2009/perf (à partir de la diapositive 17) que cela est "à l'envers" du point de vue de la lisibilité. Comme l'a souligné @ Nyuszika7H, il utilise .find () en interne, et $ (document.forms [0]). Find ('input: radio') est très facile à lire, comparé à la mise en contexte dans le sélecteur initial.
LocalPCGuy
21

Pas vraiment jQuery mais j'ai fait un joli petit bridge pour jQuery et MS AJAX:

Sys.UI.Control.prototype.j = function Sys$UI$Control$j(){
  return $('#' + this.get_id());
}

C'est vraiment bien si vous faites beaucoup d'ASP.NET AJAX, car jQuery est pris en charge par MS ayant maintenant un joli pont signifie qu'il est vraiment facile de faire des opérations jQuery:

$get('#myControl').j().hide();

Ainsi, l'exemple ci-dessus n'est pas génial, mais si vous écrivez des contrôles serveur ASP.NET AJAX, il est facile d'avoir jQuery dans votre implémentation de contrôle côté client.

Aaron Powell
la source
La bibliothèque client ajax fournit-elle un moyen de trouver un contrôle par l'ID d'origine que vous avez attribué (dans le code derrière)
Chris S
this.get_id () vous renverra l'ID du contrôle dans la portée du client. L'ID spécifié par le serveur est irrelivant car l'ID client est généré en fonction de la hiérarchie cotrol parent
Aaron Powell
20

Optimiser les performances des sélecteurs complexes

Interroger un sous-ensemble du DOM lors de l'utilisation de sélecteurs complexes améliore considérablement les performances:

var subset = $("");

$("input[value^='']", subset);
cllpse
la source
7
Uniquement si ce sous-ensemble est mis en cache / enregistré.
Dykam
6
Ce n'est pas très différent de $ (""). Find ("input [value ^ = '']")
Chad Moran
1
@Dykam: ce que c'est, dans le cas de mon exemple de code. Mais votre argument est toujours valable.
cllpse
4
@Chad, il est en fait identique et correspond à la fonction que vous avez écrite
Mike Robinson
19

En parlant de trucs et astuces et aussi de quelques tutoriels. J'ai trouvé cette série de tutoriels ( série vidéo «jQuery for Absolute Beginners») par Jeffery Way sont TRÈS UTILES.

Il cible les développeurs qui ne connaissent pas jQuery. Il montre comment créer de nombreuses choses sympas avec jQuery, comme l'animation, la création et la suppression d'éléments et plus encore ...

J'en ai beaucoup appris. Il montre comment il est facile d'utiliser jQuery. Maintenant, je l'adore et je peux lire et comprendre n'importe quel script jQuery même s'il est complexe.

Voici un exemple que j'aime " Redimensionner le texte "

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- Style 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 todays video tutorial, Ill show you how to resize text every time an associated anchor tag is clicked. Well be examining the slice”, parseFloat”, and CSS Javascript/jQuery methods. 
    </p>
</div>

Recommande fortement ces tutoriels ...

http://blog.themeforest.net/screencasts/jquery-for-absolute-beginners-video-series/

egyamado
la source
19

Fonction each () asynchrone

Si vous avez des documents vraiment complexes où l'exécution de la fonction jquery each () verrouille le navigateur pendant l'itération, et / ou Internet Explorer affiche le message `` voulez-vous continuer à exécuter ce script '', cette solution sauvera la journée.

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 première façon de l'utiliser est comme chaque ():

$('your_selector').forEach( function() {} );

Un deuxième paramètre facultatif vous permet de spécifier la vitesse / le délai entre les itérations, ce qui peut être utile pour les animations ( l'exemple suivant attend 1 seconde entre les itérations ):

$('your_selector').forEach( function() {}, 1000 );

N'oubliez pas qu'étant donné que cela fonctionne de manière asynchrone, vous ne pouvez pas compter sur les itérations pour qu'elles soient terminées avant la ligne de code suivante, par exemple:

$('your_selector').forEach( function() {}, 500 );
// next lines of code will run before above code is complete


J'ai écrit ceci pour un projet interne, et même si je suis sûr qu'il peut être amélioré, cela a fonctionné pour ce dont nous avions besoin, alors j'espère que certains d'entre vous le trouveront utile. Merci -

OneNerd
la source
18

Syntactic shorthand-sugar-thing - Cache une collection d'objets et exécute des commandes sur une seule ligne:

Au lieu de:

var jQueryCollection = $("");

jQueryCollection.command().command();

Je fais:

var jQueryCollection = $("").command().command();

Un cas d'utilisation quelque peu «réel» pourrait être quelque chose dans ce sens:

var cache = $("#container div.usehovereffect").mouseover(function ()
{
    cache.removeClass("hover").filter(this).addClass("hover");
});
roosteronacid
la source
4
il vaut mieux mettre la référence $ (this) dans une variable locale, car vous prendrez un coup de perfomance mineur ici, car cela prendra un peu plus de temps ...
Sander Versluys
4
Dans ce cas (sans jeu de mots), je n'utilise "this" qu'une seule fois. Pas besoin de mise en cache.
cllpse le
1
Un petit conseil. Même si cela n'a pas d'importance dans ce cas, c'est toujours une mauvaise idée d'apporter des modifications supplémentaires au DOM. Disons par exemple que l'élément que vous survolez avait déjà la classe "hover". Vous supprimeriez cette classe et la rajouteriez. Vous pouvez contourner cela avec $(this).siblings().removeClass("hover"). Je sais que cela ressemble à une si petite chose, mais chaque fois que vous modifiez le DOM, un nouveau rafraîchissement du navigateur peut être déclenché. D'autres possibilités incluent les événements attachés à DOMAttrModified ou les classes modifiant la hauteur de l'élément qui pourraient déclencher d'autres écouteurs d'événements "redimensionner".
gradbot
1
Si vous souhaitez utiliser le cache et minimiser les modifications DOM, vous pouvez le faire. cache.not(this).removeClass("hover")
gradbot
@gradbot: Je ne comprends pas vos deux derniers commentaires. Pourriez-vous vous étendre?
Randomblue
15

J'aime déclarer un $this variable au début des fonctions anonymes, donc je sais que je peux référencer un jQueried this.

Ainsi:

$('a').each(function() {
    var $this = $(this);

    // Other code
});
Ben Crouse
la source
12
J'utilise "ça" à la place :)
cllpse
2
ROA: Oui, ce sera l'acide :) Vous pouvez également utiliser arguments.callee pour permettre à une fonction anonyme de se référencer
JoeBloggs
5
Joe - juste un avertissement, l'appelé partira avec ECMAScript 5 et le mode strict. Voir: ejohn.org/blog/ecmascript-5-strict-mode-json-and-more
Mike Robinson
@Joe Vous pourriez lui donner un nom, méfiez-vous des caprices d' IE .
alex
Excellent exemple également d'utiliser un $ au début du nom de la variable pour indiquer une variable d'objet jQuery par rapport à une variable standard. En ajoutant cela au début de toute variable qui met en cache un objet jQuery, vous savez immédiatement en le regardant que vous pouvez exécuter des fonctions jQuery sur la variable. Rend le code beaucoup plus lisible immédiatement.
LocalPCGuy
14

Enregistrer des objets jQuery dans des variables pour les réutiliser

L'enregistrement d'un objet jQuery dans une variable vous permet de le réutiliser sans avoir à rechercher dans le DOM pour le trouver.

(Comme l'a suggéré @Louis, j'utilise maintenant $ pour indiquer qu'une variable contient un objet 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...

À titre d'exemple plus complexe, supposons que vous ayez une liste d'aliments dans un magasin et que vous souhaitiez n'afficher que ceux qui correspondent aux critères d'un utilisateur. Vous avez un formulaire avec des cases à cocher, chacune contenant un critère. Les cases à cocher ont des noms comme organicet lowfat, et les produits ont des classes correspondantes - .organic, etc.

var $allFoods, $matchingFoods;
$allFoods = $('div.food');

Vous pouvez maintenant continuer à travailler avec cet objet jQuery. Chaque fois qu'une case est cochée (pour cocher ou décocher), commencez à partir de la liste principale des aliments et filtrez en fonction des cases cochées:

// 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();
});
Nathan Long
la source
8
Ma convention de dénomination est d'avoir un $devant. par exemplevar $allItems = ...
Louis
6
@Lavinski - Je pense que l'idée est que le $indique qu'il s'agit d'un objet jQuery, ce qui faciliterait la différenciation visuelle des autres variables.
Nathan Long
@Louis - J'ai depuis adopté votre convention et je mettrai à jour ma réponse en conséquence. :)
Nathan Long
11

Il semble que la plupart des conseils intéressants et importants aient déjà été mentionnés, donc celui-ci n'est qu'un petit ajout.

La petite astuce est la fonction jQuery.each (objet, rappel) . Tout le monde utilise probablement le jQuery.each (rappel) pour itérer sur l'objet jQuery lui-même, car il est naturel. La fonction utilitaire jQuery.each (objet, rappel) parcourt les objets et les tableaux. Pendant longtemps, je ne savais pas en quoi cela pouvait servir en dehors d'une syntaxe différente (cela ne me dérange pas d'écrire toutes les boucles façonnées), et j'ai un peu honte de n'avoir réalisé sa force principale que récemment.

Le fait est que puisque le corps de la boucle dans jQuery.each (objet, rappel) est une fonction , vous obtenez une nouvelle portée à chaque fois dans la boucle, ce qui est particulièrement pratique lorsque vous créez des fermetures dans la boucle.

En d'autres termes, une erreur courante typique est de faire quelque chose comme:

var functions = [];
var someArray = [1, 2, 3];
for (var i = 0; i < someArray.length; i++) {
    functions.push(function() { alert(someArray[i]) });
}

Maintenant, lorsque vous appelez les fonctions du functionstableau, vous obtiendrez une alerte trois fois avec le contenu undefinedqui n'est probablement pas ce que vous vouliez. Le problème est qu'il n'y a qu'une seule variable iet que les trois fermetures s'y réfèrent. Une fois la boucle terminée, la valeur finale de iest 3 et someArrary[3]est undefined. Vous pouvez contourner ce problème en appelant une autre fonction qui créerait la fermeture pour vous. Ou vous utilisez l'utilitaire jQuery qui le fera essentiellement pour vous:

var functions = [];
var someArray = [1, 2, 3];
$.each(someArray, function(item) {
    functions.push(function() { alert(item) });
});

Maintenant, lorsque vous appelez les fonctions, vous obtenez trois alertes avec le contenu 1, 2 et 3 comme prévu.

En général, ce n'est rien que vous ne pourriez pas faire vous-même, mais c'est agréable à avoir.

Jan Zich
la source
11

Accédez aux fonctions jQuery comme vous le feriez pour un tableau

Ajouter / supprimer une classe basée sur un booléen ...

function changeState(b)
{
    $("selector")[b ? "addClass" : "removeClass"]("name of the class");
}

Est la version courte de ...

function changeState(b)
{
    if (b)
    {
        $("selector").addClass("name of the class");
    }
    else
    {
        $("selector").removeClass("name of the class");
    }
}

Pas autant de cas d'utilisation pour cela. Néanmoins; Je pense que c'est bien :)


Mise à jour

Juste au cas où vous n'êtes pas du type lecture-commentaire, ThiefMaster souligne que le toggleClass accepte une valeur booléenne , qui détermine si une classe doit être ajoutée ou supprimée. Donc, en ce qui concerne mon exemple de code ci-dessus, ce serait la meilleure approche ...

$('selector').toggleClass('name_of_the_class', true/false);
roosteronacid
la source
2
C'est bien et a des utilisations intéressantes, mais ce n'est pas du tout spécifique à jQuery ... c'est juste quelque chose que vous pouvez faire sur n'importe quel objet JavaScript.
TM.
1
Merci :) ... C'est du JavaScript basique; Ouais. Mais je dirais que jQuery est JavaScript. Je ne prétends pas que c'est spécifique à jQuery.
cllpse du
7
Dans ce cas spécifique, vous voulez vraiment l'utiliser $('selector').toggleClass('name_of_the_class', b);.
ThiefMaster
9

Mise à jour:

Incluez simplement ce script sur le site et vous obtiendrez une console Firebug qui apparaîtra pour le débogage dans n'importe quel navigateur. Pas tout à fait aussi complet mais c'est toujours très utile! N'oubliez pas de le retirer lorsque vous avez terminé.

<script type='text/javascript' src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>

Consultez ce lien:

De CSS Tricks

Mise à jour: j'ai trouvé quelque chose de nouveau; c'est le JQuery Hotbox.

JQuery Hotbox

Google héberge plusieurs bibliothèques JavaScript sur Google Code. Le charger à partir de là économise de la bande passante et il charge rapidement car il a déjà été mis en cache.

<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>

Ou

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script>

Vous pouvez également l'utiliser pour savoir quand une image est entièrement chargée.

$('#myImage').attr('src', 'image.jpg').load(function() {  
    alert('Image Loaded');  
});

Le "console.info" de firebug, que vous pouvez utiliser pour vider des messages et des variables à l'écran sans avoir à utiliser des boîtes d'alerte. "console.time" vous permet de configurer facilement une minuterie pour envelopper un tas de code et voir combien de temps cela prend.

console.time('create list');

for (i = 0; i < 1000; i++) {
    var myList = $('.myList');
    myList.append('This is list item ' + i);
}

console.timeEnd('create list');
3 tours
la source
ppl en Iran ne peut pas voir les pages Web chargées avec Google api. en fait, Google a restreint les Iraniens à accéder au code Google. so -1
Alireza Eliaderani
Je viens de découvrir que vous pouvez utiliser Firebug dans n'importe quel navigateur. C'est génial.
Tebo
9

Utilisez des méthodes de filtrage sur les pseudo-sélecteurs lorsque cela est possible afin que jQuery puisse utiliser querySelectorAll (ce qui est beaucoup plus rapide que sizzle). Considérez ce sélecteur:

$('.class:first')

La même sélection peut être effectuée en utilisant:

$('.class').eq(0)

Ce qui doit être plus rapide car la sélection initiale de '.class' est compatible QSA

Ralph Holzmann
la source
@ Nyuszika7H Je pense que vous manquez le point. Le fait est que QSA ne peut pas optimiser la plupart des pseudo-sélecteurs, donc $ ('. Class: eq (0)') serait plus lent que $ ('. Class'). Eq (0).
Ralph Holzmann
9

Supprimer des éléments d'une collection et préserver la chaînabilité

Considérer ce qui suit:

<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 filter()fonction supprime des éléments de l'objet jQuery. Dans ce cas: tous les éléments li ne contenant pas le texte "Un" ou "Deux" seront supprimés.

roosteronacid
la source
N'est-il pas plus simple d'utiliser simplement "chacun" et de déplacer le changement de marge à l'intérieur du commutateur?
DisgruntledGoat
Mis à jour ma réponse. S'il vous plaît laissez-moi savoir si je me fais comprendre (
euh
Cela enlève-t-il vraiment les éléments li? Il semble alerter avec une liste filtrée d'éléments.
Cheeso
1
La fonction de filtre supprime les éléments de la collection à l'intérieur de l'objet jQuery. Cela n'affecte pas le DOM.
cllpse
6
Dans votre fonction de filtrage, vous pouvez simplement écrire: return !! $ (this) .text (). Match (/ One | Two /); ;)
Vincent
8

Modification du type d'un élément d'entrée

J'ai rencontré ce problème lorsque j'essayais de changer le type d'un élément d'entrée déjà attaché au DOM. Vous devez cloner l'élément existant, l'insérer avant l'ancien élément, puis supprimer l'ancien élément. Sinon ça ne marche pas:

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");
Vivin Paliath
la source
7

Utilisation judicieuse de scripts jQuery tiers, tels que la validation de champ de formulaire ou l'analyse d'url. Cela vaut la peine de voir de quoi il s'agit afin que vous sachiez la prochaine fois que vous rencontrez une exigence JavaScript.

harriyott
la source
7

Sauts de ligne et chaînabilité

Lors du chaînage de plusieurs appels sur des collections ...

$("a").hide().addClass().fadeIn().hide();

Vous pouvez augmenter la lisibilité avec les sauts de ligne. Comme ça:

$("a")
.hide()
.addClass()
.fadeIn()
.hide();
cllpse
la source
4
Dans ce cas, le premier est plus lisible, mais oui, il y a des cas où les sauts de ligne augmentent la lisibilité.
nyuszika7h
7

Utilisez .stop (true, true) lorsque le déclenchement d'une animation l'empêche de répéter l'animation. Ceci est particulièrement utile pour les animations de survol.

$("#someElement").hover(function(){
    $("div.desc", this).stop(true,true).fadeIn();
},function(){
    $("div.desc", this).fadeOut();
});
Kenneth J
la source
7

Utiliser des fonctions anonymes auto-exécutables dans un appel de méthode de manière .append()à parcourir quelque chose. C'EST À DIRE:

$("<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();
}()));

Je l'utilise pour parcourir des choses qui seraient grandes et inconfortables pour sortir de mon enchaînement à construire.

Rixius
la source
5

Prise en charge des attributs de données HTML5, sur les stéroïdes!

La fonction de données a déjà été mentionnée. Avec lui, vous pouvez associer des données à des éléments DOM.

Récemment, l'équipe jQuery a ajouté la prise en charge des attributs de données * personnalisés HTML5 . Et comme si cela ne suffisait pas; ils ont alimenté la fonction de données avec des stéroïdes, ce qui signifie que vous pouvez stocker des objets complexes sous forme de JSON, directement dans votre balisage.

Le HTML:

<p data-xyz = '{"str": "hi there", "int": 2, "obj": { "arr": [1, 2, 3] } }' />


Le 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!
roosteronacid
la source