Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help with Arrays and Loops 1

Status
Not open for further replies.

mik3847

Programmer
Jul 4, 2008
15
GB
I have a script which resizes a div depending on the viewport size, allows the div to scroll using a custom scrollbar with up / down buttons and writes to a cookie to remember it's scrolled position on refresh.

I have grasped the concept of arrays and how they could be used to loop through this code, but with my limited js knowledge cannot get the script to work with more than one div on the same page.

If someone who knows what they're doing a bit more than me could tell me how I can get this to work, I would most appreciate it :)

The Code:

Code:
var divId = ["div_to_scroll", "div2_to_scroll"]; //which div to scroll

//scrolling code
defaultStep=1 
step=defaultStep 

function scrollDown()
	{
	clearTimeout(timerDown) 
	document.getElementById(divId).scrollTop+=step 
	timerDown=setTimeout("scrollDown('"+divId+"')",10)
	} 

function scrollUp()
	{
	clearTimeout(timerUp)
	document.getElementById(divId).scrollTop-=step 
	timerUp=setTimeout("scrollUp('"+divId+"')",10)
	} 

timerDown="" 
timerUp="" 

function stop()
	{
	clearTimeout(timerDown) 
	clearTimeout(timerUp)
	}

document.onmouseout=function()
	{
	stop()
	}
	
//div resizing code
var offSet = 276; // Offset from viewport top/bottom in px
var scrollPad = offSet + 14;

function scale()
	{
	if(useragent="msie")
		{
		document.getElementById(divId).style.height = document.body.clientHeight - offSet + "px";
		document.getElementById("scrollbar-padder").style.height = document.body.clientHeight - scrollPad + "px";
		}
	else
		{
		document.getElementById(divId).style.height = window.innerHeight - offSet + "px";
		document.getElementById("scrollbar-padder").style.height = window.innerHeight - scrollPad + "px";
		}
	}

// Create cookie to store scrolled position
function scrollPos()
	{
	var strCook = document.cookie;
	if(strCook.indexOf("!~")!=0)
		{
		var intS = strCook.indexOf("!~");
		var intE = strCook.indexOf("~!");
		var strPos = strCook.substring(intS+2,intE);
		document.getElementById(divId).scrollTop = strPos;
		}
	}

// Update divs scrolled position
function setDivPosition()
	{
	var intY = document.getElementById(divId).scrollTop;
	document.cookie = "yPos=!~" + intY + "~!";
	}

// Onload do this
function onLoader()
	{
	scale();
	scrollPos();
	document.getElementById(divId).onscroll = setDivPosition;
	}

window.onload = onLoader;
window.onresize = scale;

I think the problem may be that I'm using multiple onLoad events.

 

where is the bit of code, where you loop through your two divs, supposed to be?

and where is the bit of code where you give your divId one of the two values?

if this what you are asking?...then I would suggest to try looping through your divId values in the onLoader function like this
Code:
[blue]var divId;
var divIds =  new Array("div_to_scroll", "div2_to_scroll");[/blue]  // use this instead of your [b]var divId = ["div_to_scroll", "div2_to_scroll"];[/b] 

and loop through the values like this in the onLoader function...if the rest of the code works for one div, I would think that it will work for more than one as well..

function onLoader() {
	[blue]for ( var i=0; i<divIds.length; i++ ) {
		divId = divIds[i];[/blue]
		scale();
		scrollPos();
		document.getElementById(divId).onscroll = setDivPosition;
	}
}
If I misunderstood what you are asking please correct me...


``The wise man doesn't give the right answers,
he poses the right questions.''
TIMTOWTDI
 

Alas, this does not work... only one div resizes. I took my attempt at the loop out to save myself some embarrassment :)

Thanks for having a look btw
 
Ok let me clarify:

The onLoad event now works for both divs.
The onResize event works for the second div but not the first.
The setDivPosition function now sets both divs to the value of the second on refresh.
The scrollUp / scrollDown functions only work for the second div.
The div 'scrollbar-padder' only resizes for the first div.
 
I have built a test page so you can see the problems:

Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "[URL unfurl="true"]http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">[/URL]
<html>
<head>
<style>
html {
	overflow:hidden;
	height:100%}
