2010-02-03 3 views
0

Je suis vraiment confus, et je ne sais même pas quoi chercher pour trouver des réponses. Je reçois plusieurs appels à une fonction javascript. Cela n'a pas de sens pour moi.jquery live incrémenter automatiquement l'événement de touche

Voici ce que fait le code.

$('expenses_txt').live(\'keyup\', function() { 
    $(this).typeWatch({ highlight: true, wait: 500, captureLength: 0, callback: calculate_expenses }); 
}); 

Le « Calculate_expenses » est une fonction javascript qui utilise ajax jquery pour appeler une page php qui renvoie des données qui obtient affiché dans une travée. J'utilise firebug pour m'aider à déboguer et dans la fonction Calculate_expenses je mets un "console.log" à déboguer lorsque cette fonction est appelée.

Voici ce qui se passe. J'ai seulement 1 boîte d'entrée dans le DOM au moment où cela se produit, quand je presse une seule touche, la sortie dans la console met un message de débogage comme il le devrait, quand j'appuie à nouveau sur une touche dans la même entrée la console est doublée (la fonction Calculate_expenses a été appelée deux fois mais ne devrait être appelée qu'une fois), quand j'appuie à nouveau sur une touche (pour un total de 3 pressions), la sortie de la console émet 3 appels à la fonction Calculate_expenses maintenant ..... et ainsi de suite. Je ne sais pas vraiment ce qui se passe ici. Le code me semble que cela ne ferait qu'appeler la fonction Calculate_expenses 1 fois, mais quand j'utilise firebug, il est appelé plusieurs fois quand je ne le veux pas.

Des idées? Est-ce la façon dont j'utilise .live() Si j'utilise simplement l'événement "keyup" cela fonctionne très bien, le problème est que j'ai besoin d'utiliser plugin typeWatch pour retarder l'appel ajax jusqu'à ce que la frappe soit terminée et que l'évènement keyup se déclenche bientôt. La raison pour laquelle j'utilise live() est que j'ajoute dynamiquement des éléments au dom et c'est la seule façon de comprendre comment utiliser à la fois typeWatch et ajouter dynamiquement des éléments au dom qui doit être résumé ...

vos pensées sont appréciées. Merci.

+0

Quelle méthode utilisez-vous pour ajouter dynamiquement des éléments au dom? – user113716

+0

patrick, j'ai pris votre suggestion plus tôt dans une autre question que j'ai dû utiliser .clone (true), qui a résolu le problème avec le keyup n'étant pas copié dans les nouvelles boîtes de saisie créées. Le problème est survenu quand j'ai essayé d'utiliser le plugin typeWatch ... cela ne fonctionnait que sur la 1ère case d'entrée, celles ajoutées dynamiquement ne se déclencheraient pas. C'est comme le problème que j'avais avant de résoudre avec .clone (true), mon seul problème est que "keyup" est standard, et que "typeWatch" ne l'est pas. D'autres pensées? – Ronedog

Répondre

0

Bien, rien avec live et typewatch travaillé ... contourner était d'utiliser onblur et laisser le .clone() le copier.

0

Où est placé le bloc $('expenses_txt').live()? Il semble que ce soit déclenché plusieurs fois.

Définissez un point d'arrêt (onglet Script firebug, cliquez dans la marge de gauche autour des numéros de ligne) sur la ligne $('expenses_txt').live(). Cela ne devrait déclencher qu'une seule fois. S'il se déclenche plusieurs fois, vous verrez facilement une trace de pile (ce qui devrait vous ramener au coupable).

