1

我对 Javascript 还是有点陌生​​,并且在我的代码中的很多地方都注意到我正在使用 JQuery 来获取对我的画布元素的引用,如下所示:

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

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

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

var drawingCanvasContext;

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

    return drawingCanvasContext;
}

因此,每当我需要代码中的画布时,我都会调用该方法..但它看起来相当..混乱。我怀疑这是一个不常见的愿望,所以我很好奇正确的解决方案。我希望它只是一个变量而不是一个函数,并且可以在没有所有这些 null 检查的情况下全局访问。有谁知道如何做到这一点?谢谢。

4

4 回答 4

0

你可以简单地做到这一点

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

而不是为此定义一个函数。

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

var myNamespace = myNamespace || {};
myNamespace.drawingCanvasContext = $('#myCanvas')[0].getContext('2d');
于 2012-06-06T22:14:56.613 回答
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;
})();

当然,您可以/应该将该方法放在命名空间对象中,我猜您有不止一个这样的方法。

于 2012-06-06T21:47:59.550 回答
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 Instance getCanvasContext将为您提供 Canvas Context

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

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

于 2012-06-06T21:48:19.497 回答
0

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

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

这是一个小提琴,我将其设置为 'foo' 以向您展示它是如何工作的。

于 2012-06-06T22:00:34.113 回答