Reputation: 61
The issue I am having is when the function is called multiple times for different elements. I believe I need to localize all of the variables such that this function can be used against multiple elements. In case it matters I also call in jquery 1.3.
If I only call pageSlide once, everything is fine, but once I call it multiple times it gets painful. No errors, just erratic behaviour.
The code has been updated
var slideMenu=function(){
var speed, startWidth, time, menuId, liID, menuLen, menuWidth, globalWidth, openWidth;
return{
speed : 0, startWidth : 0, time : 0, menuId : 0, liID : 0, menuLen : 0, menuWidth : 0, globalWidth : 0, openWidth : 0,
build:function(ulID,passStartWidth,passTime,s,passSlideLen,passHeight){
speed=s;
startWidth=passStartWidth;
time=passTime;
menuId=document.getElementById(ulID);
liID=menuId.getElementsByTagName('li');
menuLen=liID.length;
menuWidth=menuId.offsetWidth;
globalWidth=menuWidth/menuLen;
openWidth=Math.floor((menuWidth-startWidth)/(menuLen-1));
var i=0;
for(i;i<menuLen;i++){
s=liID[i];
s.style.width=globalWidth+'px';
this.timer(s)
}
if(passSlideLen!=null){
menuId.timer=setInterval(function(){
slideMenu.slide(liID[passSlideLen-1])
},time)
}
},
timer:function(s){
s.onmouseover=function(){
clearInterval(menuId.htimer);
clearInterval(menuId.timer);
menuId.timer=setInterval(function(){
slideMenu.slide(s)
},
time)
}
s.onmouseout=function(){
clearInterval(menuId.timer);
clearInterval(menuId.htimer);
menuId.htimer=setInterval(function(){
slideMenu.slide(s,true)
},
time)
}
},
slide:function(s,passChange){
var changeWidth=parseInt(s.style.width);
if((changeWidth<startWidth && !passChange) || (changeWidth>globalWidth && passChange)){
var overallWidth=0;
var i=0;
for(i;i<menuLen;i++){
if(liID[i]!=s){
var slideObj,openWidth; var opening=0; slideObj=liID[i]; openWidth=parseInt(slideObj.style.width);
if(openWidth<globalWidth && passChange){
opening=Math.floor((globalWidth-openWidth)/speed);
opening=(opening>0)?opening:1;
slideObj.style.width=(openWidth+opening)+'px';
}else if(openWidth>openWidth && !passChange){
opening=Math.floor((openWidth-openWidth)/speed);
opening=(opening>0)?opening:1;
slideObj.style.width=(openWidth-opening)+'px'
}
if(passChange){
overallWidth=overallWidth+(openWidth+opening)}else{overallWidth=overallWidth+(openWidth-opening)
}
}
}
s.style.width=(menuWidth-overallWidth)+'px';
}else{
clearInterval(menuId.timer);
clearInterval(menuId.htimer)
}
}
};
}();
The code above does not error but fails to work. When I use the this keyword, it doesn't get any better.
My question is which variables should be "this.". I have tried various combinations that I thought would work, but I am missing something.
Upvotes: 0
Views: 427
Reputation: 8161
I think you're misunderstanding the overall concept of the module pattern, when you need to have a global static variable shared between all your instances then you can declare or initialize your variable with the keyword "var" just before the return statement.
Assume that whenever you change those variables all your instances will be impacted by the change.
var slideMenu=function(){
// Declare or initialize your private static variables here
var speed, startWidth, time;
return {
// Public part of your object
slide:function(s,passChange){
//To access your variable
speed = 20;
...
On the other hand if you want to keep variable safe from the global scope, you have to put your variable into the object returned by your function, this is a reliable way to provide unique per instance properties.
var slideMenu=function(){
// Declare or initialize your private static variables here
var speed, startWidth, time;
return {
// Public part of your object
// Declare internal or public properties here
menuId : 0,
liID : 0,
menuLen : 0,
...
slide:function(s,passChange){
//To access your private static variable inside functions
speed = 20;
// To access your public/internal properties
this.menuId = s; // for example ;)
}
To conclude
Sometimes to help distinguish between internal / public properties some folks writes a leading underscore on their internal properties (note that properties will still remain accessible from the outside).
Hope it helps, good luck!
Upvotes: 2
Reputation: 8161
You get this behavior because you are using the module pattern which allows to hold private static variables in your object. The problem is that those variables are shared between all instances.
var sp=0;
var st=0;
var t=0;
var m='';
var sa='';
var l=0;
var w=0;
var gw=0;
var ot=0;
You have to move these variables into your public instance aka in the return part of your script or in the constructor (but in this case you will have to provide a getter for every variable).
return{
// Place your variables here
sp : 0,
st : 0,
...
build:function(sm,sw,mt,s,sl,h){
// And then use the this keyword to access the variable
this.sp=s;
this.st=sw;
t=mt;
m=document.getElementById(sm);
sa=m.getElementsByTagName('li');
l=sa.length;
w=m.offsetWidth;
gw=w/l;
...
Upvotes: 1