...

View Full Version : "Wrap up" functions in one block for closure?



Krupski
12-10-2011, 08:37 PM
Hi all,

I've got some simple code that I use to drag the corners of a DIV to resize it on the fly. One thing that bothers me is that there is a "global" variable just hanging outside and I would rather "encapsulate" it all into a block of code so that the variable persists, but is not visible outside of the code that uses it.

So, here's the code:



/***
* support for mouse drag resize of mChat window
* "global" save of mouse start position
**/
var start = 0;

/***
* do-nothing function to attach unused events to
**/
function nullFunc () {
return false;
};

/***
* begin drag
**/
function drag () {
start = 0;
document.onmouseup = up;
document.onmousedown = nullFunc;
document.onmousemove = move;
return false;
};

/***
* end drag
**/
function up () {
start = 0;
document.onmouseup = nullFunc;
document.onmousedown = nullFunc;
document.onmousemove = nullFunc;
return false;
};

/***
* mouse move capture
**/
function move (e) {
var o = mouseXY(e); /* mouseXY not shown here */
if (start) {
mChatSize(o.y - start); /* mChatSize not shown here */
}
start = o.y;
return false;
};
You see the code captures the mouse Y coordinate and then subtracts "start" from it to generate a DELTA (which is what the mChatSize function needs). So, moving the mouse up generates "-1, -1, -1" maybe -2 if dragged fast and +1 +1 +1... if moved down.... you see?

Now what I want to do is put all this code in a "box" so that "start" is global to the box, but invisible outside. I tried to do it and made no headway... I'm sure it's simple and I'm just missing it.

Any help will be appreciated. Thanks!

-- Roger

Amphiluke
12-10-2011, 08:49 PM
The simplest way to avoid global variables is use a lambda function which is called immediately after the declaration.


(function() {
// place here any variables and function declarations...
})();


So, try to wrap your code with such an anonymous function.

Krupski
12-10-2011, 08:52 PM
The simplest way to avoid global variables is use a lambda function which is called immediately after the declaration.


(function() {
// place here any variables and function declarations...
})();
So, try to wrap your code with such an anonymous function.

OK but then how do I call a function inside? Just by it's name as usual?

Amphiluke
12-10-2011, 08:57 PM
Inside the anonymous function you may call all the nested functions by names as usual.

Krupski
12-10-2011, 09:03 PM
Inside the anonymous function you may call all the nested functions by names as usual.

Yes but how do I call it from the outside?

To use the code I posted above, I call it like this:



<img src="./img/handle.gif" id="handle" title="Drag to resize" onmousedown="drag();" />

Amphiluke
12-10-2011, 09:09 PM
You should not call the function drag() from outside. If the function is called from an event handler, it must be registered as an event handler from within the anonymous function.


(function() {
window.onload = function() {
document.getElementById("handle").onmousedown = drag;
}
// other routines
})();

Note that function names also should not take global namespace, if it is possible.

Krupski
12-10-2011, 09:41 PM
You should not call the function drag() from outside. If the function is called from an event handler, it must be registered as an event handler from within the anonymous function.


(function() {
window.onload = function() {
document.getElementById("handle").onmousedown = drag;
}
// other routines
})();Note that function names also should not take global namespace, if it is possible.

Very strange. I can't get it to work... I understand what you're showing me but it's not working. I'll have to work at it until I figure it out.

Thanks!

-- Roger

WA
12-11-2011, 04:51 AM
You can wrap everything in an immediate function to prevent the code from polluting the global space, but return an object inside it at the end exposing what you wish to access globally:


var utils=(function(){
var t=5 //private var

function doit(){ //private func
alert(t)
}

function doit2(num){ //private func
alert(num + t)
}

return {
doit: doit,
doit2: doit2
}

})()

utils.doit() //alerts 5
utils.doit2(3) //alerts 8

In the above, only "utils" is a global variable that in turn contains all the public functions you need to access within the immediate function.

Krupski
12-12-2011, 04:29 PM
You can wrap everything in an immediate function to prevent the code from polluting the global space, but return an object inside it at the end exposing what you wish to access globally:


var utils=(function(){
var t=5 //private var

function doit(){ //private func
alert(t)
}

function doit2(num){ //private func
alert(num + t)
}

return {
doit: doit,
doit2: doit2
}

})()

utils.doit() //alerts 5
utils.doit2(3) //alerts 8In the above, only "utils" is a global variable that in turn contains all the public functions you need to access within the immediate function.

OH!!!! I see! Thanks! So simple.


You are the best! Works like a charm. Thanks again!



/***
* mchat drag resize
**/
var chat = (function() {

var lastPos = 0;

function nullFunc () {
return false;
};

function drag () {
lastPos = 0;
document.onmouseup = up;
document.onmousedown = nullFunc;
document.onmousemove = move;
return false;
};

function up () {
lastPos = 0;
document.onmouseup = nullFunc;
document.onmousedown = nullFunc;
document.onmousemove = nullFunc;
return false;
};

function move (event) {
var o = mouseXY(event);
if (lastPos) {
mChatSize(o.y - lastPos);
}
lastPos = o.y;
return false;
};

return {
drag : drag
};

})();

Krupski
12-15-2011, 08:07 PM
You can wrap everything in an immediate function to prevent the code from polluting the global space, but return an object inside it at the end exposing what you wish to access globally:


var utils=(function(){
var t=5 //private var

function doit(){ //private func
alert(t)
}

function doit2(num){ //private func
alert(num + t)
}

return {
doit: doit,
doit2: doit2
}

})()
In the above, only "utils" is a global variable that in turn contains all the public functions you need to access within the immediate function.

Just wanted to thank you again... because now I UNDERSTAND what's going on. I also looked at a block of code and realized that even this way above can be shortened:



var utils=(function(){
var t=5 //private var
return {
doit : function() { //private func
alert(t)
},
doit2 : function(num){ //private func
alert(num + t)
}
};
})();

The "light bulb" lit up in my head when I saw "doit : doit".....

Thanks again for adding another block of understanding to my head! :thumbsup: :thumbsup:

-- Roger



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum