Est-il possible d'avoir un événement dans JS qui se déclenche lorsque la valeur d'une certaine variable change? JQuery est accepté.
javascript
jquery
dom-events
rashcroft22
la source
la source
variable
, mais toutes les réponses se réfèrent iciproperty
. Je me demande si nous pouvons écouter leslocal variable
changements.Réponses:
Oui, c'est désormais tout à fait possible!
Je sais que c'est un vieux fil mais maintenant cet effet est possible en utilisant des accesseurs (getters et setters): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters
Vous pouvez définir un objet comme celui-ci, dans lequel
aInternal
représente le champa
:Vous pouvez ensuite enregistrer un auditeur en utilisant les éléments suivants:
Ainsi, chaque fois que quelque chose change la valeur de
x.a
, la fonction d'écoute sera déclenchée. L'exécution de la ligne suivante fera apparaître la fenêtre d'alerte:Voir un exemple ici: https://jsfiddle.net/5o1wf1bn/1/
Vous pouvez également utiliser un tableau d'écouteurs au lieu d'un seul emplacement d'écoute, mais je voulais vous donner l'exemple le plus simple possible.
la source
this.aListener(val)
, vous devrez parcourir toutes les fonctions d'écoute et appeler chacune en passantval
. En règle générale, la méthode est appelée à laaddListener
place deregisterListener
.La plupart des réponses à cette question sont obsolètes, inefficaces ou nécessitent l'inclusion de grandes bibliothèques gonflées:
Aujourd'hui, vous pouvez désormais utiliser l' objet Proxy pour surveiller (et intercepter) les modifications apportées à un objet. Il est spécialement conçu pour ce que le PO essaie de faire. Voici un exemple de base:
Les seuls inconvénients de l'
Proxy
objet sont:Proxy
objet n'est pas disponible dans les anciens navigateurs (comme IE11) et le polyfill ne peut pas répliquer entièrement laProxy
fonctionnalité.Date
) - l'Proxy
objet est mieux couplé avec des objets ou des tableaux simples.Si vous devez observer les modifications apportées à un objet imbriqué , vous devez utiliser une bibliothèque spécialisée telle que Observable Slim (que j'ai publiée) qui fonctionne comme ceci:
la source
target.hello_world = "test"
)you don't actually watch changes on the target object but only on proxy object
- ce n'est pas tout à fait exact. L'Proxy
objet n'est pas modifié - il n'a pas sa propre copie de la cible.you just want to know when a property change on the target object
- vous pouvez accomplir cela avec unProxy
, c'est l'un des principaux cas d'utilisation des proxys.target
, vous devez le faire via un proxy. Cependant,proxy.hello_world = "test"
cela ne signifie pas que vous modifiez le proxy, le proxy reste inchangé,target
est modifié (si votre gestionnaire d'ensemble est configuré pour le faire). On dirait que votre point est que vous ne pouvez pas observer directementtarget.hello_world = "test"
. C'est vrai. Les affectations de variables simples n'émettent aucun type d'événement. C'est pourquoi nous devons utiliser des outils comme ceux décrits dans les réponses à cette question.It sounds like your point is that you cannot directly observe target.hello_world = "test". That is true.
c'est exactement ce que je veux dire. Dans mon cas, j'ai un objet créé ailleurs et mis à jour par un autre code ... un proxy, dans ce cas, n'est pas utile car les modifications seront effectuées sur la cible.Non.
Mais, si c'est vraiment si important, vous avez 2 options (la première est testée, la seconde ne l'est pas):
Tout d'abord, utilisez des setters et des getters, comme ceci:
alors vous pouvez faire quelque chose comme:
puis définissez l'auditeur comme:
Deuxièmement, j'ai en fait oublié, je vais soumettre pendant que j'y pense :)
EDIT: Oh, je me souviens :) Vous pouvez mettre une montre sur la valeur:
Étant donné myobj ci-dessus, avec 'a' dessus:
la source
En utilisant
Prototype
: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/definePropertyAutre exemple
la source
varw
nécessite 2 arguments mais une partie de votre exemple montre que la fonction est appelée avec juste le paramètre value.Désolé de faire apparaître un vieux fil, mais voici un petit manuel pour ceux qui (comme moi!) Ne voient pas comment l'exemple d'Eli Grey fonctionne:
J'espère que cela peut aider quelqu'un
la source
Comme la réponse de Luke Schafer ( note : cela fait référence à son message d'origine; mais le point ici reste valable après la modification ), je suggère également une paire de méthodes Get / Set pour accéder à votre valeur.
Cependant, je suggérerais quelques modifications (et c'est pourquoi je poste ...).
Un problème avec ce code est que le champ
a
de l'objetmyobj
est directement accessible, il est donc possible d'y accéder / changer sa valeur sans déclencher les écouteurs:Encapsulation
Donc, pour garantir que les auditeurs sont effectivement appelés, il faudrait interdire cet accès direct au terrain
a
. Comment faire Utilisez une fermeture !Vous pouvez maintenant utiliser la même méthode pour créer et ajouter les écouteurs comme l'a proposé Luke, mais vous pouvez être assuré qu'il n'y a aucun moyen possible de lire ou d'écrire
a
passer inaperçu!Ajout de champs encapsulés par programme
Toujours sur la piste de Luke, je propose maintenant un moyen simple d'ajouter des champs encapsulés et les getters / setters respectifs aux objets au moyen d'un simple appel de fonction.
Notez que cela ne fonctionnera correctement qu'avec les types de valeur . Pour que cela fonctionne avec les types de référence , une sorte de copie complète devrait être implémentée (voir celle-ci , par exemple).
Cela fonctionne de la même manière qu'auparavant: nous créons une variable locale sur une fonction, puis nous créons une fermeture.
Comment l'utiliser? Facile:
la source
Si vous utilisez jQuery {UI} (que tout le monde devrait utiliser :-)), vous pouvez utiliser .change () avec un élément <input /> caché.
la source
<input/>
élément caché ?<input type="hidden" value="" id="thisOne" />
et avec jQuery$("#thisOne").change(function() { do stuff here });
et$("#thisOne").val(myVariableWhichIsNew);
puis le.change()
feu se déclenche.var1 = 'new value';
, vous allez plutôt définir la valeur de cette entrée cachée, puis ajouter un écouteur pour changer la variable.$("#val1").on('change', function(){ val1 = this.val(); ... do the stuff that you wanted to do when val1 changed... }); $("#val1").val('new value');
AngularJS
(Je sais que ce n'est pas le casJQuery
, mais cela pourrait aider. [Pure JS est bon en théorie uniquement]):où "data" est le nom de votre variable dans la portée.
Il y a un lien vers doc.
la source
$scope.$apply()
est exécutéPour ceux qui accordent quelques années plus tard:
Une solution pour la plupart des navigateurs (et IE6 +) est disponible qui utilise l'événement onpropertychange et la nouvelle spécification defineProperty. Le léger hic, c'est que vous devrez faire de votre variable un objet dom.
Tous les détails:
http://johndyer.name/native-browser-get-set-properties-in-javascript/
la source
La fonctionnalité que vous recherchez peut être obtenue grâce à l'utilisation de la méthode "defineProperty ()" - qui n'est disponible que pour les navigateurs modernes:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
J'ai écrit une extension jQuery qui a des fonctionnalités similaires si vous avez besoin de plus de support multi-navigateurs:
https://github.com/jarederaj/jQueue
la source
Pas directement: vous avez besoin d'une paire getter / setter avec une interface "addListener / removeListener" de quelque sorte ... ou un plugin NPAPI (mais c'est une autre histoire).
la source
ou
ou
la source
Une solution assez simple et simpliste consiste à simplement utiliser un appel de fonction pour définir la valeur de la variable globale et ne jamais définir sa valeur directement. De cette façon, vous avez un contrôle total:
Il n'y a aucun moyen d'imposer cela, cela nécessite simplement une discipline de programmation ... bien que vous puissiez utiliser
grep
(ou quelque chose de similaire) pour vérifier que votre code ne définit directement la valeur deglobalVar
.Ou vous pouvez l'encapsuler dans un objet et des méthodes getter et setter utilisateur ... juste une pensée.
la source
var
dans les modules ES6 - c'est la seule solution.Veuillez vous rappeler que la question initiale était pour les VARIABLES, pas pour les OBJETS;)
en plus de toutes les réponses ci-dessus, j'ai créé une minuscule bibliothèque appelée forTheWatch.js , qui utilise la même manière pour intercepter et rappeler les modifications des variables globales normales en javascript.
Compatible avec les variables JQUERY, pas besoin d'utiliser des OBJETS, et vous pouvez passer directement un TABLEAU de plusieurs variables si nécessaire.
Si cela peut être utile ...: https://bitbucket.org/esabora/forthewatch
Fondamentalement, il vous suffit d'appeler la fonction:
watchIt("theVariableToWatch", "varChangedFunctionCallback");
Et désolé par avance si non pertinent.
la source
La façon la plus simple que j'ai trouvée, à partir de cette réponse :
Et alors:
la source
Dans mon cas, j'essayais de savoir si une bibliothèque que j'incluais dans mon projet redéfinissait la mienne
window.player
. Donc, au début de mon code, je viens de faire:la source
Ce n'est pas directement possible.
Cependant, cela peut être fait en utilisant CustomEvent: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
La méthode ci-dessous accepte un tableau de noms de variables en entrée et ajoute un écouteur d'événements pour chaque variable et déclenche l'événement pour toute modification de la valeur des variables.
La méthode utilise l'interrogation pour détecter la modification de la valeur. Vous pouvez augmenter la valeur du délai d'expiration en millisecondes.
En appelant la méthode:
Il détectera les modifications apportées aux variables nom d'utilisateur et ID utilisateur.
la source
Avec l'aide de getter et setter , vous pouvez définir une classe JavaScript qui fait une telle chose.
Tout d'abord, nous définissons notre classe appelée
MonitoredVariable
:Supposons que nous voulons écouter les
money
changements, créons une instance deMonitoredVariable
avec de l'argent initial0
:Ensuite, nous pourrions obtenir ou définir sa valeur en utilisant
money.val
:Puisque nous n'avons défini aucun écouteur pour cela, rien de spécial ne se produit après
money.val
modifications apportées à 2.Définissons maintenant certains écouteurs. Nous avons quatre auditeurs disponibles:
beforeSet
,beforeChange
,afterChange
,afterSet
. Les événements suivants se produisent séquentiellement lorsque vous utilisezmoney.val = newValue
pour modifier la valeur de la variable:Maintenant, nous définissons l'
afterChange
écouteur qui ne sera déclenché qu'après avoirmoney.val
changé (alors queafterSet
sera déclenché même si la nouvelle valeur est la même que l'ancienne):Maintenant, définissez une nouvelle valeur
3
et voyez ce qui se passe:Vous verrez ce qui suit dans la console:
Pour le code complet, voir https://gist.github.com/yusanshi/65745acd23c8587236c50e54f25731ab .
la source
C'est un vieux fil de discussion mais je suis tombé sur la deuxième réponse la plus élevée (écouteurs personnalisés) tout en recherchant une solution utilisant Angular. Alors que la solution fonctionne, angular a une meilleure manière intégrée de résoudre ce problème en utilisant des
@Output
émetteurs d'événements. En sortant de l'exemple dans l'écouteur personnalisé, répondez:ChildComponent.html
ChildComponent.ts
ParentComponent.html
ParentComponent.ts
Cela sera désormais mis à jour
n
sur le parent à chaque fois que le bouton enfant est cliqué. Stackblitz de travailla source
la source