473,767 Members | 1,717 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Get all href values in <ul> group and compare with current url

Is it possible to get all href URLs contained in a unordered list and place
them in an array?
Or in fact two different arrays, differently named one for each <ul> group?

<ul>
<li><a href="lemurs.ht ml">Lemurs</a></li>
<li><a href="chameleon s.html">Chamele ons</a></li>
</ul>

<ul>
<li><a href="sharks.ht ml">Sharks</a></li>
<li><a href="crocs.htm l">Crocodile s</a></li>
</ul>

I want to fetch an array of the links within a <ul> group, and
document.write the above, but with class variable in which I can
set a different value, depending on if the current url filename matches
exactly any one of the links within the <ul> group the <li> belongs to.

More specifically, I would like to ...

document.write( '<li class'+myvariab le+'>')
|
... class 'green' or 'blue' -------'
depending on whether filename in any href contained
in an <li> of the <ul> group it is in.
If an exact match is found, write out green, if not blue.

The file name portion of the current URL I simply get through:

var f = window.location .href;
file = i.substring (f.lastIndexOf( '/') +1);

It is for drop-down nav-system whereby all list items would of a ul group
would appear either one of two colours as specified in css properties. All
links are internal links on the same domain so one would always match.

I could naturally do it all by having a pre-typed list of all filenames and
run each <li> through an if statement before writing it out. But as there
will be many <li>'s I would prefer a more typeless method if possible.

Many thanks for any tips!

Michael

--
(1) Everything depends.
(2) Nothing is always.
(3) Everything is sometimes.

Jul 23 '05 #1
16 4451
Try this:

<script>
uls = document.getEle mentsByTagName( "UL");
for (var u=0; u<uls.length; u++) {
alert("entering list ["+u+"]");
lis=uls[u].getElementsByT agName("LI");
for (var i=0; i<lis.length; i++) {
if (lis[i].childNodes[0] && lis[i].childNodes[0].href) {
alert("found link ["+lis[i].childNodes[0].href+"]");
}
}
}
</script>

(Testes on IE 6.0 only)

--Jerome
Jul 23 '05 #2
Jerome Bei wrote:
Try this:

<script>
uls = document.getEle mentsByTagName( "UL");
for (var u=0; u<uls.length; u++) {
alert("entering list ["+u+"]");
lis=uls[u].getElementsByT agName("LI");
for (var i=0; i<lis.length; i++) {
if (lis[i].childNodes[0] && lis[i].childNodes[0].href) {
alert("found link ["+lis[i].childNodes[0].href+"]");
}
}
}
</script>

(Testes on IE 6.0 only)

--Jerome


Works nicely, fetches the links if there are, and it works on Mozilla too.

Thanks!
Michael

-
The human animal differs from the lesser primates in his passion for
lists of "Ten Best".
-- H. Allen Smith

Jul 23 '05 #3
michael wrote:
Jerome Bei wrote:

Try this:

<script>
uls = document.getEle mentsByTagName( "UL");
for (var u=0; u<uls.length; u++) {
alert("entering list ["+u+"]");
lis=uls[u].getElementsByT agName("LI");
for (var i=0; i<lis.length; i++) {
if (lis[i].childNodes[0] && lis[i].childNodes[0].href) {
If anything is inserted between the <li> and <a> tags, even a space,
this will fail as the <a> element will no longer be the first child
of the <li>.

Probably better to use a recursive function to go down the tree from
the <li> to see if it has an <a> element as a descendant.
alert("found link ["+lis[i].childNodes[0].href+"]");
}
}
}
</script>

(Testes on IE 6.0 only)

--Jerome

Works nicely, fetches the links if there are, and it works on Mozilla too.


But will fall over if you insert anything between the <li> and <a>
tags, as that will insert another element and the parent/child
relationship is broken. Below is a script that runs down the tree
to the first <a> and returns that (if there is one).
<script type="text/javascript">
function getULs() {
var h, i, u, lena, lenb, lis, uls;
uls = document.getEle mentsByTagName( "UL");
for ( u=0, lena=uls.length ; u<lena; u++) {
alert("entering list [" + u + "]");
lis = uls[u].getElementsByT agName("LI");
for (i=0, lenb=lis.length ; i<lenb; i++) {
if ( (h = hasAchild(lis[i])) ) {
alert("found link [" + h.id + "]");
}
}
}
}

