2009-05-12 2 views
0

Хорошо, поэтому я не понимаю, почему Firefox говорит, что $ ("# canvas") [0] .getContext ('2d'); не определено. Я выложил его из функции, чтобы вся функция могла получить к ней доступ, но здесь ctx все еще не определен.jQuery- Пожалуйста, объясните мне Закрытие, переменный контекст

(function($) { 
     // Undefined 
     var ctx = $('#canvas')[0].getContext("2d"); 
     var x = 150; 
     var y = 150; 
     var dx = 2; 
     var dy = 4; 
     $(function() { 
      setInterval(draw, 10); 
     }) 
     function draw() { 
      ctx.clearRect(0,0,300,300); 
      ctx.beginPath(); 
      ctx.arc(x,y,10,0,Math.PI*2,true); 
      ctx.closePath(); 
      ctx.fill(); 
      x+=dx; 
      y+=dy; 
     } 
    })(jQuery); 

Однако, когда я передал местоположение CTX неназванного функции, то CTX не определено:

(function($) { 
     var ctx; 
     var x = 150; 
     var y = 150; 
     var dx = 2; 
     var dy = 4; 
     $(function() { 
       //Not Undefined 
      ctx = $("#canvas")[0].getContext('2d'); 
      setInterval(draw, 10); 
     }) 
     function draw() { 
      ctx.clearRect(0,0,300,300); 
      ctx.beginPath(); 
      ctx.arc(x,y,10,0,Math.PI*2,true); 
      ctx.closePath(); 
      ctx.fill(); 
      x+=dx; 
      y+=dy; 
     } 
    })(jQuery); 

Что случилось с первым кодом? Я имею в виду, что var ctx объявлен сверху. Таким образом, это сделает глобальную переменную. Hmm ошибка, которую я получил, была $ ("# canvas") [0] не определена. Значит, что он не может получить доступ к #canvas .. Почему?

ответ

3

Это связано с тем, что при первом вызове вы фактически создаете объект Function, который будет обрабатываться только после загрузки DOM в другом контексте.

Эта анонимная функция будет вызываться, когда все элементы на странице уже загружены, поэтому вызывающая функция будет основной функцией jQuery, и ее контекст полностью отличается от того, который вы кодируете здесь.

Я предлагаю оборачивать все внутри $() вызова, так что это должно работать:

(function($) { 
     $(function() { 
      var ctx = $("#canvas")[0].getContext('2d'); 
      var x = 150; 
      var y = 150; 
      var dx = 2; 
      var dy = 4; 

      setInterval(draw, 10); 

      function draw() { 
        ctx.clearRect(0,0,300,300); 
        ctx.beginPath(); 
        ctx.arc(x,y,10,0,Math.PI*2,true); 
        ctx.closePath(); 
        ctx.fill(); 
        x+=dx; 
        y+=dy; 
      } 
     }); 
})(jQuery); 
+0

Что говорит Себ правильно. первый из них не работает, потому что в то время, когда вы пытаетесь получить свой объект canvas, он еще не загружен. –

+0

Хотя вы правы в отношении обертывания кода внутри обратного вызова, вы ошибаетесь * в контексте проблемы. Вероятно, проблема заключается в том, что javascript-код запускается до объявления тега canvas. Я продемонстрировал это в своем ответе. – brianpeiris

+0

Спасибо. Я просто экспериментировал с тем, как это работает. Я понимаю это сейчас. – rymn

4

Я думаю, что вы перепутали проблему. Дело не в том, что вы неправильно поняли свой контекст переменной, но, вероятно, что вы используете javascript до, ваш тэг canvas объявлен.

Следующий код демонстрирует проблему. Появится сообщение «canvasOne undefined!» потому что мы пытаемся получить доступ к canvasOne до его объявления (обратите внимание на размещение тегов <canvas>).

Я создал размещаемой демо здесь: http://jsbin.com/afuju (редактируется с помощью http://jsbin.com/afuju/edit)

<html> 
    <head> 
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
    </head> 
    <body> 
    <script> 
     /* 
     The following line of code is run as soon as the browser sees it. 
     Since the "canvasOne" tag is not declared yet, the variable will be undefined. 
     */ 
     var canvasOne = $('#canvasOne')[0]; 

     $(function() { 
     // The following code is run after the whole document has finished loading. 
     if (canvasOne === undefined) { 
      alert('canvasOne is undefined!'); 
     } 
     else { 
      canvasOne.getContext("2d").fillRect(5, 5, 15, 15); 
     } 
     }); 
    </script> 
    <canvas id="canvasOne"></canvas> 



    <canvas id="canvasTwo"></canvas> 

    <script> 
     /* 
     The following line of code is run as soon as the browser sees it. 
     But since the "canvasTwo" tag *is* declared above, the variable will *not* be undefined. 
     */ 
     var canvasTwo = $('#canvasTwo')[0]; 

     $(function() { 
     // The following code is run after the whole document has finished loading. 
     if (canvasTwo === undefined) { 
      alert('canvasTwo is undefined!'); 
     } 
     else { 
      canvasTwo.getContext("2d").fillRect(5, 5, 15, 15); 
     } 
     }); 
    </script> 



    <script> 
     $(function() { 
     /* 
      The following code is run after the whole document has finished loading. 
      Hence, the variable will *not* be undefined even though the "canvasThree" tag appears after the code. 
     */ 
     var canvasThree = $('#canvasThree')[0]; 
     if (canvasThree === undefined) { 
      alert('canvasThree is undefined!'); 
     } 
     else { 
      canvasThree.getContext("2d").fillRect(5, 5, 15, 15); 
     } 
     }); 
    </script> 

    <canvas id="canvasThree"></canvas> 
    </body> 
</html> 
+0

Спасибо Брайан Пейрис! – rymn

+0

+1 для демонстрационной развертки – Seb

Смежные вопросы