How to add class to selective <li> in a generated menu
Hi I am looking for a solution to add a class to every list item <li>
which has a child item with a class of <span class="separator">
and a different class to <li>
with an anchor link.
I use Joomla and the menu is being generated somewhat like this:
<ul class="menu">
<li class="item1"><a href="<!-- link goes here -->"><span>Home</span></a></li>
<li class="parent item59"><span class="separator"><span>Demo</span></span></li>
<li class="item62"><a href="<!-- link goes here -->"><span>Article</span></a></li>
<li id="current" class="parent active item27"><a href="<!-- link goes here -->"><span>CMS</span></a>
<ul>
<li class="item50"><a href="<!-- link goes here -->"><span>The News</span></a></li>
<li class="item48"><a href="<!-- link goes here -->"><span>Web Links</span></a></li>
<li class="item65"><span class="separator"><span /></span></li>
<li class="item49"><a href="<!-- link goes here -->"><span>News Feeds</span></a></li>
<li class="item66"><span class="separator"开发者_如何学Python><span /></span></li>
<li class="item67"><span class="separator"><span /></span></li>
<li class="item68"><span class="separator"><span /></span></li>
</ul>
</li>
<li class="item71"><span class="separator"><span>Help</span></span></li>
</ul>
What I want is to add class "anclink"
or "seplink"
to the <li>
depending on their child item so that the final output looks like below.
<ul class="menu">
<li class="item1 anclink"><a href="<!-- link goes here -->"><span>Home</span></a></li>
<li class="parent item59 seplink"><span class="separator"><span>Demo</span></span></li>
<li class="item62 anclink"><a href="<!-- link goes here -->"><span>Article</span></a></li>
<li id="current" class="parent active item27" anclink><a href="<!-- link goes here -->"><span>CMS</span></a>
<ul>
<li class="item50 anclink"><a href="<!-- link goes here -->"><span>The News</span></a></li>
<li class="item48 anclink"><a href="<!-- link goes here -->"><span>Web Links</span></a></li>
<li class="item65 seplink"><span class="separator"><span /></span></li>
<li class="item49 anclink"><a href="<!-- link goes here -->"><span>News Feeds</span></a></li>
<li class="item66 seplink"><span class="separator"><span /></span></li>
<li class="item67 seplink"><span class="separator"><span /></span></li>
<li class="item68 seplink"><span class="separator"><span /></span></li>
</ul>
</li>
<li class="item71 seplink"><span class="separator"><span>Help</span></span></li>
</ul>
How can I achieve this using PHP or even a jQuery solution will be fine.
Kindly help.
With jQuery:
$('#menu > li:has( > span.separator )').addClass('seplink');
$('#menu > li:has( > a )').addClass('anclink');
or:
$('#menu > li > span.separator').parent().addClass('seplink');
$('#menu > li > a').parent().addClass('anclink');
EDIT: I was just walking out the door when I left this solution, so I didn't have the chance to note that I'd strongly favor the second solution since it utilizes a valid CSS selector.
It will perform better in browsers that support querySelectorAll
.
Without jQuery:
var ul = document.getElementsByClassName("menu");
var li = ul[0].getElementsByTagName("li");
for ( var i = 0; i < li.length; i++ ){
var class = li[i].className;
class += ( li[i].childNodes[0].tagName.toUpperCase() == 'A' ) ? ' anclink' : ' seplink';
li[i].className = class;
}
Edit
So you can eitheir use getElementsByClassName as defined in http://robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/ or use another method such as getElementsByTagName (in your case the root of your nested list is the first UL.
For testing purpose I'd advise you to paste this code in the HEAD of your HTML document. Also, you need to call this function once the window is loaded as you want to apply changes on the window's loaded elements.
<script type="text/javascript">
window.onload = function(){
var ul = document.getElementsByTagName("ul")[0];
var li = ul.getElementsByTagName("li");
for ( var i = 0; i < li.length; i++ ){
var myClass = li[i].className;
myClass += ( li[i].childNodes[0].tagName.toUpperCase() == 'A' ) ? ' anclink' : ' seplink';
li[i].className = myClass;
}
};
</script>
Adding a second answer, because I'd advise against loading the entire jQuery
library if this is its only purpose.
An alternative would be to use Sizzle
, which is the CSS selector engine that is included in jQuery
. It is a much smaller download, and as such, may be a decent compromise.
You'd get the library, and use it like this:
var li_span = Sizzle('#menu > li > span.separator'),
li_a = Sizzle('#menu > li > a'),
s = li_span.length,
a = li_a.length;
while( s-- ) {
if( li_span[ s ].className === 'separator' ) {
li_span[ s ].parentNode.className += ' seplink';
}
}
while( a-- ) {
li_a[ a ].parentNode.className += ' anclink';
}
The downloaded file is full size, so you'll want to minify it.
Hey @Patrick and @Nabab none of the solutions worked for me but some how managed to work around with this script and it is working fine in even in IE 6-9 and Firefox. I didnt get chance to check on Opera, Chrome and Safari will try it later.
$(document).ready(function() {
$('ul.menu li:not(:has(li))')
.addClass(function() {
return (
($('span.separator',this).length)
? 'seplink' : (($('a[href]',this).length)
? 'anclink' : null));
});
});
This script was contributed by some generous member yesterday here as an answer to this question. I couldn't get his / her name but don't know why later it disappeared from the list of answers. Luckily I had already copied it by then. I am posting this as an answer as it is working perfectly for me.
I am anyway using the entire jQuery library because there are other aspects of my template which need it. Kindly advise if you guys see any challenge which I may not know, in using this script.
精彩评论