// Given an element ref, descend element tree until an <a> is found
// Return a reference to the element or null if not found
function hasAchild(x){
isA = false; // global
if (x.nodeName == 'A') {
isA = x;
return isA; // Stop descent on first A element
}
for (var i=0; i<x.childNodes. length; i++) {
// Descend if not found an A yet
if (!isA) hasAchild(x.chi ldNodes[i]);
}
return isA;
}

</script>
</head>
<body id="theBody">
<ul>
<li><span>space r</span> <a id="a0" href="blah" onclick="getULs ();
return false;">the ref</a></li>
<li><a id="a1" href="blah" onclick="getULs (); return false;">the
ref</a></li>
<li>no ref</li>
</ul>
--
Rob
Jul 23 '05 #4
RobG wrote:
michael wrote: [...]
// Given an element ref, descend element tree until an <a> is found
// Return a reference to the element or null if not found
function hasAchild(x){
isA = false; // global
if (x.nodeName == 'A') {
isA = x;
return isA; // Stop descent on first A element
}
for (var i=0; i<x.childNodes. length; i++) {
// Descend if not found an A yet
if (!isA) hasAchild(x.chi ldNodes[i]);
}
return isA;
}


Had a bit of fun with this, here's a neater version:

function hasAchild(x){
isA = ( 'A' == x.nodeName)? x : false;
for (var i=0, j=x.childNodes. length; !isA && i<j; i++) {
hasAchild(x.chi ldNodes[i]);
}
return isA;
}
--
Rob
Jul 23 '05 #5
On 04/05/2005 08:35, RobG wrote:

[snip]
If anything is inserted between the <li> and <a> tags, even a space,
this will fail as the <a> element will no longer be the first child
of the <li>.

Probably better to use a recursive function to go down the tree from
the <li> to see if it has an <a> element as a descendant.


Probably better to use getElementsByTa gName to find any A elements
within a list, directly. An A element would only be valid within a list
item, so it seems rather pointless to spend time walking through the tree.

[snip]

Mike

--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.
Jul 23 '05 #6
Michael Winter wrote:
On 04/05/2005 08:35, RobG wrote:

[snip]
If anything is inserted between the <li> and <a> tags, even a space,
this will fail as the <a> element will no longer be the first child
of the <li>.

Probably better to use a recursive function to go down the tree from
the <li> to see if it has an <a> element as a descendant.

Probably better to use getElementsByTa gName to find any A elements
within a list, directly. An A element would only be valid within a list
item, so it seems rather pointless to spend time walking through the tree.


Killjoy.
--
Rob
Jul 23 '05 #7
> Probably better to use getElementsByTa gName to find any A elements

There are obvsiously many ways and maybe this one would be the best. I'm a
bit lost however as how to piece it all together.
Therefore I shall try and explain a bit more what I'm looking for:

I plan to generate a drop-down menu with CSS hover effects that would
simply work on top of bare-bone unordered lists and which will be
javascript generated by a central.js file for easy cross-site modifications.

Disregarding style issues for this example sake, the navigation may be
described simply as a bunch of links, within <LI>'s, within different
groups of <UL>'s.

These UL's will be horizontally aligned in CSS navbar style, and only the
first link of each UL group will be visible until the mouse hovers over it,
at which point the complete array of links of the UL group appears below it.

The first and always visible link of each UL would simply lead to an
overview page containing a summary of contents for its group of links.
So the top-level links, would function a bit like a subject headings,
although they may be considered by the javascript as any of the links
contained within their groups.

The javascript would define a class property for all LI's in each group, as
either:
The active, green class, if the user is on any page linked within its group.
OR
Non-active, blue class, for all other UL's and their LI's contained within.

The purpose of the CSS class is only to indicate in which section the user
currently is, which should make more sense in the CSS version, as only the
first link is displayed, and as the mouse hovers over the currently active
group with its current page on display, or when its over a non-active group.

An example with only two link groups below, if viewed as a page named
"lemurs.htm l" would style all background of the "flora_and_faun a" group of
links light-green, whilst if viewed as a page named "hiking.htm l", all
links in the "activities " group would be light-blue. Or, a page not linked
from anywhere within the js menu itself, all groups would remain light-blue.

Note that each link would appear only in one place or the navigation system
woudl not be clear to the user.

My so-called javascript below requires all links and groups pre-defined,
and filenames in the if statements explicity typed out etc.
This may be OK for a few links only but to be used in a => 50 links
nav-system that one can easily modified its not a very good solution.
But anyway, the functionality could be more or less same as below mock-up:

