...

View Full Version : adding window event listener in loop



xelawho
09-19-2011, 02:08 AM
hello,

I am trying to add a window event listener on some links in a loop instead of doing them one by one. I've tried



function setListeners (){
for (var i = 0; i < document.links.length; i++) {
src=document.links[i].href;
document.links[i].onmousemove=changeIframeSrc(src, 'solid',1, event);
document.links[i].onmouseout=changeIframeSrc(null,'none',0,event);
}
}


and



function setListeners (){
for (var i = 0; i < document.links.length; i++) {
src=document.links[i].href;
document.links[i].onmousemove=function(a1,a2,a3,a4){
return function(){changeIframeSrc(a1,a2,a3,a4);}
}(src, 'solid',1, event);
}
}


but the event keeps coming up undefined. Any ideas on how to do this?

DaveyErwin
09-19-2011, 02:29 AM
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="generator" content="daveyerwin">
<title>Untitled</title>

<script type="text/javascript">

function init(){

for(var i=document.links.length;i--; ){
document.links[i].onmouseover=function(){alert('x');};
};
};
</script>

</head>
<body onload="init();">

<div id="td1">
<p>
<a href="/js.htm"> JavaScript </a>
<a href="/java.htm"> Java </a>
</p>
</div>

</body></html>

xelawho
09-19-2011, 02:36 AM
thanks for the reply DaveyErwin, but it's the event argument here:
changeIframeSrc(src, 'solid',1, event);

that is coming up as undefined (I imagine because an event hasn't actually happened yet)...

DaveyErwin
09-19-2011, 02:56 AM
thanks for the reply DaveyErwin, but it's the event argument here:
changeIframeSrc(src, 'solid',1, event);

that is coming up as undefined (I imagine because an event hasn't actually happened yet)...

Well uh , show a complete
page (small as possible)that
demonstrates the prob
and Ill tell you whats wrong.
I'm a really poor guesser.

xelawho
09-19-2011, 03:14 AM
ok. sorry - I thought there may be some one-size-fits-all trick...



<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="UTF-8">
<style>
#square {
position:absolute;
}
</style>
<script type="text/javascript">

function MoveSquare (e) {
var square = document.getElementById ("square");
var posx = 0;
var posy = 0;
if (e==null)
e = window.event;
if (e.pageX || e.pageY){
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY){
posx = (e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft);
posy = (e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop);
}
square.style.left = posx+15 + "px";
square.style.top = posy+20 + "px";
}

function changeIframeSrc(src,bstyle,bweight,event) {
var box=document.getElementById("square");
var el = document.getElementById("ifrm");
el.src = src;
box.style.borderStyle=bstyle;
box.style.borderWidth=bweight+"px";
MoveSquare(event);
}


function setListeners (){
for (var i = 0; i < document.links.length; i++) {
src=document.links[i].href;
document.links[i].onmousemove=changeIframeSrc(src, 'solid',1, event);
document.links[i].onmouseout=changeIframeSrc(null,'none',0,event);
}
}
</script>
</head>

<body onload=setListeners()>
<div style="width:100%">
<a href="http://www.google.com";>Google</a><br>
<a href="http://www.yahoo.com";>Yahoo</a><br>
<a href="http://www.theonion.com";>The Onion</a><br>
</div>

</div>

</div>
<div id="square" >
<iframe id="ifrm" frameborder="0" src=""></iframe>
</div>
</body>
</html>

xelawho
09-19-2011, 03:22 AM
no, that's ok. I got it :D



function setListeners (){
for (var i = 0; i < document.links.length; i++) {
src=document.links[i].href;
document.links[i].onmousemove=function (event){changeIframeSrc(src, 'solid',1, event);}
document.links[i].onmouseout=function (event){changeIframeSrc(null,'none',0,event);}
}
}

xelawho
09-19-2011, 03:27 AM
no, wait, I didn't :(

all the listeners point to the same link :confused:

DaveyErwin
09-19-2011, 03:58 AM
no, wait, I didn't :(

all the listeners point to the same link :confused:

Not any more ...


<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="UTF-8">
<style>
#square {
position:absolute;
}
</style>
<script type="text/javascript">

function changeIframeSrc(src,bstyle,bweight) {
var box=document.getElementById("square");
var el = document.getElementById("ifrm");
el.src = src;
box.style.borderStyle=bstyle;
box.style.borderWidth=bweight+"px";
//MoveSquare();
}


