2010-02-13 4 views
1

Проблемы с переменным объектом:Objects игровой

this.timer

это не «глобальное», так что, когда я нажимаю на кнопку остановки значение переменного является неправильным.
Если я объявляю глобальную переменную MyObject (loke var mytimer;) и использую ее вместо this.timer, она работает.

Это мой код:

<html> 
    <head> 
     <meta http-equiv="content-type" content="text/html; charset=utf-8"> 
     <title></title> 
     <script type="text/javascript" language="JavaScript">    
      var MyObject = { 

       init: function(){ 
        this.timer = 0; 
        document.getElementById("btn1").onclick = function(){ 
         MyObject.RunIt(); 
        }; 
        document.getElementById("btn2").onclick = function(){ 
         clearInterval(this.timer); 
        }; 

       }, 

       RunIt: function(){ 
        var x=0; 
        this.timer = setInterval(function(){ 
       x++; 
         document.getElementById("spn").innerHTML=x; 
        }, 1000); 

       } 

      }; 


     </script> 
     <style type="text/css"> 
     </style> 
    </head> 
    <body onload="MyObject.init();"> 
     <input type="button" id="btn1" value="Run"/> 
     <input type="button" id="btn2" value="Stop"/> 
     <span id="spn"></span> 
    </body> 
</html> 
+0

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

+0

вы мне котируете? – mariki

+1

Я спросил, почему я не получаю реальную ценность this.timer, когда я нажимаю кнопку остановки. – mariki

ответ

2

Проблема заключается в следующем: когда вы установите «OnClick» для вызова функции например, в вызове нет ссылки на объект. Браузер вызывает вашу функцию, чтобы выполнить «clearInterval», но «это» не указывает на ваш объект - фактически, он указывает на сам элемент кнопки.

Вот один из способов обойти эту проблему:

var self = this; 
document.getElementById('btn2').onclick = function() { 
    clearInterval(self.timer); 
}; 

Я знаю, что вопрос-аскеры на Stackoverflow злюсь иногда, когда люди призывают их исследовать JQuery или некоторые другие современные рамки Javascript, но это просто лучше способ сделать что-то.

+0

@Pointy: Что касается вашего последнего предложения, это только ваше мнение. Есть много ситуаций, когда я думаю, что лучше не использовать одну из больших библиотек JavaScript. –

+0

о jquery, возможно, вы правы, но если бы я хотел jquery, я бы добавил необходимый тег ... – mariki

+0

@frunsi, так что этот ответ тоже не хорош? – mariki

-1

Вы можете получить доступ к объекту через this только если объект был создан new.

this в вашем коде относится к объекту window. В обработчиках событий это относится к соответствующему элементу HTML.

Read a detailled explanation.

Ваше объявление MyObject является объектом, но позволяет сказать, что это не является экземпляром объекта. В JS есть разница.

экземпляр объекта Пример:

 function MyClass() { 
       this.timer = 0; 

       this.RunIt = function() { 
         var x=0; 
         this.timer = setInterval(function(){ 
           x++; 
           document.getElementById("spn").innerHTML=x; 
         }, 1000); 
       }; 

       var me = this; // alias to current "this" 

       document.getElementById("btn1").onclick = function(){ 
        // "this" refers to btn1, use me 
        me.RunIt(); 
       }; 
       document.getElementById("btn2").onclick = function(){ 
        // "this" refers to btn2, use me 
        clearInterval(me.timer); 
       }; 
     } 

     var MyObject = new MyClass(); 

Обратите внимание, что существует множество различных способов для создания объектов в JavaScript.

EDIT: он содержит еще одну ошибку: функции обработчика событий будут выполняться как элементы HTML-элемента. Так что в обработчиках относится к элементу HTML, а не к вашему объекту.

EDIT: фиксированный код

EDIT: Плохой день, не слушают меня ;-)

+0

Это первое предложение абсолютно неверно. – Pointy

+0

Есть ли обходной путь с использованием объявления объекта, которое я использовал? – mariki

+0

mariki: вы можете поместить таймер в свое объявление MyObject, например. 'var MyObject = {timer: 0, ...}'. Но вам всегда нужно ссылаться на него через MyObject.timer - даже в RunIt и других двух функциях. – Frunsi

1

Это распространенная проблема при написании кода javascript; Область применения.

в .onclick методом на элементе, то сферу (это) является сам элемент, а не класс вы в (MyObject).

Я использую этот/этот метод; как показано ниже:

  init: function(){ 
       this.timer = 0; 
       document.getElementById("btn1").onclick = function(){ 
        MyObject.RunIt(); 
       }; 

       var that = this; 
       document.getElementById("btn2").onclick = function(){ 
        /** 
         Here i use 'that' instead of 'this'; 
         because 'this' is the button element 
        */ 
        clearInterval(that.timer); 
       }; 

      },