<style>
..green { background-color:lightgree n }
..blue { background-color:lightblue ; }
</style>

var f = window.location .href; /* get file name portion of URL */
file = f.substring (f.lastIndexOf( '/') +1);
function display_links(g roup){ /* run function with group argument */
var state = "green";

/* explicity type possible combinations for each group */
if (group == "flora_and_faun a" && file == "flora_and_faun a.html" || group
== "flora_and_faun a" && file == "lemurs.htm l" || group == "flora_and_faun a"
&& file == "chameloens.htm l" || group == "flora_and_faun a" && file ==
"mangroves.html "){
return state;
}

/* and again ... */
else if (group == "activities " && file == "activities.htm l" || group ==
"activities " && file == "hiking.htm l" || group == "activities " && file ==
"diving.htm l"){
return state;
}

/* if none is matched, eg. a user is on a page not linked within the .js
navigation system itself, all groups light-blue */
else {
return "blue";
}

}

/* write out each ul, li and link, and run function to set class value */
document.write( '<ul>')
document.write( '<li class='+display _links('flora_a nd_fauna')+'><a
href="flora_and _fauna.html">Fl ora & Fauna</a></li>')
document.write( '<li class='+display _links('flora_a nd_fauna')+'><a
href="lemurs.ht ml">Lemurs</a></li>')
document.write( '<li class='+display _links('flora_a nd_fauna')+'><a
href="chameleon s.html">Chamele ons</a></li>')
document.write( '<li class='+display _links('flora_a nd_fauna')+'><a
href="mangroves .html">Mangrove s</a></li>')
document.write( '</ul>')
document.write( '<ul>')
document.write( '<li class='+display _links('activit ies')+'><a
href="activitie s.html">Activit ies</a></li>')
document.write( '<li class='+display _links('activit ies')+'><a
href="hiking.ht ml">Hiking</a></li>')
document.write( '<li class='+display _links('activit ies')+'><a
href="diving.ht ml">diving</a></li>')
document.write( '</ul>')

Any ideas, and especially short code would be greatly appreciated!

Many thanks,
Michael
--

You know the great thing about TV? If something important happens
anywhere at all in the world, no matter what time of the day or night,
you can always change the channel.
-- Jim Ignatowski
Jul 23 '05 #8
michael wrote:
Probably better to use getElementsByTa gName to find any A elements

There are obvsiously many ways and maybe this one would be the best. I'm a
bit lost however as how to piece it all together.
Therefore I shall try and explain a bit more what I'm looking for:

[...]
')

Any ideas, and especially short code would be greatly appreciated!


Yes, there are a zillon ways to do this, google "DHTML menu".

Forget 'document.write ' to create your menu as the page loads, that
will guarantee that non-JavaScript browsers can't use your site.

To get further help:

1. Create your menus as static HTML.

2. Add DHTML behaviour as an add-on, that way non-JavaScript browsers
can still navigate your pages.

3. As part of the above, you can see if a UL group contains an HREF
with the same filename as the current page. If so, change its
parent UL class to 'active'.

I've posted a bit of code that just does the class thing, I've
included multiple classes so I can detect the 'head' ULs (I'm not
interested in descendant ULs, you may be) as an example, but my idea
of what you are trying to do is probably very different to what you
are actually doing.

Note you don't have to define 'convenience' classes like head and sub
if you don't want to.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title> Z 0 </title>
<meta http-equiv="Content-Type"
content="text/html; charset=ISO-8859-1">
<style type="text/css">
..high {background-color: #99FFCC; color: black;}
..low {background-color: #33CC00; color: white;}
</style>
<script type="text/javascript">

function doClass(){
var As, ff, x;
var a = RegExp('.*/'); // Needed many times, compile for speed
var f = document.URL.re place(a,''); // filename of current page
var d = document.getEle mentById('menu' );
var uls = d.getElementsBy TagName('ul');

for (var i=0, j=uls.length; i<j; i++){
x = uls[i];

// If the UL className string includes word 'head'
if ( /\bhead\b/.test(x.classNa me) ){

// Get its A elements
As = x.getElementsBy TagName('a');

// Search for matching file names
for (var k=0, m=As.length; k<m; k++) {
ff = As[k].href.replace(a ,'');

// If match, modify the className string of the parent UL
if ( ff == f ){
x.className = x.className.rep lace(/\blow\b/,'high');

// No need to continue once we've found one
return;
}
}
}
}
}
</script>
</head>
<body onload="doClass ();">
<div id="menu">
<ul class="head low" id="blah">
<li><a href="z0.html"> Flora&nbsp;&amp ;&nbsp;funa</a>
<ul class="sub">
<li><a href="z1.html"> Pretty&nbsp;flo wers</a></li>
<li><a href="z2.html"> Deadly&nbsp;vin es</a></li>
</ul>
</li>
</ul>
<ul class="head low">
<li><a href="z3.html"> Aquatic&nbsp;cr eatures</a>
<ul class="sub">
<li><a href="z4.html"> Pretty&nbsp;fis h</a></li>
<li><a href="z5.html"> Don&#39t&nbsp;eat</a></li>
</ul>
</li>
</ul>
</div>
</body>
</html>
--
Rob
Jul 23 '05 #9
RobG wrote:
michael wrote:
[...]

Any ideas, and especially short code would be greatly appreciated!

[...]
var f = document.URL.re place(a,''); // filename of current page


Sorry, forgot IE doesn't do document.URI, try this:

var f = document.locati on.href.replace (a,'');

[...]

--
Rob
Jul 23 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
4662
by: bearclaws | last post by:
I am looping through a list of categories and want to display the list horizontally (instead of vertically). I want to create a single row with 4 list items in each cell of the row. I thought this would work but I get this error: "End tag 'xsl:if' does not match the start tag 'ul'." Any thoughts?
5
9245
by: toylet | last post by:
Attached is some css codes for a website. It has 3 parts: top-bar, side-bar (on the left) and main-body. The top-bar has a mouseover menu called top-menu implemented via ul:hover. When the mouse pointer hovers over the top-menu, the bottom margin of the top-bar expands downwards. How could I make the hover menu to stack on top of the main-body, not expanding the bottom margin of the top-bar? I believe it has something to do with...
19
17561
by: CMAR | last post by:
I have the following markup. The problem is that the browser, e.g., IE6, inserts several lines of blank space between the <div> and the following table. Is there a way to minimize that vertical spacing? Thanks, CMA <div class="vlgray">Condition</div> <table cellpadding="0" cellspacing="0">
4
2210
by: abs | last post by:
Anybody has an idea how to get the <ul> element which is not nested in <li> element ? In other words I have several lists like this: <ul id="1"> <li>Aaaaaaaa</li> <li>Bbbbbbbb</li> <li>Cccccccc <ul> <li>111111</li> <li>222222</li>
2
7632
by: Shaun | last post by:
Hello! I have a quick question regarding CSS and having it applied to all elements. I am trying to eliminate the gap between a paragraph and a list that usually occurs in html and I've found away to do that with this code: <p>a</p> <ul style="margin-top: -20; padding-top: 0"> <li>1</li>
11
5175
by: namenotgivenhere | last post by:
My design goal is to make the white space above and below <p> and <ul> equal to the height of my font. The first step to achieving this I believe is to have an equal amount of white space above or below <p> and <ul>. Can someone suggest a method using css to accomplish this? I have succeeded in doing this in IE6 but I'd also like to know if there's a method to achive this goal that will have a similar visual look in other modern browsers....
3
6689
by: Man-wai Chang | last post by:
A 2 columns x 10 rows matrix input form <ul> <li> <ul> <li>item name 1 <li><input type="textbox" name="input_col_1_row_1"> <li><input type="textbox" name="input_col_1_row_2"> </ul> <li>
6
4472
by: capricious | last post by:
Is it possible, so that when you do multiple <UL>'s to control how deep the UL's are marked? For example, it would defaultly look like this with multiple ULs and LIs: -- Code : Main Menu<ul>Fruits<ul><li>Apples</li><li>Oranges</li></ul></ul> .. -- Returns :
2
2362
by: Shahid | last post by:
Hi, I am parsing an .HTML file that contains following example code: <div> <p class="html_preformatted" awml:style="HTML Preformatted" dir="ltr" style="text-align:left"><span style="font-size:12pt;font- family:'Arial'" xml:lang="en-US" lang="en-US">Normal Text Arial 12 Black before bullets.</span></p> <ul> <li class="html_preformatted" dir="ltr" style="text- align:left">&nbsp;<span style="font-size:12pt;font-family:'Arial'"
0
9571
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10169
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10013
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9841
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5280
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5424
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3930
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3533
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2807
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.