PDA

View Full Version : Resolved Does a script for a stretchable navigation exist on Dynamic Drive?



Shammus
05-01-2009, 09:00 PM
I was hoping to find a script for a particular sort of top navigational menu on this forum. I took a look and couldn't find one so I thought I'd post the question here. Basically, what I have in mind starts out with a few tabs sitting inside a larger wrapper like you see in the first picture. The silver is simply a background color for the <div> containing the six cities that are listed. (see first image below)

2660

Basically, what I was hoping for, is a script that allows me to click on one of the cities (an onclick not onmouseover) and that tab expands to fill 100% of the remaining space in the wrapping parent <div> This will stay that way until you click on a second city and that tab expands. (see second image)

2661

Hope that makes sense. Thanks in advance for pointing me in the right direction....

Master_script_maker
05-01-2009, 09:18 PM
I can't find anything, but I would gladly make something. Would you like to use just <div>'s or <li>'s?

Shammus
05-01-2009, 09:36 PM
I think either floating <div> tags or even a table would work if that's easier. Thank you in advance, I appreciate the assistance!

Master_script_maker
05-02-2009, 02:06 PM
Fixed ErrorOkay it's all done. Here is an example: http://masterscriptmaker.co.cc/dy/stretch.html. To do this you use the following structure:
<div class="s_menu">
<ul>
<li style="background-color: violet;"><a href=""><span>Baltimore</span></a></li>
<li style="background-color: yellow;" class="s_menu_f"><a href=""><span>Newark</span></a></li>
<li style="background-color: blue;"><a href=""><span>Memphis</span></a></li>
<li style="background-color: orange;"><a href=""><span>San Antonio</span></a></li>
<li style="background-color: purple;"><a href=""><span>Miami</span></a></li>
<li style="background-color: gold;"><a href=""><span>Bronx</span></a></li>
</ul>
</div> what ever <li> you want expanded add class="s_menu_f", as you can see it is in the second <li>. If you don't add it to anything, it defaults to the first.
To style it correctly you would add this css:
body {
padding: 0;
margin: 0;
}
.s_menu ul {
list-style: none;
padding: 0;
margin: 0;
}
.s_menu li {
display: inline;
float: left;
}
.s_menu a {
color: white;
text-decoration: none;
font: bold 13px "Lucida Grande", "Trebuchet MS", Verdana, Helvetica, sans-serif;
}
.s_menu a span {
display: block;
padding: 5px 30px;
cursor: pointer;
} And now for the script, you would add this before the </body> tag:
<script type="text/javascript">
/**Made By Master_Script_Maker**/
var s_menu={
by:[],
init:function() {
var t=this.get();
var f='', t2=[];
for(var i=0;i<t.length;i++) {
t2=t[i].getElementsByTagName("li");
for(var n=0;n<t2.length;++n) {
if(t2[n].className=="s_menu_f") {
f=n;
}
t2[n].onclick=(function(i, n) {
return function() {
s_menu.expand(i, n);
return false;
};
})(i, n);
}
this.menus.push([t[i], t2]);
if(!f) {
f=t2[0];
f.className="s_menu_f";
f=0;
}
setTimeout((function(t, i, f) {return function() {t.expand(i, f);};})(this, i, f), 200);
}
},
menus:[],
get:function() {
var t=document.body.getElementsByTagName("div");
var a=[];
for(var i=0;i<t.length;i++) {
if(t[i].className=="s_menu") {
a.push(t[i]);
}
}
return a;
},
expand:function(n, m) {
var f=this.menus[n][1][m];
var tem=f.parentNode.getElementsByTagName("li");
for(var i=0;i<tem.length;i++) {
tem[i].style.width='';
}
if(!this.by[n]) {
this.by[n]=f.offsetParent.clientWidth-tem[tem.length-1].offsetLeft-tem[tem.length-1].clientWidth;
}
f.style.width=f.childNodes[0].childNodes[0].offsetWidth+this.by[n]+"px";
}
};
function check() {
var div=document.createElement("div");
document.body.appendChild(div);
if(typeof console!="object") {
log=(function(d) {
return function() {
var temp=document.createTextNode(arguments.join(" "));
d.appendChild(temp);
d.appendChild(document.createElement("br"));
}
})(div);
} else {
log=console.log;
}
}
Object.prototype.join=function (a) {
var t="";
for(var i=0;i<this.length;i++) {
t+=this[i]+a;
}
return t;
};
check();
s_menu.init();
</script>
Feel free to edit anything to better suit you; also, I'll be glad to answer any questions you have about it.

