...

View Full Version : Find links and desired parentNode



Ulysses69
11-14-2012, 08:07 PM
I have been working on a script to find links and pass on analytical data when clicked. The first part I can do, but I'm struggling to find a way to tidy way to get desired parent ID. The idea is to find parent of clicked link, if it is undesired (such as child UL or empty) then find next parent up until we find an ID. All my links will be within ID parent, except for those immediately children of body (which will use body ID). These links are generated in a custom CMS so body tag always have an ID and so do UL and DIVs that will contain links ... some client-generated links could be created without ID hence why I am having the body as a catchall.

Anyways, if we have something like DIV > UL > LI > UL > LI > A and I click A, I want href or title to be passed along with top-most UL or DIV ID to be passed too.

The general parent ID works this way:


if (targ.parentNode.id != '') {
dad = targ.parentNode;
} else if (targ.parentNode.parentNode.id != '') {
dad = targ.parentNode.parentNode;
} else if (targ.parentNode.parentNode.parentNode.id != '') {
dad = targ.parentNode.parentNode.parentNode;
} else if (targ.parentNode.parentNode.parentNode.parentNode.id != '') {
dad = targ.parentNode.parentNode.parentNode.parentNode;
}

But I am trying to mimize the code so that I can start to add some exclusions and/or other intelligence to handle what ID should be used, and it isn't quite working:


while(targ.parentNode && targ.parentNode.id != '' && tagx.indexOf(targ.parentNode.tagNode) == -1) {
targ = targ.parentNode;
}
dad = targ;

The full page code to test might help you see what I am doing:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Find Parent Id</title>
<script type="text/javascript">
function assignClickEvent(){
var links = document.links;
for(var i =0; i < links.length; i++){
links[i].onclick = findDivId;
}
};
function findDivId(e) {
var targ;
var dad;
var idx = new Array('nav');
var tagx = new Array('BODY','P','LI','A');
if (!e){
var e = window.event;
}
if (e.target){
targ = e.target;
} else if (e.srcElement) {
targ = e.srcElement;
}


while(targ.parentNode && targ.parentNode.id != '' && tagx.indexOf(targ.parentNode.tagNode) == -1) {
targ = targ.parentNode;
}
dad = targ;


/*
if (targ.parentNode.id != '') {
dad = targ.parentNode;
} else if (targ.parentNode.parentNode.id != '') {
dad = targ.parentNode.parentNode;
} else if (targ.parentNode.parentNode.parentNode.id != '') {
dad = targ.parentNode.parentNode.parentNode;
} else if (targ.parentNode.parentNode.parentNode.parentNode.id != '') {
dad = targ.parentNode.parentNode.parentNode.parentNode;
}
*/


if(dad){
//if(idx.indexOf(dad.id) == -1){
alert(dad.id + ' ' + dad.tagName + ' ' + dad.href);
//}
};
return false;
};
window.onload = assignClickEvent;
</script>
</head>
<body id="page">

<div id="main">

<h2>Header</h2>

<div>

<ul>
<li><a href="scot.html">Scotiabank</a> (6)</li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="cibc.html">CIBC</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul>

</div>

<h2>Main</h2>

<ul id="nav">
<li><a href="scot.htm">Scotiabank</a> (6)
<ul id="nav-sub">
<li id="cib-sub"><a href="scot.html">Scotiabank</a> (6)</li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul></li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="cibc.html">CIBC</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul>

</div>



<h2>Footer</h2>

<ul>
<li><a href="scot.html">Scotiabank</a> (6)</li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="cibc.html">CIBC</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul>

</body>
</html>

Ulysses69
11-15-2012, 12:27 AM
I'm not any closer with my while loop, but my original if else approach is getting closer:


if(targ.parentNode.tagName == 'BODY'){
dad = targ.parentNode;
test = 0;
} else if (targ.parentNode.id != '' && tagx.indexOf(targ.parentNode.tagNode) !== -1) {
dad = targ.parentNode;
test = 1;
} else if (targ.parentNode.parentNode.id != '' && tagx.indexOf(targ.parentNode.parentNode.tagNode) !== -1) {
dad = targ.parentNode.parentNode;
test = 2;
} else if (targ.parentNode.parentNode.parentNode.id != '' && tagx.indexOf(targ.parentNode.parentNode.parentNode.tagNode) !== -1) {
dad = targ.parentNode.parentNode.parentNode;
test = 3;
} else if (targ.parentNode.parentNode.parentNode.parentNode.id != '') {
dad = targ.parentNode.parentNode.parentNode.parentNode;
test = 4;
} else {
dad = targ.parentNode.parentNode;
test = 5;
}

