Forum Moderators: open

Message Too Old, No Replies

dynamically change onmouseover of links

change links' onmouseover and onmouseout properties with javascript

         

code_geek

12:04 am on Nov 15, 2004 (gmt 0)

10+ Year Member



there is a thread about this (http://www.webmasterworld.com/forum91/1546.htm), but it is very old and i cannot reply to it anymore.
please read that thread to see what i mean.
i have adapted their code to make it parse all links on a page and if they open in a new window (that is, if their target is _blank or new, then the status bar will prepend (popup) before the address in the status bar. here is the code:

<html>
<head>
<title>test</title>
<script language="javascript">
function changeLinks() {
for (var i = 0; i < alinks.length; i++) {
if ((document.links[i].target == "_blank") ¦¦ (document.links[i].target == "new")) {
document.links[i].addeventlistener("onmouseover", changeStatus(document.links[i].href), false);
document.links[i].addeventlistener("onmouseout", changeStatus(), false);
}
}
}
function changeStatus(href) {
window.status = "(popup)" + href;
return true;
}
function changeStatus() {
window.status = "";
return true;
}
</script>
</head>
<body onLoad="changeLinks()">
<a href="javascript:void(0)">default</a><br>
<a href="javascript:void(0)" target="_blank">_blank</a><br>
<a href="javascript:void(0)" target="new">new</a>
</body>
</html>

but it doesn't work ;(

note: this is a whole html page; save it as test.html and open it in your browser to see it
another note: this code does not work in internet explorer. to make it work in ie, change both instances of addeventlistener to attachevent

either way, it is broken--what am i doing wrong?

Lance

1:07 am on Nov 15, 2004 (gmt 0)

10+ Year Member



I think your array "alinks" is not defined. Try adding:

var alinks = document.getElementsByTagName("a");

as the first line of the function.

code_geek

1:23 am on Nov 15, 2004 (gmt 0)

10+ Year Member


thank you for your reply, Lance, but i still have the same problem. here is the code again:

<html>
<head>
<title>test</title>
<script language="javascript">
function changeLinks() {
for (var i = 0; i < document.links.length; i++) {
if ((document.links[i].target == "_blank") ¦¦ (document.links[i].target == "new")) {
document.links[i].addeventlistener("onmouseover", changeStatus(document.links[i].href), false);
document.links[i].addeventlistener("onmouseout", changeStatus(), false);
}
}
}
function changeStatus(href) {
window.status = "(popup)" + href;
return true;
}
function changeStatus() {
window.status = "";
return true;
}
</script>
</head>
<body onLoad="changeLinks()">
<a href="javascript:void(0)">default</a><br>
<a href="javascript:void(0)" target="_blank">_blank</a><br>
<a href="javascript:void(0)" target="new">new</a>
</body>
</html>

i have eliminated the alinks array altogether, just sticking with the document.links array. this should work, no?
perhaps i am misusing the overloading of the changeStatus() function, or the implementation of the href parameter for the changeStatus() function?
still, SOMETHING should display in the status bar, if only "undefined"

Bernard Marx

2:07 am on Nov 15, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here are 3 more:

1. addEventListener - JS is case-sensitive

2. addEventListener takes a function reference for its 2nd arg, not a function call.

3. There are two

changeStatus
definitions. You can't overload functions in JS.

(4) This won't work in IE, as it doesn't recognise addEventListener.

code_geek

2:12 am on Nov 15, 2004 (gmt 0)

10+ Year Member


again, thanks Bernard, but i still can't make this work (in Mozilla Firefox 1.0--for IE, change addEventListener to attachEvent):

<html>
<head>
<title>test</title>
<script language="javascript">
function changeLinks() {
for (var i = 0; i < document.links.length; i++) {
if ((document.links[i].target == "_blank") ¦¦ (document.links[i].target == "new")) {
document.links[i].addEventListener("onmouseover", changeStatus, false);
document.links[i].addEventListener("onmouseout", returnStatus, false);
}
}
}
function changeStatus() {
window.status = "(popup)";
return true;
}
function returnStatus() {
window.status = "";
return true;
}
</script>
</head>
<body onLoad="changeLinks()">
<a href="javascript:void(0)">default</a><br>
<a href="javascript:void(0)" target="_blank">_blank</a><br>
<a href="javascript:void(0)" target="new">new</a>
</body>
</html>

any ideas?

Bernard Marx

9:01 pm on Nov 15, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There is one more error that I forgot to mention...

addEventListener's event types don't include the 'on':

addEventListener("mouseover", changeStatus, false);

I had a go. I decided to use the 'traditional' approach, with dot syntax. My reasoning was that we can A) avoid having to write a special function, or code-branch to get around IE's non-support of addEventListener, and B) IE's attachEvent isn't executed in the context of the element (ie. it's not a method call). This makes is hard to refer back to the element so as to find its target value (which you originally wanted to include).