Shammus
05-06-2009, 12:25 AM
Hello,

Sorry for the delay in my response, I've been out of town for a couple days. I appreciate the effort and time you put into helping me out with this. I'll take a look at the script a little closer and will certainly let you know, either way, the outcome or if I have any questions. Thank you again and much appreciated!

Brian

Master_script_maker
05-06-2009, 02:00 AM
You're welcome! If it doesn't suit your needs, I would be glad to change it. :)

Shammus
05-07-2009, 03:56 PM
Thank you again for taking the time to put this together for me. It looks great in Firefox 2 and 3, however it's actually not working in IE 6 or 7. This holds true for the script hosted on your website at the URL above as well. Is there anything that I'm missing?

Thanks again!
Brian

Shammus
05-11-2009, 05:01 PM
Friendly bump hoping "Master_script_maker" sees it....

Thanks again

Master_script_maker
05-11-2009, 08:02 PM
Okay, it's all fixed!

Shammus
05-14-2009, 02:22 AM
Thanks again for the assistance! I noticed a few quirks about the script, a couple things I already took care of -

1. Removing the following IF statement allows you to have no tab extended when the page loads -

if(!f) {
f=t2[0];
f.className="s_menu_f";
f=0;
}
setTimeout((function(t, i, f) {return function() {t.expand(i, f);};})(this, i, f), 200);

2. There was a tiny quirk in IE 6 where additional padding was created underneath the tabs after one had been clicked. However, adding a "clear:both;" tag after all the <li> tags in the html (since they're floating anyway) fixed this issue....

The two things I haven't been able to fix just yet -

1. In Firefox, the script as a whole gets very testy if you set it in a parent <div> that has a set width. Unfortunately though, it will be necessary to set a width somehow when this is used. If you place the script as is on a site that already has containing <div> tags set up, the tabs will appear normally at first, but anytime you click on one of them, it will knock the remaining tabs to a second line.

2. In IE 6, if you click the tab on the right to extend it, and then click it a second time, that far right tab falls to a second line. Setting heights and widths for the tabs don't seem to have any effect on this either. This can be seen in IE 6 on your site at the URL above too.

Thanks so much for the assistance so far...any thoughts on the final two quirks?

PS...if it's easier to send you an email, let me know and I can continue dialogue with you privately.

Regards,
Brian

vwphillips
05-14-2009, 12:11 PM
Just playing


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Stretch Menu</title>
<style type="text/css">
body {
padding: 0;
margin: 0;
}

#tst1 {
width:800px;border:solid black 0px;
}

#tst2 {
width:800px;border:solid black 0px;
}

.s_menu ul {
list-style: none;
padding: 0;
margin: 0;
}
.s_menu li {
display: inline;
float: left;
}
.s_menu a {
color: white;
text-decoration: none;
font: bold 13px "Lucida Grande", "Trebuchet MS", Verdana, Helvetica, sans-serif;
}
.s_menu a span {
display: block;
padding: 5px 30px;
cursor: pointer;
}
</style>

<script type="text/javascript">
/*<![CDATA[*/
// Basic Element Animator (11-May-2009)
// by Vic Phillips http://www.vicsjavascripts.org.uk

// To progressively change the Left, Top, Width, Height or Opacity of an element over a specified period of time.
// With the ability to scale the effect time on secified minimum/maximum values<br />
// and with three types of progression 'sin' and 'cos' and liner and an optional 'Bounce'.

// **** Application Notes

// **** The HTML Code
//
// when moving an element the inline or class rule style position of the element should be assigned as
// 'position:relative;' or 'position:absolute;'.
//
// The element would normally be assigned a unique ID name.
//

// **** Executing the Effect(Script)
//
// The effect is executed by an event call to function 'zxcBAnimator('width#',document.getElementById('tst'),10,800,5000,[10,800],'sin');'
// where:
// parameter 0 = the mode(see Note 2). (string)
// parameter 1 = the unique ID name or element object. (string or element object)
// parameter 2 = the start position of the effect. (digits, for opacity minimum 0, maximum 100)
// parameter 3 = the finish position of the effect. (digits, for opacity minimum 0, maximum 100)
// parameter 4 = (optional) period of time between the start and finish of the effect in milliseconds. (digits or defaults to 2000 milliSeconds)
// parameter 5 = (optional) to scale the effect time on a secified minimum/maximum. (array, see Note 5)
// field 0 the minimum. (digits)
// field 1 the maximum. (digits)
// parameter 6 = (optional) the type of progression, 'sin', 'cos' or 'liner'. (string, default = 'liner')
// 'sin' progression starts fast and ends slow.
// 'cos' progression starts slow and ends fast.
//
// Note 1: The default units(excepting opacity) are 'px'.
// Note 2: Examples modes: 'left', 'top', 'width', 'height', 'opacity.
// For hyphenated modes, the first character after the hyphen must be upper case, all others lower case.
// Note 3: To 'toggle' the effect include '#' in parameter 0.
// The first call will set the toggle parameters.
// Subsequent calls with '#' in parameter 0 and the same start and finish parameters will 'toggle' the effect.
// Note 4: The function may be re-executed with a different set of parameters (start/finish time or period)
// whenever required, say from an onclick/mouseover/out event.
// The period parameter will be retained unless re-specified.
// Note 5: parameter 5 is of particular use when re-calling the effect
// in mid travel to retain an constant rate of progression.
// Note 6: parameters 2 and 3 must be different values to execute the script.
//


// **** Functional Code - NO NEED to Change


function zxcBAnimator(mde,obj,srt,fin,ms,scale,curve){
if (typeof(obj)=='string'){ obj=document.getElementById(obj); }
if (!obj) return;
var oop=obj[mde.replace(/\W/g,'')+'oop'];
if (oop){
if (oop.srtfin[0]==srt&&oop.srtfin[1]==fin&&mde.match('#')) oop.update([oop.data[0],(oop.srtfin[0]==oop.data[2])?fin:srt],ms,scale,curve);
else oop.update([srt,fin],ms,scale,curve);
}
else oop=obj[mde.replace(/\W/g,'')+'oop']=new zxcBAnimatorOOP(mde,obj,srt,fin,ms,scale,curve);
return oop;
}

function zxcBAnimatorOOP(mde,obj,srt,fin,ms,scale,curve){
this.srtfin=[srt,fin];
this.to=null;
this.obj=obj;
this.mde=mde.replace(/\W/g,'');
this.update([srt,fin],ms,scale,curve);
}

zxcBAnimatorOOP.prototype.update=function(srtfin,ms,scale,curve){
clearTimeout(this.to);
this.time=ms||this.time||2000;
this.data=[srtfin[0],srtfin[0],srtfin[1]];
this.mS=this.time*(!scale?1:Math.abs((srtfin[1]-srtfin[0])/(scale[1]-scale[0])));
this.ms=this.mS;
this.curve=(typeof(curve)=='string')?curve.charAt(0).toLowerCase():(this.curve)?this.curve:'x';
this.inc=Math.PI/(2*this.mS);
this.srttime=new Date().getTime();
this.cng();
}

zxcBAnimatorOOP.prototype.cng=function(){
this.ms=new Date().getTime()-this.srttime;
this.data[0]=(this.curve=='s')?Math.floor((this.data[2]-this.data[1])*Math.sin(this.inc*this.ms)+this.data[1]):(this.curve=='c')?(this.data[2])-Math.floor((this.data[2]-this.data[1])*Math.cos(this.inc*this.ms)):(this.data[2]-this.data[1])/this.mS*this.ms+this.data[1];
this.apply();
if (this.ms<this.mS) this.to=setTimeout(function(oop){return function(){oop.cng();}}(this),10);
else {
this.data[0]=this.data[2];
this.apply();
}
}

zxcBAnimatorOOP.prototype.apply=function(){
if (isFinite(this.data[0])){
if (this.mde!='left'&&this.mde!='top'&&this.data[0]<0) this.data[0]=0;
if (this.mde!='opacity') this.obj.style[this.mde]=this.data[0]+'px';
else zxcOpacity(this.obj,this.data[0]);
}
}

function zxcOpacity(obj,opc){
if (opc<0||opc>100) return;
obj.style.filter='alpha(opacity='+opc+')';
obj.style.opacity=obj.style.MozOpacity=obj.style.KhtmlOpacity=opc/100-.001;
}

/*]]>*/
</script>

<script type="text/javascript">
<!--

function zxcStretch(id,max,ms){
var obj=document.getElementById(id);
var lis=obj.getElementsByTagName('LI')
this.ary=[];
this.max=max;
obj.style.width=max+'px';
for (var w,z0=0;z0<lis.length;z0++){
w=lis[z0].offsetWidth;
this.ary[z0]=[zxcBAnimator('width',lis[z0],w,w,10),w];
zxcAddOOPEvt(this,lis[z0],'click','Stretch',z0);
this.max-=w;
}
this.ms=ms||1000;
this.lst=false;
}

zxcStretch.prototype.Stretch=function(nu,e,ms){
if (this.lst) this.lst[0].update([this.lst[0].data[0],this.lst[1]],ms||this.ms);
this.lst=this.ary[nu];
this.lst[0].update([this.lst[0].data[0],this.lst[1]+this.max],ms||this.ms);
}

function zxcAddOOPEvt(oop,o,t,f,p){
if (o.addEventListener) o.addEventListener(t,function(e){ return oop[f](p,e);}, false);
else if (o.attachEvent) o.attachEvent('on'+t,function(e){ return oop[f](p,e); });
else {
var prev=o['on'+t];
if (prev) o['on'+t]=function(e){ prev(e); oop[f](p,e); };
else o['on'+t]=o[f];
}
}

//-->
</script>

<script type="text/javascript">
<!--

var S1,S2;

function Init(){
S1=new zxcStretch('tst1',800,1000);
S1.Stretch(0,false,10);
S2=new zxcStretch('tst2',850,500);
}
//-->
</script>
</head>
<body onload="Init();" >
<div class="s_menu" id="tst1" >
<ul>
<li style="background-color: violet;"><a ><span>Baltimore</span></a></li>
<li style="background-color: yellow;" class="s_menu_f"><a ><span>Newark</span></a></li>
<li style="background-color: blue;"><a ><span>Memphis</span></a></li>
<li style="background-color: orange;"><a ><span>San Antonio</span></a></li>
<li style="background-color: purple;"><a ><span>Miami</span></a></li>
<li style="background-color: gold;"><a ><span>Bronx</span></a></li>
</ul>
</div>



<br>You can have multiple menus!<br>
<div class="s_menu" id="tst2">

<ul>
<li style="background-color: violet;"><a ><span>Baltimore</span></a></li>
<li style="background-color: yellow;" class="s_menu_f"><a ><span>Newark</span></a></li>
<li style="background-color: orange;"><a ><span>San Antonio</span></a></li>
<li style="background-color: purple;"><a ><span>Miami</span></a></li>
<li style="background-color: gold;"><a ><span>Bronx</span></a></li>
</ul>
</div>
</body>
</html>

Shammus
05-19-2009, 04:05 AM
Hey that last attempt worked really well! I tried to break it in several browsers and couldn't. I think this could be exactly what I need to get started. Thank you both very much for the assistance!