AndrewGSW
11-15-2012, 01:01 AM
The id may be undefined rather than '' so it's best to test this way:


while (targ.parentNode && targ.parentNode.id &&

meaning that "it has an id" other than any of undefined, '', null, void.

Off topic, but it is preferable to declare arrays like this:


var tagx = ['BODY', 'P', 'LI', 'A'];

Your current code will skip some links. Where you have LI > A followed by an UL, clicking a link in the UL will not find the first A-link (assuming this is your intent?) as it is not a parent-element.

If you wish to search other than through the direct parent-heritage then you might consider jQuery. Using jQuery it is much easier to obtain, and navigate, siblings() and parents(), etc. It would still, however, prove a challenge to navigate reliably/consistently.

I haven't come across tagNode(?) - nodeName.

For your sample code your LI's need to have IDs to continue the search.

AndrewGSW
11-15-2012, 01:14 AM
Your sample code is stopping straight-away though as it immediately finds a (parent) LI and targ is still referring to the A that I clicked.

I'm a bit tired to correct it though at this time, soz. Try


while ((targ = targ.parentNode) && /* etc. */ )
/* empty statement */ ;

AndrewGSW
11-15-2012, 01:22 AM
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Find Parent Id</title>
<script type="text/javascript">
function assignClickEvent(){
var links = document.links;
for(var i =0; i < links.length; i++){
links[i].onclick = findDivId;
}
};
function findDivId(e) {
var targ;
var dad;
var idx = ['nav'];
var tagx = ['BODY','P','LI','A'];

e = e || window.event;
var targ = e.target || srcElement;
var clickedRef = targ.href;

while((targ = targ.parentNode) && targ.id && tagx.indexOf(targ.nodeName) == -1) {
//targ = targ.parentNode;
}
dad = targ;


/*
if (targ.parentNode.id != '') {
dad = targ.parentNode;
} else if (targ.parentNode.parentNode.id != '') {
dad = targ.parentNode.parentNode;
} else if (targ.parentNode.parentNode.parentNode.id != '') {
dad = targ.parentNode.parentNode.parentNode;
} else if (targ.parentNode.parentNode.parentNode.parentNode.id != '') {
dad = targ.parentNode.parentNode.parentNode.parentNode;
}
*/


if (dad) {
//if(idx.indexOf(dad.id) == -1){
alert(dad.id + ' ' + dad.tagName + ' ' + clickedRef);
//}
};
return false;
};
window.onload = assignClickEvent;
</script>
</head>
<body id="page">

<div id="main">

<h2>Header</h2>

<div>

<ul id="blah2">
<li><a href="scot.html">Scotiabank</a> (6)</li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="cibc.html">CIBC</a> (3)</li>
<li id="blah1"><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul>

</div>

<h2>Main</h2>

<ul id="nav">
<li><a href="scot.htm">Scotiabank</a> (6)
<ul id="nav-sub">
<li id="cib-sub"><a href="scot.html">Scotiabank</a> (6)</li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul></li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="cibc.html">CIBC</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul>

</div>



<h2>Footer</h2>

<ul>
<li><a href="scot.html">Scotiabank</a> (6)</li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="cibc.html">CIBC</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul>

</body>
</html>

Ulysses69
11-15-2012, 09:47 AM
Thanks for your feedback, Andrew.

I am new to arrays in javascript, so thanks for the tip. I also looked at the nodeTag (not sure where it came from, but it certainly wasn't needed) so thanks for that too ... and the id check.

I have a modified version of my original now ... still testing it though, before cleaning it up.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Find Parent Id</title>
<script type="text/javascript">
function assignClickEvent(){
var links = document.links;
for(var i =0; i < links.length; i++){
links[i].onclick = findDivId;
}
};
function findDivId(e) {
var targ;
var dad;

var idx = ['nav'];
var tagx = ['LI','UL','A'];
if (!e){
var e = window.event;
}
if (e.target){
targ = e.target;
} else if (e.srcElement) {
targ = e.srcElement;
}

dad = targ;



/*
while(dad.parentNode && dad.parentNode.id != '' && tagx.indexOf(dad.parentNode.tagName) == -1 && tagx.indexOf(dad.tagName) == -1) {
dad = dad.parentNode;
}
*/



if(targ.parentNode.tagName == 'BODY'){
dad = targ.parentNode;
test = 0;
} else if (targ.parentNode.id && tagx.indexOf(targ.parentNode.tagName) !== -1) {
dad = targ.parentNode;
test = 1;
} else if (targ.parentNode.parentNode.id && tagx.indexOf(targ.parentNode.parentNode.tagName) !== -1) {
dad = targ.parentNode.parentNode;
test = 2;
if(dad.parentNode.tagName == 'LI'){
dad = targ.parentNode.parentNode.parentNode.parentNode;
test = 8;
}
if(dad.parentNode.tagName == 'LI'){
dad = targ.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
test = 9;
}
} else if (targ.parentNode.parentNode.parentNode.id && tagx.indexOf(targ.parentNode.parentNode.parentNode.tagName) !== -1) {
dad = targ.parentNode.parentNode.parentNode;
test = 3;
} else if (targ.parentNode.parentNode.parentNode.parentNode.id) {
dad = targ.parentNode.parentNode.parentNode.parentNode;
test = 4;
} else {
dad = targ.parentNode.parentNode;
test = 5;
}


if(dad.tagName == 'LI'){
dad = targ.parentNode.parentNode.parentNode.parentNode;
test = 6;
if(dad.parentNode.tagName == 'LI'){
dad = targ.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
test = 7;
}
}



if(dad){
//if(idx.indexOf(dad.id) == -1){
alert('TAG = ' + dad.tagName + ' : ID = ' + dad.id + ' : HREF = ' + targ.href + ' : TEST = ' + test);
//}
};

return false;
};
window.onload = assignClickEvent;
</script>
</head>
<body id="page">

<a href="home.html">Help</a>

<div id="main">

<h2>Header</h2>

<div>

<ul>
<li><a href="scot.html">Scotiabank</a> (6)</li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="cibc.html">CIBC</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul>

</div>

<h2>Main</h2>

<ul id="nav">
<li><a href="scot.htm">Scotiabank</a> (6)
<ul id="nav-sub">
<li id="cib-sub"><a href="scot.html">Scotiabank</a> (6)
<ul id="nav-sub-sub">
<li id="cib-sub-sub"><a href="scot.html">Scotiabank</a> (6)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul></li></li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul></li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="cibc.html">CIBC</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul>

</div>



<h2>Footer</h2>

<ul>
<li><a href="scot.html">Scotiabank</a> (6)</li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="cibc.html">CIBC</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul>

</body>
</html>

AndrewGSW
11-15-2012, 07:15 PM
The code I posted in my previous post is a modified version of your original code.

Ulysses69
11-16-2012, 12:57 AM
Used a whitelist array approach in the end to get a very tight script that works under the desired framework I am using:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Find Parent Id</title>
<script type="text/javascript">
function assignClickEvent(){
var links = document.links;
for(var i =0; i < links.length; i++){
links[i].onclick = findDivId;
}
};
function findDivId(e) {
var targ;
var dad;
var idx = ['nav','navigation','main'];
var tagx = ['LI','UL','A'];
if (!e){
var e = window.event;
}

e = e || window.event;
var targ = e.target || srcElement;
var clickedRef = targ.href;

while((targ = targ.parentNode) && targ.tagName != 'BODY' && idx.indexOf(targ.id) == -1);
dad = targ;

if(dad){
alert('TAG = ' + dad.tagName + '\nID = ' + dad.id + '\nHREF = ' + clickedRef);
};

return false;
};
window.onload = assignClickEvent;
</script>
</head>
<body id="page">

<a href="home.html">Help</a>

<div id="main">

<h2>Header</h2>

<div>

<ul>
<li><a href="scot.html">Scotiabank</a> (6)</li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="cibc.html">CIBC</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul>

</div>

<h2>Main</h2>

<ul id="nav">
<li><a href="scot.htm">Scotiabank</a> (6)
<ul id="nav-sub">
<li id="cib-sub"><a href="scot.html">Scotiabank</a> (6)
<ul id="nav-sub-sub">
<li id="cib-sub-sub"><a href="scot.html">Scotiabank</a> (6)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul></li></li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul></li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="cibc.html">CIBC</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul>

</div>



<h2>Footer</h2>

<ul>
<li><a href="scot.html">Scotiabank</a> (6)</li>
<li><a href="mon.html">Bank of Montreal</a> (3)</li>
<li><a href="cibc.html">CIBC</a> (3)</li>
<li><a href="canada.html">National Bank of Canada</a> (2)</li>
</ul>

</body>
</html>

Thanks again, Andrew.

I tried to submit the thank you button, but I don't have privileges, so "Thanks you".



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum