2009-10-01 9 views
4

Je viens de commencer à utiliser javascript et il me manque quelque chose d'important à ma connaissance. J'espérais que vous pourriez m'aider à combler le vide. Par conséquent, le script que j'essaie d'exécuter suppose de compter les caractères dans un champ de texte et de mettre à jour un paragraphe pour indiquer à l'utilisateur le nombre de caractères qu'il a tapés. J'ai un objet appelé charCounter. sourceId est l'identifiant de la zone de texte pour compter les caractères. statusId est l'identifiant du paragraphe à mettre à jour chaque fois qu'une touche est enfoncée.Comment exécuter la méthode onEvent d'un objet en javascript?

function charCounter(sourceId, statusId) { 
    this.sourceId = sourceId; 
    this.statusId = statusId; 
    this.count = 0; 
} 

Il existe une méthode appelée updateAll. Il met à jour le nombre de caractères et met à jour le paragraphe.

charCounter.prototype.updateAll = function() { 
    //get the character count; 
    //change the paragraph; 
} 

J'ai une fonction de démarrage qui est appelée lorsque la fenêtre se charge.

function start() { 
    //This is the problem 
    document.getElementbyId('mytextfield').onkeydown = myCounter.updateAll; 
    document.getElementbyId('mytextfield').onkeyup = myCounter.updateAll; 
} 

myCounter = new charCounter("mytextfield","charcount"); 
window.onload = start; 

Le code ci-dessus est le problème. Pourquoi dans le monde ne puis-je pas appeler la méthode myCounter.updateAll lorsque l'événement est déclenché? C'est vraiment déroutant pour moi. Je comprends que si vous appelez une méthode likeThis() vous obtiendrez une valeur de la fonction. Si vous l'appelez comme ceci vous obtenez un pointeur vers une fonction. Je pointe mon événement vers une fonction. J'ai également essayé d'appeler la fonction directement et cela fonctionne très bien, mais cela ne fonctionnera pas quand l'événement est déclenché.

Qu'est-ce qui me manque?


Merci pour toutes les réponses. Voici trois implémentations différentes.

Application 1

function CharCounter(sourceId, statusId) { 
    this.sourceId = sourceId; 
    this.statusId = statusId; 
    this.count = 0; 
}; 
    CharCounter.prototype.updateAll = function() { 
     this.count = document.getElementById(this.sourceId).value.length; 
     document.getElementById(this.statusId).innerHTML = "There are "+this.count+" charactors"; 
    }; 

function start() { 
    myCharCounter.updateAll(); 
    document.getElementById('mytextfield').onkeyup = function() { myCharCounter.updateAll(); }; 
    document.getElementById('mytextfield').onkeydown = function() { myCharCounter.updateAll(); }; 
}; 

myCharCounter = new CharCounter('mytextfield','charcount'); 
window.onload = start; 

Application 2

function CharCounter(sourceId, statusId) { 
    this.sourceId = sourceId; 
    this.statusId = statusId; 
    this.count = 0; 
}; 
    CharCounter.prototype.updateAll = function() { 
     this.count = document.getElementById(this.sourceId).value.length; 
     document.getElementById(this.statusId).innerHTML = "There are "+ this.count+" charactors"; 
    }; 
    CharCounter.prototype.start = function() { 
     var instance = this; 
     instance.updateAll(); 

     document.getElementById(this.sourceId).onkeyup = function() { 
      instance.updateAll(); 
     }; 
     document.getElementById(this.sourceId).onkeydown = function() { 
      instance.updateAll(); 
     }; 
    }; 

window.onload = function() { 
    var myCounter = new CharCounter("mytextfield","charcount"); 
    myCounter.start(); 
}; 

Mise en œuvre 3

function CharCounter(sourceId, statusId) { 
    this.sourceId = sourceId; 
    this.statusId = statusId; 
    this.count = 0; 
}; 
    CharCounter.prototype.updateAll = function() { 
     this.count = document.getElementById(this.sourceId).value.length; 
     document.getElementById(this.statusId).innerHTML = "There are "+this.count+" charactors"; 
    }; 

function bind(funcToCall, desiredThisValue) { 
    return function() { funcToCall.apply(desiredThisValue); }; 
}; 

function start() { 
    myCharCounter.updateAll(); 
    document.getElementById('mytextfield').onkeyup = bind(myCharCounter.updateAll, myCharCounter); 
    document.getElementById('mytextfield').onkeydown = bind(myCharCounter.updateAll, myCharCounter); 
}; 

myCharCounter = new CharCounter('mytextfield','charcount'); 
window.onload = start; 