function setListeners (){
for (var i = 0; i < document.links.length; i++) {
document.links[i].onmousemove=(function(){
var src = document.links[i].href;
return function(){
changeIframeSrc(src, 'solid',1);
} })()
document.links[i].onmouseout=function(){changeIframeSrc(null,'none',0);}
}
}
</script>
</head>

<body onload="setListeners()">
<div style="width:100%">
<a href="http://www.google.com";>Google</a><br>
<a href="http://www.yahoo.com";>Yahoo</a><br>
<a href="http://www.theonion.com";>The Onion</a><br>
</div>

<div id="square" >
<iframe id="ifrm" frameborder="0" src="" ></iframe>
</div>
</body>
</html>that part about moving the box
around well I wasn't prepared for
that , Ill get back to ya on that one.

xelawho
09-19-2011, 04:04 AM
that part about moving the box
around well I wasn't prepared for
that , Ill get back to ya on that one.

cool... 'cos that's the important bit... thanks, DaveyE.

Old Pedant
09-19-2011, 04:04 AM
event is only available in the way you coded it with non-MSIE browsers (and MSIE 9).

I think it is time to rewrite your changeIframeSrc code.



function setListeners ()
{
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++)
{
var link = links[i];
link.onmousemove = function (evt){changeIframeSrc(this.src, 'solid',1, evt); } ;
link.onmouseout = function (evt){changeIframeSrc(null,'none',0,evt); };
}
}

function changeIframeSrc(src,bstyle,bweight,evt)
{
if ( evt == null ) evt = window.event; // for older MSIE
var box=document.getElementById("square");
var el = document.getElementById("ifrm");
el.src = src;
box.style.borderStyle=bstyle;
box.style.borderWidth=bweight+"px";
MoveSquare(evt);
}

Of course, if you were already doing that event==null detection in MoveSquare, you can ignore me.

The important part was the this.src in the onmouseover function.

Old Pedant
09-19-2011, 04:08 AM
Personally, and I do mean personally, I'd have probably coded:


function setListeners ()
{
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++)
{
var link = links[i];
link.onmousemove = function (evt){changeIframeSrc(this,evt,true);};
link.onmouseout = function (evt){changeIframeSrc(this,evt,false);};
}
}

function changeIframeSrc(link, evt, isOver)
{
var box=document.getElementById("square");
var el = document.getElementById("ifrm");
el.src = isOver ? link.src : null;
box.style.borderStyle = isOver ? "solid" : "none";
box.style.borderWidth = isOver ? "1px" : "0px"; /* ?? why? if style is none, width ignored? */
MoveSquare(evt == null ? window.event : evt);
}

DaveyErwin
09-19-2011, 04:16 AM
Thank you o.p.


even though venegal already explained to
me about closures ...




That's the right idea, but it's a bit convoluted and makes the whole closure thing look more complicated than it really is.

Creating a closure in order to pass that local variable as a parameter is as easy as this:

function human2(toDisplay2) {
var toAdd = toDisplay2.substring(0,1);
document.getElementById('box').innerHTML += toAdd;
setTimeout(function () {human2(toDisplay2);} , 500);
}



I'm still convoluting.

xelawho
09-19-2011, 04:48 AM
mmm...

I have tried both versions and they both give "file not found" inside the iFrame...

this is what I did, based on Old Pedant's personal preference

(no doubt I made some goofy mistake somewhere, but I can't see it)



<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="UTF-8">
<style>
#square {
position:absolute;
}
</style>
<script type="text/javascript">

function MoveSquare (e) {
var square = document.getElementById ("square");
var posx = 0;
var posy = 0;
if (e==null)
e = window.event;
if (e.pageX || e.pageY){
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY){
posx = (e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft);
posy = (e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop);
}
square.style.left = posx+15 + "px";
square.style.top = posy+20 + "px";
}

function changeIframeSrc(link, evt, isOver)
{
var box=document.getElementById("square");
var el = document.getElementById("ifrm");
el.src = isOver ? link.src : null;
box.style.borderStyle = isOver ? "solid" : "none";
box.style.borderWidth = isOver ? "1px" : "0px"; /* ?? why? if style is none, width ignored? */
MoveSquare(evt == null ? window.event : evt);
}


function setListeners ()
{
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++)
{
var link = links[i];
link.onmousemove = function (evt){changeIframeSrc(this,evt,true);};
link.onmouseout = function (evt){changeIframeSrc(this,evt,false);};
}
}
</script>
</head>

<body onload=setListeners()>
<div style="width:100%">
<a href="http://www.google.com";>Google</a><br>
<a href="http://www.yahoo.com";>Yahoo</a><br>
<a href="http://www.theonion.com";>The Onion</a><br>
</div>