body{
	width:100%;
	font:12px arial;
	margin:0px;
	text-align:left;
	padding:0px;
	height:100%;
	max-height:100%;}
#div_container{
	position:absolute;
	top:100px;
	left:1px;
	height:auto;
	}
#div_container2{
	position:absolute;
	top:100px;
	left:500px;
	height:auto;
	display:block;}
#div_to_scroll, 
#div_to_scroll2{
	background-color:#f7f7f7;
	width:191px;
	font-size:11px;
	padding:0px;
	margin:0px;
	color:#506666;
	bottom:0px;
	float:left;
	overflow:hidden;
	position:relative;
	height:0px;
	}
.scrollbar{
	float:left;
	width:10px;
	display:block;
	position:relative;
	margin:0px;}
.scrollbar-top, 
.scrollbar-bottom{
	padding:0px;
	margin:0px;}
#scrollbar-padder{
	width:10px;
	border:0px;}
.content_div{
	position:relative;}
</style>
<script type="text/javascript">
var divId;
var divIds =  new Array("div_to_scroll", "div_to_scroll2");
var offSet = 276;

//scrolling code
defaultStep=1 
step=defaultStep 

function scrollDown()
	{
	clearTimeout(timerDown) 
	document.getElementById(divId).scrollTop+=step 
	timerDown=setTimeout("scrollDown('"+divId+"')",10)
	} 

function scrollUp()
	{
	clearTimeout(timerUp)
	document.getElementById(divId).scrollTop-=step 
	timerUp=setTimeout("scrollUp('"+divId+"')",10)
	} 

timerDown="" 
timerUp="" 

function stop()
	{
	clearTimeout(timerDown) 
	clearTimeout(timerUp)
	}

document.onmouseout=function()
	{
	stop()
	}
	
var scrollPad = offSet + 14;

//div resizing code
function scale()
	{
	if(useragent="msie")
		{
		document.getElementById(divId).style.height = document.body.clientHeight - offSet + "px";
		document.getElementById("scrollbar-padder").style.height = document.body.clientHeight - scrollPad + "px";
		}
	else
		{
		document.getElementById(divId).style.height = window.innerHeight - offSet + "px";
		document.getElementById("scrollbar-padder").style.height = window.innerHeight - scrollPad + "px";
		}
	}
// Create cookie to store scrolled position
function scrollPos()
	{
	var strCook = document.cookie;
	if(strCook.indexOf("!~")!=0)
		{
		var intS = strCook.indexOf("!~");
		var intE = strCook.indexOf("~!");
		var strPos = strCook.substring(intS+2,intE);
		document.getElementById(divId).scrollTop = strPos;
		}
	}

// Update cookie to current position
function setDivPosition()
	{
	var intY = document.getElementById(divId).scrollTop;
	document.cookie = "yPos=!~" + intY + "~!";
	}

// Onload do this
function onLoader()
	{
	for ( var i=0; i<divIds.length; i++ ) {
	divId = divIds[i];
	scale();
	scrollPos();
	document.getElementById(divId).onscroll = setDivPosition;
	}
}
window.onload = onLoader;
window.onresize = scale;
</script>
</head>
<body>
		<div id="div_container">
			<div id="div_to_scroll">
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
			</div>
			<div class="scrollbar">
				<div class="scrollbar-top">
				<a alt="Scroll Up" onmousedown="scrollUp(divIds[0])" onmouseup="stop()">Scroll Up</a>
				</div>
				<div id="scrollbar-padder"></div>
				<div class="scrollbar-bottom">
				<a alt="Scroll Up" onmousedown="scrollDown(divIds[0])" onmouseup="stop()">Scroll Down</a>
				</div>
			</div>
		</div>
		<div id="div_container2">
			<div id="div_to_scroll2">
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
				<div class="content_div">Content</div><div class="content_div">More Content</div>
			</div>
			<div class="scrollbar">
				<div class="scrollbar-top">
				<a alt="Scroll Up" onmousedown="scrollUp(divIds[1])" onmouseup="stop()">Scroll Up</a>
				</div>
				<div id="scrollbar-padder"></div>
				<div class="scrollbar-bottom">
				<a alt="Scroll Up" onmousedown="scrollDown(divIds[1])" onmouseup="stop()">Scroll Down</a>
				</div>
			</div>
		</div>
</body>
</html>
 
The key to debug is to trace what divId is at different stages of the page.

[1] Reset divId to null after onLoader() has done the main work, though this is not critical if you do properly at the other places.
[tt]
function onLoader()
{
for ( var i=0; i<divIds.length; i++ ) {
divId = divIds;
scale();
scrollPos();
document.getElementById(divId).onscroll = setDivPosition;
}
[red]divId=null;[/red]
}
[/tt]
[2] In the same spirit, when you stop, you reset it to null.
[tt]
function stop()
{
clearTimeout(timerDown)
clearTimeout(timerUp)
[red]divId=null;[/red]
}
[/tt]
[3] The critical part is the calls to the scrollbar.

><a alt="Scroll Up" onmousedown="scrollUp(divIds[0])" onmouseup="stop()">Scroll Up</a>
[tt]<a alt="Scroll Up" onmousedown="[red]divId=divIds[0];scrollUp()[/red]" onmouseup="stop()">Scroll Up</a>[/tt]

><a alt="Scroll Up" onmousedown="scrollDown(divIds[0])" onmouseup="stop()">Scroll Down</a>
[tt]<a alt="Scroll [blue]Down[/blue]" onmousedown="[red]divId=divIds[0];scrollDown()[/red]" onmouseup="stop()">Scroll Down</a>[/tt]

><a alt="Scroll Up" onmousedown="scrollUp(divIds[1])" onmouseup="stop()">Scroll Up</a>
[tt]<a alt="Scroll Up" onmousedown="[red]divId=divIds[1];scrollUp()[/red]" onmouseup="stop()">Scroll Up</a>[/tt]

><a alt="Scroll Up" onmousedown="scrollDown(divIds[1])" onmouseup="stop()">Scroll Down</a>
[tt]<a alt="Scroll [blue]Down[/blue]" onmousedown="[red]divId=divIds[1];scrollDown()[/red]" onmouseup="stop()">Scroll Down</a>[/tt]
 
Thanks tsuji, that has fixed the scrolling problem. Any idea how to fix the other issues? I don't understand why one scrollbar-padder div resizes and the other does not...? I guess it may have something to do with how getElementById works.
 
I did not read through previous discussions. I take the demo page as the starting point.

Since you mention the scrollbar-padder resizing issue, I have looked at it and indeed it is not exactly correct.

[4] First, you have to change scrollbar-padder selector from id to class. Why? because, you have two identical id.
[tt]
[red]/*[/red] #scrollbar-padder{ [red]*/[/red]
[red].[/red]scrollbar-padder{
width:10px;
border:0px;}
[/tt]
[5] Change the reference of scrollbar-padder.

[5.1] For scrollbar, change accordingly the element.
><div id="scrollbar-padder"></div>
[tt]<div id="scrollbar-padder" [red]class[/red]="scrollbar-padder"></div>[/tt]

[5.2] But for scrollbar2, different id.
><div id="scrollbar-padder"></div>
[tt]<div id="scrollbar-padder[red]2[/red]" [red]class[/red]="scrollbar-padder"></div>[/tt]

[6] Then in the function scale(), you have to make proper reference.
[tt]
//div resizing code
function scale()
{
[blue]//as I changed scrollbar-padder to class rather than id to avoid duplicate id, make this index determined from divId - implementation dependent, though it can be made more general[/blue]
[blue]var n=(/\d$/.test(divId))?divId.substr(divId.length-1):"";[/blue]
if(useragent="msie")
{
document.getElementById(divId).style.height = document.body.clientHeight - offSet + "px";
[blue]document.getElementById("scrollbar-padder"+n).style.height = document.body.clientHeight - scrollPad + "px";[/blue]
}
else
{
document.getElementById(divId).style.height = window.innerHeight - offSet + "px";
[blue]document.getElementById("scrollbar-padder"+n).style.height = document.body.clientHeight - scrollPad + "px";[/blue]
}
}
[/tt]
 
I find this line rather complex in terms of what it does:

Code:
var n=(/\d$/.test(divId))?divId.substr(divId.length-1):"";

I would like to say I understand how that works, but it's a bit beyond me, I can see how it's taking the divId.length - 1 and creating a variable 'n', but I do not get the /\d$/.test section of the code..?

OT: Any idea how I can incorporate the onResize event into the for loop?

Thanks again!
 
If you don't feel comfortable with it, just use instead string functions to get the last character of divId. If it is an integer, add that integer to "scrollbar-padder". If it is not an integer, leave the id "scrollbar-padder" alone. That's why it is implementation-dependent.
 
lol thanks :)

Any chance of a bit of help with the onResize event?
 
[7] resize event
>Any chance of a bit of help with the onResize event?
Part of the discussions above has an impact on the resize event handling. This is how it is expanded to handle more than one div to scroll.
[tt]
[red]//[/red]window.onresize = scale;
[blue]window.onresize = function() {
for (var i=0; i<divIds.length;i++) {
divId=divIds;
scale();
}
divId=null;
}[/blue]
[/tt]
[8] Upon re-read what's been done, there are two other places you have to amend to be consistent. They have no impact on the well-functioning, but, logically, they are incorrect.

>timerDown=setTimeout("scrollDown('"+divId+"')",10)
[tt]timerDown=setTimeout("scrollDown[blue]()[/blue]",10)[/tt]

>timerUp=setTimeout("scrollUp('"+divId+"')",10)
[tt]timerUp=setTimeout("scrollUp[blue]()[/blue]",10)[/tt]
 
I see, I had tried to incorporate the onResize event into the original loop with no sucess, I think that I have a better understanding of how for loops can be used.

Thanks alot

 
Trying to get cookie values stored for each divId using:

Code:
function scrollPos()
	{
	for ( var i=0; i<divIds.length; i++ ) {
	divId = divIds[i];
	var strCook = document.cookie;
	if(strCook.indexOf("!~")!=0)
		{
		var intS = strCook.indexOf("!~");
		var intE = strCook.indexOf("~!");
		var strPos = strCook.substring(intS+2,intE);
		document.getElementById(divId).scrollTop = strPos;
		}
	}
}

But it still sets either div position to the equal of the last modified. Would I have to also loop through the setDivPosition function ?
 
ok, so I think I need to get the cookie value from the previous state and add the other values to the cookie.

Then be able to read back the two values independently, is this the right way to go about this or would it be better to use separate cookies for each value?

/me is lost

 
>if(strCook.indexOf("!~")!=0)
If that's what you want to test if any of the position has been set, it is not "=0", it is "=-1",
[tt]if(strCook.indexOf("!~")!=[red]-1[/red])[/tt]
although practically it is the same.

[9] Setting cookie
[9.1] I think you get the general idea on the array of scrolling div's. But the approach of general re-reading of the cookie is unnecessarily out-of-ordinary by using the artificial signature of !~ and ~!. Use simply the ordinary method of split(;) and further split the "crumb". This is a reference of the ordinary way.
[9.2] One way is to set up two name/value pair one for each div, like yPos and yPos1. (The use of an numeric for the second is all the result of the original set up of div id. You can make life easier for indexing with 0,1,... but it can be done, just more clumsy and very much implementation dependent.) Then setting and retrieving are done in the ordinary way. No need to use !~ and ~! delimiters. If both positions are set, there will be two pairs of those delimiters and their signature-status is lost. Use the ordinary way: identify the cookie name (yPos or yPos1) then read out its value and it will be done.
 
I understand what you mean, but don't understand js enough to be able to do this ...

/me googles for a good js book
 
I trying to do:

Code:
// Create cookie to store scrolled position
function scrollPos()
	{
	for ( var i=0; i<divIds.length; i++ ) {
	divId = divIds[i];
	var strCook = document.cookie;
	if(strCook !=0)
		{
		var strPos = strCook.substring(+2);
		document.getElementById(divId).scrollTop = strPos;
		}
	}
	divId = null;
}
// Update cookie to current position
function setDivPosition()
	{
	for ( var i=0; i<divIds.length; i++ ) {
	divId = divIds[i];
	var intY = document.getElementById(divId).scrollTop;
	document.cookie = intY;
	}
	divId = null;
}

But to no avail and am also using in my onLoader events:

Code:
document.getElementById(divId=divIds[i]).onscroll = setDivPosition;

It does not work at all really and has actually broken the scrolling functionality of one of the divs ...

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top