PDA

View Full Version : Anylink Menu & Validation



dmwhipp
11-15-2013, 07:54 PM
1) Script Title: Anylink JS Drop Down Menu v2.3*

2) Script URL (on DD): http://www.dynamicdrive.com/dynamicindex1/dropmenuindex.htm

3) Describe problem: On this page - http://www.flimpact.org/amp/sample1.html I get a validation error at http://html5.validator.nu/. Since the site has been tested in major browsers and the menu works, I don't think it's critical to remove the error, but if it's something that's can be done easily, I would like to know how to have the page validate error free.
Thanks,
Deborah Whipp

*Mr. Scheuer was kind enough to edit the .js file that goes with this so some links will open in new windows.

molendijk
11-15-2013, 08:09 PM
Replace

<link rel="stylesheet" type="text/css" href="/amp/anylink/anylinkmenu.css">
<script type="text/javascript" src="/amp/anylink/menucontents.js"></script>
<script type="text/javascript" src="/amp/anylink/anylinkmenu.js">
/***********************************************
//* AnyLink JS Drop Down Menu v2.0- Copyright Dynamic Drive DHTML code library (www.dynamicdrive.com)
//* This notice MUST stay intact for legal use
//* Visit Project Page at http://www.dynamicdrive.com/dynamicindex1/dropmenuindex.htm for full source code
/***********************************************/
</script>
<script type="text/javascript">
//anylinkmenu.init("menu_anchors_class") //Pass in the CSS class of anchor links (that contain a sub menu)
anylinkmenu.init("menuanchorclass")
</script>
with

<link rel="stylesheet" type="text/css" href="/amp/anylink/anylinkmenu.css">
<script type="text/javascript" src="/amp/anylink/menucontents.js"></script>
<!-- AnyLink JS Drop Down Menu v2.0- Copyright Dynamic Drive DHTML code library (www.dynamicdrive.com). This notice MUST stay intact for legal use. Visit Project Page at http://www.dynamicdrive.com/dynamicindex1/dropmenuindex.htm for full source code -->
<script type="text/javascript" src="/amp/anylink/anylinkmenu.js"></script>
<script type="text/javascript">
//anylinkmenu.init("menu_anchors_class") //Pass in the CSS class of anchor links (that contain a sub menu)
anylinkmenu.init("menuanchorclass")
</script>
and check the validator again.

dmwhipp
11-15-2013, 08:21 PM
I tried that, but I'm still getting the error "Attribute rel not allowed on element div at this point." The errors appeared to be caused not from the coding in the head section, but in the body where I've coded the menu and there is an error for each instance where a menu tab is coded.
Deborah

molendijk
11-15-2013, 10:59 PM
You are using <!DOCTYPE html> so try the data attribute instead of the rel attribute.

dmwhipp
11-16-2013, 04:58 PM
I tried changing rel= to data= on this page http://www.flimpact.org/amp/sample1.html, but then the menu completely quit working. I'm guessing references to rel would probably have to also be changed in multiple places in anylinkmenu.js too:



//** AnyLink JS Drop Down Menu v2.0- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com
//** Script Download/ instructions page: http://www.dynamicdrive.com/dynamicindex1/dropmenuindex.htm
//** January 29th, 2009: Script Creation date

//**May 22nd, 09': v2.1
//1) Automatically adds a "selectedanchor" CSS class to the currrently selected anchor link
//2) For image anchor links, the custom HTML attributes "data-image" and "data-overimage" can be inserted to set the anchor's default and over images.

//**June 1st, 09': v2.2
//1) Script now runs automatically after DOM has loaded. anylinkmenu.init) can now be called in the HEAD section

//**May 23rd, 10': v2.21: Fixes script not firing in IE when inside a frame page

//**June 28th, 11': v2.3: Menu updated to work properly in popular mobile devices such as iPad/iPhone and Android tablets.

//**Sept 24th, 2013: unofficial mod to allow for individual targets for menu links

if (typeof dd_domreadycheck=="undefined") //global variable to detect if DOM is ready
var dd_domreadycheck=false

var anylinkmenu={

menusmap: {},
preloadimages: [],
effects: {delayhide: 200, shadow:{enabled:false, opacity:0.3, depth: [1, 1]}, fade:{enabled:false, duration:500}}, //customize menu effects

dimensions: {},
ismobile:navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i) != null, //boolean check for popular mobile browsers

getoffset:function(what, offsettype){
return (what.offsetParent)? what[offsettype]+this.getoffset(what.offsetParent, offsettype) : what[offsettype]
},

getoffsetof:function(el){
el._offsets={left:this.getoffset(el, "offsetLeft"), top:this.getoffset(el, "offsetTop"), h: el.offsetHeight}
},

getdimensions:function(menu){
this.dimensions={anchorw:menu.anchorobj.offsetWidth, anchorh:menu.anchorobj.offsetHeight,
docwidth:(window.innerWidth ||this.standardbody.clientWidth)-20,
docheight:(window.innerHeight ||this.standardbody.clientHeight)-15,
docscrollx:window.pageXOffset || this.standardbody.scrollLeft,
docscrolly:window.pageYOffset || this.standardbody.scrollTop
}
if (!this.dimensions.dropmenuw){
this.dimensions.dropmenuw=menu.dropmenu.offsetWidth
this.dimensions.dropmenuh=menu.dropmenu.offsetHeight
}
},

isContained:function(m, e){
var e=window.event || e
var c=e.relatedTarget || ((e.type=="mouseover")? e.fromElement : e.toElement)
while (c && c!=m)try {c=c.parentNode} catch(e){c=m}
if (c==m)
return true
else
return false
},

setopacity:function(el, value){
el.style.opacity=value
if (typeof el.style.opacity!="string"){ //if it's not a string (ie: number instead), it means property not supported
el.style.MozOpacity=value
if (document.all && typeof el.style.filter=="string"){
el.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity="+ value*100 +")"
}
}
},

showmenu:function(menuid){
var menu=anylinkmenu.menusmap[menuid]
clearTimeout(menu.hidetimer)
this.getoffsetof(menu.anchorobj)
this.getdimensions(menu)
var posx=menu.anchorobj._offsets.left + (menu.orientation=="lr"? this.dimensions.anchorw : 0) //base x pos
var posy=menu.anchorobj._offsets.top+this.dimensions.anchorh - (menu.orientation=="lr"? this.dimensions.anchorh : 0)//base y pos
if (posx+this.dimensions.dropmenuw+this.effects.shadow.depth[0]>this.dimensions.docscrollx+this.dimensions.docwidth){ //drop left instead?
posx=posx-this.dimensions.dropmenuw + (menu.orientation=="lr"? -this.dimensions.anchorw : this.dimensions.anchorw)
}
if (posy+this.dimensions.dropmenuh>this.dimensions.docscrolly+this.dimensions.docheight){ //drop up instead?
posy=Math.max(posy-this.dimensions.dropmenuh - (menu.orientation=="lr"? -this.dimensions.anchorh : this.dimensions.anchorh), this.dimensions.docscrolly) //position above anchor or window's top edge
}
if (this.effects.fade.enabled){
this.setopacity(menu.dropmenu, 0) //set opacity to 0 so menu appears hidden initially
if (this.effects.shadow.enabled)
this.setopacity(menu.shadow, 0) //set opacity to 0 so shadow appears hidden initially
}
menu.dropmenu.setcss({left:posx+'px', top:posy+'px', visibility:'visible'})
if (this.effects.shadow.enabled){
//menu.shadow.setcss({width: menu.dropmenu.offsetWidth+"px", height:menu.dropmenu.offsetHeight+"px"})
menu.shadow.setcss({left:posx+anylinkmenu.effects.shadow.depth[0]+'px', top:posy+anylinkmenu.effects.shadow.depth[1]+'px', visibility:'visible'})
}
if (this.effects.fade.enabled){
clearInterval(menu.animatetimer)
menu.curanimatedegree=0
menu.starttime=new Date().getTime() //get time just before animation is run
menu.animatetimer=setInterval(function(){anylinkmenu.revealmenu(menuid)}, 20)
}
},

revealmenu:function(menuid){
var menu=anylinkmenu.menusmap[menuid]
var elapsed=new Date().getTime()-menu.starttime //get time animation has run
if (elapsed<this.effects.fade.duration){
this.setopacity(menu.dropmenu, menu.curanimatedegree)
if (this.effects.shadow.enabled)
this.setopacity(menu.shadow, menu.curanimatedegree*this.effects.shadow.opacity)
}
else{
clearInterval(menu.animatetimer)
this.setopacity(menu.dropmenu, 1)
menu.dropmenu.style.filter=""
}
menu.curanimatedegree=(1-Math.cos((elapsed/this.effects.fade.duration)*Math.PI)) / 2
},

setcss:function(param){
for (prop in param){
this.style[prop]=param[prop]
}
},

setcssclass:function(el, targetclass, action){
var needle=new RegExp("(^|\\s+)"+targetclass+"($|\\s+)", "ig")
if (action=="check")
return needle.test(el.className)
else if (action=="remove")
el.className=el.className.replace(needle, "")
else if (action=="add" && !needle.test(el.className))
el.className+=" "+targetclass
},

hidemenu:function(menuid){
var menu=anylinkmenu.menusmap[menuid]
clearInterval(menu.animatetimer)
menu.dropmenu.setcss({visibility:'hidden', left:0, top:0})
menu.shadow.setcss({visibility:'hidden', left:0, top:0})
},

getElementsByClass:function(targetclass){
if (document.querySelectorAll)
return document.querySelectorAll("."+targetclass)
else{
var classnameRE=new RegExp("(^|\\s+)"+targetclass+"($|\\s+)", "i") //regular expression to screen for classname
var pieces=[]
var alltags=document.all? document.all : document.getElementsByTagName("*")
for (var i=0; i<alltags.length; i++){
if (typeof alltags[i].className=="string" && alltags[i].className.search(classnameRE)!=-1)
pieces[pieces.length]=alltags[i]
}
return pieces
}
},


That's not the whole script, since it exceeds the 10,000 character max for these forums.

molendijk
11-16-2013, 07:33 PM
I tried changing rel= to data= on this page http://www.flimpact.org/amp/sample1.html, but then the menu completely quit working. I'm guessing references to rel would probably have to also be changed in multiple places in anylinkmenu.js too.
In just one place, actually. In anylinkmenu.js, replace var relattr=anchorobj.getAttribute("rel") with var relattr=anchorobj.getAttribute("data"). That'll probably do it.

molendijk
11-16-2013, 10:02 PM
Hello dmwhipp,
Someone was kind enough to explain to me that what I said about rel/data is not correct. Please read this (http://html5doctor.com/html5-custom-data-attributes/) for how you could try to correct things in your script(s).

dmwhipp
11-19-2013, 03:40 AM
Thanks for your patience molendijk... your change got the menu working again, but I'm still getting same error, except now it says data instead of rel:
Error: Attribute data not allowed on element div at this point.

vwphillips
11-19-2013, 08:59 AM
using illegal attributes is a common problem with many older DD scripts

change line in red


setupmenu:function(targetclass, anchorobj, pos){
this.standardbody=(document.compatMode=="CSS1Compat")? document.documentElement : document.body
var relattr='anylink'+anchorobj.id // this is the variable name containing the menu data
dropmenuid=relattr.replace(/\[(\w+)\]/, '')
var dropmenuvar=window[dropmenuid];



change the HTML



<div class="navborder">
<div style="width:110px;" class="menuanchorclass" id="menu1"><a class="menutop" href="/amp/sample1.html">Overview</a></div>
<div style="width:235px;" class="menuanchorclass" id="menu2"><a class="menutop" href="/amp/sample1.html">Assess &amp; Become a Provider</a></div>
<div style="width:195px;" class="menuanchorclass" id="menu3"><a class="menutop" href="/amp/sample1.html">For Current Providers</a></div>
<div style="width:130px;" class="menuanchorclass" id="menu4"><a class="menutop" href="/amp/sample1.html">For Caterers</a></div>
<div style="width:190px;" class="menuanchorclass" id="menu5"><a class="menutop" href="/amp/sample1.html">Guidance &#43; Resources</a></div>
<div style="width:100px;" class="menuanchorclass" id="menu6"><a class="menutop" href="/amp/sample1.html">Quicklinks</a></div>
<div style="clear: both;"></div>
</div>

molendijk
11-19-2013, 10:33 AM
Thanks Vic (and John) for filling a gap in my javascript knowledge.

dmwhipp
11-19-2013, 03:33 PM
Thank you so much - menu is working perfectly and validating error-free on the sample page and will be implemented on this client's final site.

dmwhipp
11-19-2013, 03:35 PM
Hi Arie,
Thanks for sticking with this thread. I know validation wasn't critical since the menu was tested and working on all modern browsers, but since I use it on so many client sites, it's nice to know I can use the version that validates error-free as I transition them to HTML5/CSS3.

Regards,
Deborah