</div>

</div>
<div id="square" >
<iframe id="ifrm" frameborder="0" src=""></iframe>
</div>
</body>
</html>


[EDIT]

but it appears that changing those lines to


link.onmousemove = function (evt){changeIframeSrc(this.href,evt,true);};
link.onmouseout = function (evt){changeIframeSrc(this.href,evt,false);};

does the trick. thanks, guys

xelawho
09-19-2011, 05:20 AM
ok...

so if anybody feels like answering a question or two, I'm going to throw them out there. This is how my functions ended up looking (I made them as close to the ones that I wrote so I could try to see what went wrong):



function changeIframeSrc(src,bstyle,event) {
var box=document.getElementById("square");
var el = document.getElementById("ifrm");
el.src = src;
box.style.borderStyle=bstyle;
MoveSquare(event);
}

function setListeners () {
var links = document.getElementsByTagName("a");
for (var i = 0; i < links.length; i++) {
var link = links[i];
link.onmousemove = function (event){changeIframeSrc(this.href,"solid",event);};
link.onmouseout = function (event){changeIframeSrc(null,"none",event);};
}
}

(I ended up putting the border width in the css because as Old Pedant points out, if the style is none there is no width)

but here's the bit that confuses me, and I guess I'm still a little shaky on what "this" means in javascript.

I'm pretty sure I tried calling functions like that before, only getting the href as the link attribute in the loop. But why, if it was the link that was the problem, was I getting an error saying that "event is undefined"?

and why, when I was harcoding these things, did they work something like this:

<a href="http://www.google.com" onmousemove = "changeIframeSrc(this,'solid',event)"; onmouseout = "changeIframeSrc(null,'none',event)";>Google</a><br>

but inside the loop, that "this" doesn't work and it has to be "this.href"?

and (for bonus points) why can't I change the frameborder of the iframe like this:
el.frameborder=myvar
in the changeIframeSrc function?

any thoughts appreciated :thumbsup:

Old Pedant
09-19-2011, 06:44 AM
One *TINY* typo in my post #11.



el.src = isOver ? link.src : null;

should be


el.src = isOver ? link.href : null;

Then it works.

Old Pedant
09-19-2011, 06:45 AM
why, when I was harcoding these things, did they work something like this:


<a href="http://www.google.com" onmousemove = "changeIframeSrc(this,'solid',event)"; onmouseout = "changeIframeSrc(null,'none',event)";>Google</a><br>

but inside the loop, that "this" doesn't work and it has to be "this.href"?

Because, in the meantime, you have apparently changed your code for changeIframeSrc.

I'll bet that, before, you were doing the equivalent of my

el.src = isOver ? link.href : null;

xelawho
09-19-2011, 07:15 AM
mmm... I'm pretty sure I didn't. This is was the working version, Mk I:



<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="UTF-8">
<style>
#square {
position:absolute;
}
</style>
<script type="text/javascript">

function MoveSquare (e) {
var square = document.getElementById ("square");
var posx = 0;
var posy = 0;
if (e==null)
e = window.event;
if (e.pageX || e.pageY){
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY){
posx = (e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft);
posy = (e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop);
}
square.style.left = posx+15 + "px";
square.style.top = posy+20 + "px";
}

function changeIframeSrc(src,bstyle,bweight,event) {
var box=document.getElementById("square");
var el = document.getElementById("ifrm");
el.src = src;
box.style.borderStyle=bstyle;
box.style.borderWidth=bweight+"px";
MoveSquare(event);
}


</script>
</head>

<body>
<div style="width:100%">
<a href="http://www.google.com" onmousemove = "changeIframeSrc(this,'solid',1,event)"; onmouseout = "changeIframeSrc(null,'none',0,event)";>Google</a><br>
<a href="http://www.yahoo.com" onmousemove = "changeIframeSrc(this,'solid',1,event)"; onmouseout = "changeIframeSrc(null,'none',0,event)";>Yahoo</a><br>
<a href="http://www.theonion.com" onmousemove = "changeIframeSrc(this,'solid',1,event)"; onmouseout = "changeIframeSrc(null,'none',0,event)";>Onion</a><br>
</div>

</div>

</div>
<div id="square" >
<iframe id="ifrm" frameborder="0" src=""></iframe>
</div>
</body>
</html>

xelawho
09-19-2011, 10:27 PM
why can't I change the frameborder of the iframe like this:
el.frameborder=myvar
in the changeIframeSrc function?


well, I got the answer to that one at least (in case anybody cares about iframes anymore):

el.frameBorder = myvar; :thumbsup:



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum