试图找到一种正确的方式来全局访问画布

时间:2012-06-06 21:39:12

标签: javascript jquery html global-variables

我仍然是Javascript的新手并注意到我的代码中的很多地方我使用JQuery来获取对我的canvas元素的引用:

$('#myCanvas')[0].getContext('2d');

我怀疑它减慢了我的网站速度,因为我在许多地方都有这种情况可能经常被调用。理想情况下,我只需执行此操作并从任何javascript页面访问上下文。

我试图创建一个全局变量,但它看起来不起作用(可能是因为它在页面加载之前运行)所以我把这个函数放在我的第一个引用的javascript文件的全局范围内:

var drawingCanvasContext;

function getDrawingCanvas() {
    if (drawingCanvasContext == null) {
        drawingCanvasContext = $('#myCanvas')[0].getContext('2d');
    }

    return drawingCanvasContext;
}

那么每当我需要我的代码中的画布时,我只是调用那个方法..但它似乎相当......混乱。我怀疑这是一个不寻常的愿望,所以我很好奇正确的解决方案。我更喜欢它只是一个变量而不是一个函数,并且在没有所有这些空检查的情况下全局访问。有谁知道如何做到这一点?感谢。

4 个答案:

答案 0 :(得分:0)

我的代码只有两点改进:

(function(){
    // move the var out of the global context by wrapping everything in a closure
    var /* static */ drawingCanvasContext;

    function getDrawingCanvas() {
        if (!drawingCanvasContext) // no need to check for null, defaultvalue is undefined
            drawingCanvasContext = $('#myCanvas')[0].getContext('2d');
        return drawingCanvasContext;
    }

    window.getDrawingCanvas = getDrawingCanvas;
})();

当然你可以/应该把这个方法放在命名空间对象中,我猜你有多个这样的方法。

答案 1 :(得分:0)

最终,您所能做的就是存储上下文,然后再进行检索。我在这里看到的问题可能是一个操作顺序,在页面准备好之前正在请求上下文,并且可能你正在丢失VAR声明的范围(我认为)。

;(function($, window, document) {

   /* private */ var canvas = null;
   /* private */ var context = null;

   $(document).ready(function() {
      canvas = $("#myCanvas")[0];
      context = canvas.getContext('2d');
      $('body').trigger('CanvasReady', [canvas, context]); // You can fire an event to bind to with jquery for when the canvas is ready.
   });

   /* public */ window.getCanvas = function() { return canvas; };
   /* public */ window.getCanvasContext = function() { return context; };

   // You can also use a namespace here too if you want
   // window.Canvas = {};
   // window.Canvas.GetContext = ... etc ...

})(jQuery, window, document);

这将在画布准备好后获取画布,触发一个事件,您可以在找到画布并准备好操作时订阅该事件。

它将在全球公开2个功能:

getCanvas它将为您提供Canvas实例 getCanvasContext它将为您提供画布上下文

您可以根据需要调整此选项以使用注册表模式,以便它可以获取&存储多个画布元素/上下文,但这只是一个向您展示的简单模式。

注意:如果在画布/文档准备好之前调用方法,则返回null,无论如何,您应该在domReady之后执行所有设置代码。

答案 2 :(得分:0)

您可以在全局变量上定义一个getter,每次从该变量读取时都会执行该getter(有关向后兼容的提示,请参阅here):

var _drawingCanvasContext;//behind the scenes variable that keeps the value
Object.defineProperty(this, "drawingCanvasContext", {
    get: function() {
        return _drawingCanvasContext || (_drawingCanvasContext = $('#myCanvas')[0].getContext('2d'));
    }
});

Here's a fiddle我将其设置为'foo'以向您展示它是如何工作的。

答案 3 :(得分:0)

你可以简单地这样做

var drawingCanvasContext = $('#myCanvas')[0].getContext('2d');

而不是为此定义函数。

如果您对全局范围污染非常小心,则应将其包装在函数中或使用命名空间。 E.g。

var myNamespace = myNamespace || {};
myNamespace.drawingCanvasContext = $('#myCanvas')[0].getContext('2d');