Répondre

2

Je pense que vous avez des problèmes pour accéder à vos membres d'instance sur la fonction updateAll, puisque vous utilisez comme un gestionnaire d'événements, le contexte (le mot-clé this) est l'élément DOM qui a déclenché l'événement, pas votre instance d'objet CharCounter.

Vous pouvez faire quelque chose comme ceci:

function CharCounter(sourceId, statusId) { 
    this.sourceId = sourceId; 
    this.statusId = statusId; 
    this.count = 0; 
} 

CharCounter.prototype.updateAll = function() { 
    var text = document.getElementById(this.sourceId).value; 
    document.getElementById(this.statusId).innerHTML = text.length; 
}; 

CharCounter.prototype.start = function() { 
    // event binding 
    var instance = this; // store the current context 
    document.getElementById(this.sourceId).onkeyup = function() { 
    instance.updateAll(); // use 'instance' because in event handlers 
          // the 'this' keyword refers to the DOM element. 
    }; 
} 

window.onload = function() { 
    var myCharCounter = new CharCounter('textarea1', 'status'); 
    myCharCounter.start(); 
}; 

Vérifiez l'exemple ci-dessus en cours d'exécution here.

+0

Merci! Cela jette beaucoup de lumière sur mon problème! – user182666

+0

De rien @dgendill! – CMS

0

Vous pouvez:

function start() { 
    //This is the problem 
    document.getElementbyId('mytextfield').onkeydown = function() { myCounter.updateAll(); }; 
    document.getElementbyId('mytextfield').onkeyup = function() { myCounter.updateAll(); }; 
} 
2

L'expression "myCounter.updateAll" renvoie simplement une référence à l'objet de fonction lié à "updateAll". Il n'y a rien de spécial dans cette référence - spécifiquement, rien ne "se souvient" que la référence provenait d'une propriété de votre objet "myCounter".

Vous pouvez écrire une fonction qui prend une fonction en argument et renvoie une nouvelle fonction spécialement conçue pour exécuter votre fonction avec un objet spécifique en tant que pointeur "this". Beaucoup de bibliothèques ont une routine comme celle-ci; voir par exemple la bibliothèque "functional.js" et sa fonction "bind". Voici une version réelle simple:

function bind(funcToCall, desiredThisValue) { 
    return function() { funcToCall.apply(desiredThisValue); }; 
} 

Maintenant, vous pouvez écrire:

document.getElementById('myTextField').onkeydown = bind(myCounter.updateAll, myCounter); 
0

En ASP.Net Ajax, vous pouvez utiliser

Function.createDelegate(myObject, myFunction); 
0

Je veux faire quelque chose comme ça, mais plus simple. L'idée est que l'utilisateur clique sur du texte en gras et qu'un champ de texte apparaisse où il peut changer toutes les valeurs d'un personnage jouant un rôle. Ensuite, lorsque la valeur est modifiée, le champ de texte disparaît à nouveau remplacé par la valeur de texte mise à jour en gras. Je peux le faire déjà en utilisant une alerte de boîte de texte ennuyante. Mais je préférerais avoir quelque chose de semblable à ceci ci-dessous pour remplacer tout cela. J'ai cherché des mois et CMS est le plus proche de répondre à ma question de la manière la plus simple avec un exemple html complet. Personne d'autre sur le net ne pourrait le faire. Donc, ma question est, comment puis-je faire cela? J'ai plusieurs objets (caractères) et j'ai besoin de this.elementId pour que cela fonctionne.

J'ai modifié cet exemple mais il casse si j'essaie d'y ajouter.

 

html> 
head> 
title>Sandbox 
/head> 
body> 
input id="textarea1" size=10 type=text> 

script> 
function CharCounter(sourceId, statusId) 
{this.sourceId=sourceId; 
    this.statusId=statusId; 
    this.count=0; 
} 
CharCounter.prototype.updateAll=function() 
{text=document.getElementById(this.sourceId).value 
    document.getElementById(this.statusId).innerHTML=text 
} 
CharCounter.prototype.start=function() 
{instance=this 
    document.getElementById(this.sourceId).onkeyup=function() 
    {instance.updateAll()} 
} 
window.onload=function() 
{myCharCounter=new CharCounter('textarea1', 'status') 
    myCharCounter.start() 
} 
/script> 
/body> 
/html> 

+0

Merci EFraim et Ryu! De même, dans JQuery 1.4.4, comment combiner - response = $ ("getName") .val() et response = $ (this) .val() dans la même instruction? – ren1999

Questions connexes