<html><head><title>test</title>
<script type="text/javascript">

window.onload = changeLinks;

function changeLinks()
{
var links = document.links, link, k=0;
var targetReg = /^_blank$¦^new$/i;

while(link=links[k++])
if(targetReg.test(link.target))
{
link.onmouseover = changeStatus;
link.onmouseout = returnStatus;
}
}

function changeStatus() {
window.status = "(popup) " + this.target;
return true;
}
function returnStatus() {
window.status = "";
return true;
}

</script>
</head>
<body>
<a href="javascript:void(0)">default</a><br>
<a href="javascript:void(0)" target="_blank">_blank</a><br>
<a href="javascript:void(0)" target="new">new</a>
</body>
</html>

Trouble is it doesn't work in Mozilla (or Opera either).
The problem isn't the assignment of events to methods per se - that's working as normal. It's something to do with status messages that I still can't work out.

code_geek

9:50 pm on Nov 15, 2004 (gmt 0)

10+ Year Member


yes! thank you

a little tweaking and it works in both moz and ie:

<html><head><title>test</title>
<script type="text/javascript">

window.onload = changeLinks;

function changeLinks()
{
var links = document.links, link, k=0;

while(link=links[k++])
if((link.target=="new")¦¦(link.target=="_blank"))
{
link.onmouseover = changeStatus;
link.onmouseout = returnStatus;
}
}

function changeStatus() {
window.status = "(popup) " + this.href;
return true;
}
function returnStatus() {
window.status = "";
return true;
}

</script>
</head>
<body>
<a href="javascript:void(0)">default</a><br>
<a href="javascript:void(0)" target="_blank">_blank</a><br>
<a href="javascript:void(0)" target="new">new</a>
</body>
</html>

one thing i don't understand: what does the line do that says while(link=links[k++])?
i think you are assigning the variable link to point to the object referred by the element k of the object array links, while adding 1 to k each time the loop runs, but i'm not sure

thanks a lot for your help!

Bernard Marx

12:31 pm on Nov 18, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Exactly that. The counter increment, variable assignment, and the boundary test are all done in a single statement. I find it a bit clearer for looping element collections.

Mozilla's Javascript console shows a warning when it's used, suggesting that the assignment is in fact a mistyped comparison. The fact is that it kind of acts like a condition. Assignments statements have values themselves - the value being assigned. While k is in range, the value of the assignment is the object reference returned, which "while" evealuates to true. As soon as k goes out of range (end of collection), the assignment has the value null (DOM collections return null when you try to access an element with an invalid index/identifier). null is evaluated to false, and the loop stops.

One thing is that, in this form, k is always one step ahead of the currently held element, which is fine if you don't need to use k's value again. The better way is to set k to -1, then pre-increment. Then k holds the current element's index.

[pre]
k=-1
while(link=links[++k])
{
doSomething
}

[/pre]

The construction is perfect for collections, but can be used for arrays too, butshould only be used on arrays that you are 100% certain do not contain any members that evaluate to false [false,0,"",null,undefined] (or are sparse) - else the loop will stop prematurely.