My Goal: To namespace my javascript to keep the global namespace clean.
My question: how do I share variables between methods in my JavaScript namespace?
In my example I am extending and overwriting the behaviour of the ASP.net ModalPopupExtender. I want to know how I can share the modalPopupStack
variable with ModalPopupShowOverride
and ModalPopupHideOverride
without making it global.
Relevant code:
$(function () {
if (Sys.Extended != undefined && Sys.Extended.UI != undefined && Sys.Extended.UI.ModalPopupBehavior != undefined) {
MyPageMethods.ModalPopupShowOriginal = Sys.Extended.UI.ModalPopupBehavior.prototype.show;
MyPageMethods.ModalPopupHideOriginal = Sys.Extended.UI.ModalPopupBehavior.prototype.hide;
Sys.Extended.UI.ModalPopupBehavior.prototype.show = MyPageMethods.ModalPopupOverrides.ModalPopupShowOverride;
Sys.Extended.UI.ModalPopupBehavior.prototype.hide = MyPageMethods.ModalPopupOverrides.ModalPopupHideOverride;
}
});
var MyPageMethods = {
ModalPopupShowOriginal: function () { },
ModalPopupHideOriginal: function () { },
ModalPopupOverrides: {
modalPopupStack: new Array(),
ModalPopupShowOverride: function () {
var extender = this;
var topElement;
MyPageMethods.ModalPopupShowOriginal.apply(this, arguments);
for (var x = 0; x < modalPopupStack.length; x++) {
if ($(modalPopupStack[x].background).css("z-index") > $(extender._element).css('z-index') || $(modalPopupStack[x].popup).css("z-index") > $(extender._element).css('z-index')) {
if ($(modalPopupStack[x].background).css("z-index") > $(extender._element).css('z-index')) {
topElement = $(modalPopupStack[x].background).css("z-index");
}
else if ($(modalPopupStack[x].popup).css("z-index") > $(extender._element).css('z-index')) {
topElement = $(modalPopupStack[x].popup).css("z-index");
}
}
}
if (topElement != undefined) {
$(extender._backgroundElement).css('z-index', topElement);
}
modalPopupStack.push({ 'id': extender._id, 'background': extender._backgroundElement, 'popup': extender._element });
},
ModalPopupHideOverride: function () {
var extender;
MyPageMethods.ModalPopupHideOriginal.apply(this, arguments);
extender = modalPopupStack.shift();
}
}
}
I'm sure there is a simple solution to this, but I'm not sure what it is.
It sounds like you want the variables to be visible within your namespace but not outside of it. If so then try the following solution.
var MyPageMethods = (function() {
// This variable is local to the namespace. It can't be accessed from
// the caller
var modalPopupStack = new Array();
// These values are available to the callers as members of MyPageMethods
return {
ModalPopupShowOriginal: function () { },
ModalPopupHideOriginal: function () { },
ModalPopupOverrides: { ... }
};
})();
This pattern uses a function to establish a private function scope for local variables of the namespace. It then returns a new object which contains the members accessible outside the namespace. Those definitions occur inside the function hence they can access the namespace private data.