Как запустить метод объекта onEvent в JavaScript? - PullRequest
4 голосов
/ 01 октября 2009

Я только начал использовать JavaScript, и мне не хватает чего-то важного в моих знаниях. Я надеялся, что ты поможешь мне заполнить пробел.

Итак, скрипт, который я пытаюсь запустить, предполагает подсчет символов в текстовом поле и обновление абзаца, чтобы сообщить пользователю, сколько символов они набрали. У меня есть объект с именем charCounter. sourceId - это идентификатор текстовой области для подсчета символов. statusId - это идентификатор абзаца, который нужно обновлять при каждом нажатии клавиши.

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

Существует один метод с именем updateAll. Обновляет количество символов и обновляет абзац.

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

У меня есть функция запуска, которая вызывается при загрузке окна.

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;

Приведенный выше код является проблемой. Почему в мире я не могу вызвать метод myCounter.updateAll при возникновении события? Это действительно смущает меня. Я понимаю, что если вы вызовете метод likeThis () , вы получите значение из функции. Если вы называете это как этот , вы получаете указатель на функцию. Я указываю свое событие на функцию. Я также попытался вызвать функцию прямо вверх, и она работает просто отлично, но она не будет работать при возникновении события.

Чего мне не хватает?


Спасибо за все ответы. Вот три разных реализации.

Реализация 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;

Реализация 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();
};

Реализация 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;

Ответы [ 5 ]

2 голосов
/ 01 октября 2009

Выражение «myCounter.updateAll» просто возвращает ссылку на объект функции, связанный с «updateAll». В этой ссылке нет ничего особенного - в частности, ничто не «помнит», что ссылка получена из свойства вашего объекта «myCounter».

Вы можете написать функцию, которая принимает функцию в качестве аргумента и возвращает новую функцию, созданную специально для запуска вашей функции с определенным объектом в качестве указателя «this». У многих библиотек есть такая рутина; см., например, библиотеку «functions.js» и ее функцию «bind». Вот очень простая версия:

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

Теперь вы можете написать:

document.getElementById('myTextField').onkeydown = bind(myCounter.updateAll, myCounter);
2 голосов
/ 01 октября 2009

Я думаю, что у вас есть проблемы с доступом к членам вашего экземпляра в функции updateAll, так как вы используете его как обработчик событий, контекст (ключевое слово this) - это элемент DOM, который вызвал событие, а не Экземпляр объекта CharCounter.

Вы можете сделать что-то вроде этого:

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

Проверьте приведенный выше пример с здесь .

0 голосов
/ 20 января 2011

Я хочу сделать что-то подобное, но проще. Идея состоит в том, чтобы пользователь щелкнул текст, выделенный жирным шрифтом, и отобразил текстовое поле, в котором он может изменить все значения персонажа, играющего роль. Затем, когда значение будет изменено, текстовое поле снова исчезнет, ​​заменив его обновленным жирным шрифтом. Я могу сделать это уже с помощью раздражающего текстового поля оповещения. Но я бы предпочел что-то подобное ниже, чтобы заменить все это. Я искал несколько месяцев, и CMS ближе всего отвечает на мой вопрос самым простым способом с полным примером HTML. Никто другой в сети не мог.

Итак, мой вопрос, как мне это сделать? У меня есть несколько объектов (символов) и мне нужен this.elementId, чтобы эта работа работала.

Я изменил этот пример, но он ломается, если я пытаюсь добавить его.


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 голосов
/ 01 октября 2009

В ASP.Net Ajax вы можете использовать

Function.createDelegate(myObject, myFunction); 
0 голосов
/ 01 октября 2009

Вы можете:

function start() {
    //This is the problem
    document.getElementbyId('mytextfield').onkeydown = function() { myCounter.updateAll(); };
    document.getElementbyId('mytextfield').onkeyup = function() { myCounter.updateAll(); };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...