Définissez également un point d'arrêt à l'intérieur de la fermeture (où vous utilisez typeWatch). La partie typeWatch peut être le coupable car elle se réinstancie à chaque keyup (indépendamment du fait que this a déjà été "traité" (et lier le callback plusieurs fois)

Si c'est typeWatch au travail, vous aurez envie . pour vérifier si elle est liée en quelque sorte la chose la plus simple serait de marquer l'élément DOM en quelque sorte, vous pouvez, par exemple l'utilisation.

jQuery('#element').data('hasTypeWatch',true) 

de définir le drapeau d'abord vérifiez pour l'aide.

jQuery('#element').data('hasTypeWatch') 

Vérifiez les documents du plugin pour voyez-le l'auteur a expliqué cela en quelque sorte.

+0

J'ajoute cette page via php et j'écoute la chaîne. Le script Jquery est dans cette chaîne. Je peux ajouter des points d'arrêt à tous les éléments de mon fichier .js, mais je ne peux pas voir le script jquery dans firebug pour placer un point d'arrêt où le .live() est. Le .live() est dans la partie document.ready de ce script. Je pense que le .live() est en quelque sorte le coupable, parce que quand je l'enlève, ça marche. Le problème est que j'ai utilisé .live() parce que quand j'ai ajouté dynamiquement un nouvel élément au DOM, il ne lierait pas l'événement typeWatch, et je suis assez nouveau pour jquery, je ne suis pas vraiment sûr du travail autour . – Ronedog

+0

Vous êtes sur la bonne voie avec l'utilisation de 'live' pour ce cas (appliquer la liaison d'événement maintenant + tous les futurs éléments dom - c'est en fait une idée vraiment cool). L'onglet Script de Firebug vous montrera généralement tout le script.js fichiers, tous les scripts créés dynamiquement, tous les scripts qui apparaissent dans le corps du document. La recherche (côté droit) est sensible au contexte et très utile. Vous devriez être capable de l'utiliser pour chercher votre chemin vers le coupable. Il y a aussi une petite flèche vers le bas dans l'onglet Script où vous pouvez configurer exactement les scripts à afficher. – Koobz

+0

Eh bien, j'ai trouvé comment obtenir le js dymanic à montrer dans firebug, mais je ne peux pas résoudre ce problème. si je supprime .live() le problème disparaît ... mais j'ai vraiment besoin d'être capable de lier les boîtes de saisie dynamiques aux événements ... je suppose que je vais devoir trouver un travail. merci pour l'aide de toute façon – Ronedog

0

Voici un mockup:

function handleData(data){ 
    console.log(data); 
    $("#results").append("<p>"+ data +"</p>"); 
} 

$(function(){ 
    $("#inputElm").focus(); 
    $("#inputElm").live('keyup', function(){ 
     $(this).typeWatch({ 
      callback: handleData, 
      wait: 500, 
      captureLength: 0 
     }); 
    }); 
}); 

Notez la console enregistre plusieurs appels à la méthode de typeWatch sur chaque keyup, selon le commentaire par Koobz. Je pense que vous voulez omettre le $.Live() handler et simplement attacher typeWatch à votre entrée.

0

Eh bien, je suis encore vraiment confus. Koobz, merci pour l'astuce firebug. J'ai découvert où je pouvais voir le script, mais les points d'arrêt ne semblent pas fonctionner, ou arrêter le code, il arrête le code très bien dans mon fichier .js qui est chargé avec l'application principale, mais le script qui est ajouter dynamiquement lorsque la page particulière charge ne semble pas reconnaître les points d'arrêt et s'arrêter à eux, donc je ne peux pas parcourir le code.

J'ai remarqué quelque chose d'étrange, mais il se peut que ce soit moi en tant que cinglé, mais les fonctions de jquery s'affichent sans $(). Par exemple: le code jquery dans mon code source est écrit comme:.

$ ('de income_txt') vivent ('keyup', function() { $ (this) .typeWatch ({point fort: true, wait: 500, captureLength: -1, callback: calculate_income}); });

mais quand on regarde l'onglet script Firebug, il ressemble à ceci:

function() { $ (this) .typeWatch ({point fort: true, attendez: 500, captureLength: -1, rappel: calculate_income }); }

Est-ce ce que jquery est supposé faire? Je suppose qu'il est lié au "sélecteur" et n'a donc pas besoin d'afficher le sélecteur devant lui, il utilise plutôt "function()" ... est-ce correct? Toutes les autres idées sur le truc .live(), ou un travail différent pour utiliser typeWatch, peu importe ce que j'essaie appelle encore la fonction plusieurs fois, à moins que je supprime le .live(). Si je n'utilise pas .live() le typewatch fonctionne sur l'événement keyup, mais de nouveaux éléments ajoutés dynamiquement au dom en utilisant .clone (true) ne fonctionnent pas sur cet objet et que typeWatch ne se déclenche pas. Je ne sais pas comment lier les objets nouvellement créés à l'événement qui utilise typewatch, autre que l'utilisation de .live(), ce qui provoque d'autres problèmes. Si j'oublie d'utiliser typeWatch et lie mon événement keyup au sélecteur, cela fonctionne, mais le problème principal est de le faire de cette façon, il appelle l'ajax trop vite et provoque des problèmes à chaque frappe.

Existe-t-il d'autres façons d'accomplir ce que j'essaie de faire? Merci de votre aide.