Bogus IE mouseover on adding href

J

Jonas Smithson

I have some JavaScript that turns a row of anchors ('a' tags with no
hrefs) into links by adding a href to each one. There are two ways I
know of to do this; they both seem to have identical results in every
browser I've tested:

myElement.href="foo.html";
or
myElement.setAttribute("href", "foo.html");

Either one works fine in Firefox and Safari; as the loop runs, you can
see a whole row of anchors (which previously looked like ordinary text
to the user) suddenly turn into clickable links. It's really pretty cool.

However, there's a slight problem in IE. (I work on a Mac but I've been
testing it in IE6 on an old PC.) The code works, but as IE adds the href
to each anchor, it also puts the resultant link into a hover (or
mouseover) state -- so the user would see a whole row of links in the
hover style, as though a bunch of ghostly mouse pointers were
simultaneously hovering over all of them. If I physically mouse over and
then off each link, they resume the normal link appearance and behave
normally from then on.

I've experimented a lot but could not find a way to get IE to stop
acting as though adding a href meant it should also issue a persistent
mouseover. For example, I tried, right after adding the href to each,
applying myElement.blur() -- not surprisingly, that did nothing, since
the problem appears to be a mouseover not a focus state. More hopefully,
I tried myElement.mouseout() -- which threw an unspecified error.
Unfortunately I don't know the IE event model (or, frankly, any event
model) well enough to know how to deal with the situation.

I eventually came up with a workaround by browser sniffing, forking the
code, and using outerHTML to replace the entire element, which then
necessitated that I add some other kludgy code -- it works but it's
really ugly JavaScript.

Does anyone know how to stop IE from issuing the bogus mouseover event
as it adds a href to each anchor? Or, if that's not possible, how to
issue a mouseout event immediately afterwards, to undo the hover state?

Thanks.
 
J

JR

Hi Jonas,
I've been changing href attribute without experiencing the problem
described by you. Maybe it's because the href attribute is already
present in the anchor tag (link) and my code just changes the previous
href value to another value. Therefore I guess you might define the
initial value for the href attribute as below:

<a href="javascript:void(0)">link 1</a>
as the loop runs, you can
see a whole row of anchors (which previously looked like ordinary text
to the user) suddenly turn into clickable links. It's really pretty cool.

Of course you'll lose that 'magic'.

Cheers,
Joao Rodrigues
 
J

Jonas Smithson

JR said:
.... you might define the
initial value for the href attribute as below:

<a href="javascript:void(0)">link 1</a>


Of course you'll lose that 'magic'.

Thanks for the suggestion. The reason you're not seeing the effect I am
is probably that IE only creates the bogus mouseover/hover effect if you
create a href where there was _none_ (of any kind) before.

If the point were simply to make the text unclickable, I could do that
various ways: your suggestion of "javascript:void(0)" would work, or
else <a href=""> or <a href="#"> etc. Unfortunately, _any_ href still
makes it look like a link. What I'm building is a simple web app, not an
ordinary web page, and I don't want to confuse the user: the text
snippets are _not_ links until the user commits a certain action, so I
don't want them to look like links until then. I could just restyle them
with CSS to disguise their linky-ness (kill the blue and the underscore)
but you'd still see a finger when you moused over, implying that they're
clickable.

I realize it's a pretty obscure question, and I may be stuck with my
crappy IE-only code fork unless there's someone around here who actually
understands the IE event model well enough to suggest a more specific
solution.

Thanks for trying, though.

Jonas
 
H

Henry

JR wrote:

Presumably this is a suggestion form someone who is not aware that
javascript pseudo-protocol HREFs can themselves directly promote
issues on IE 6, and so are quite capable of introducing more problems
than they solve (with those problems being extremely hard to track
down).

I realize it's a pretty obscure question, and I may be stuck
with my crappy IE-only code fork unless there's someone around
here who actually understands the IE event model well enough
to suggest a more specific solution.

If you want people to look at this issue you should post a (cut-down/
minimal) test case that demonstrates your issue. That way it would be
possible for people to see exactly what you are doing (and how you are
doing it) and then they would have a basis for trying out alternatives
to see if they addressed the issue.

Asking people to first reproduce an issue from scratch, identify the
cause and effect relationships involved, and then work out how to
eliminate the issues is asking a great deal. And it issues that if
they can reproduce the issue if the first place, that the way they
have reproduced the issue is the same way you produced it in the first
place, else there 'solution' may have no real relevance to the
original issue.

This is particularly significant if the issue cannot be reproduced
simply. For example:-

<html>
<head>
<title></title>
</head>
<style type="text/css">
a:hover {
font-size:200%;
}
</style>
<script type="text/javascript">
function changeToLink(){
document.getElementById('x').href = 'http://www.google.com/';
}
</script>
<body>
<a id="x">xxxxxxxxxx</a>
<br>
<input value="to link" type="button" onclick="changeToLink();">
</body>
</html>

- adds an HREF to an A element that did not previously have one and in
IE 6 (6.0.2900) it does not result in that element going into an
apparent 'hover' state. That suggests your issue is caused by
something separate from the act of assigning a value to the HREF, but
without seeing it what that could be can only be guessed at.
 
J

JR

What I'm building is a simple web app, not an
ordinary web page, and I don't want to confuse the user: the text
snippets are _not_ links until the user commits a certain action, so I
don't want them to look like links until then. I could just restyle them
with CSS to disguise their linky-ness (kill the blue and the underscore)
but you'd still see a finger when you moused over, implying that they're
clickable.

Hi Jonas,
I use server side scripting (php or asp) to do such a task. I my case,
links are shown only if user is logged in or depending on some other
session variables. Another way to do that is using Ajax to load a page
with the underlying links whenever the user commits a certain action.

Hope this helps.

Joao Rodrigues
 
J

Jonas Smithson

Henry said:
If you want people to look at this issue you should post a (cut-down/
minimal) test case that demonstrates your issue. That way it would be
possible for people to see exactly what you are doing (and how you are
doing it) and then they would have a basis for trying out alternatives
to see if they addressed the issue.

Obviously I prepared insufficiently before my initial posting. Since
adding a href (to an 'a' tag that had no href) always caused the problem
in IE6 in my code, I just assumed that that alone would always cause it.
After trying the code you posted and confirming that it didn't reproduce
the problem, I realized that, as you said, there was something more
involved. Even after hours of additional experimentation, I still don't
really understand what's going on.

Below you'll find a test case I've constructed. The code will seem
excessively complicated for such a simple function, but it was extracted
from the project I'm working on and makes more sense in that context.
Please try loading it as an HTML file in Firefox and then in IE6. I
believe its instructions are self-explanatory.

If you can't see the odd effects in IE6 that I see, I'll have to
consider the possibility that a really funky pair of Firebug wannabes
that I installed in IE6 (called Companion JS and DebugBar) may be
causing the problem. Unfortunately, I can't find a "disable" command and
would rather not uninstall them entirely. But anyway I'm guessing that
this time, you'll see the same odd IE6 behavior that I'm seeing. Of
course, what I'm really hoping for is to either find out what I'm doing
wrong, or to find a workaround better than what I'm using now (outerHTML
junk) -- and even my current workaround only solves the fake-hover
problem, not the fake-visited problem.

Thanks,
Jonas

- - - - - code follows: - - - - -

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">

<head>
<title>IE_Mouseover_Weirdness_Test</title>

<meta http-equiv="content-type" content="text/html; charset=utf-8">

<style type="text/css">
body { padding: 0 18px 0 18px; }
a { padding: 0 12px 0 12px; }
a { font: bold 14px/1em verdana, helvetica, sans-serif; }
a:hover { color: red; }

/* It should seem that nothing happens if you mouse over the nonlink: */
a.nonlink { color: black; }
a.nonlink:hover { color: black; }

h1 { font-size: 18px; font-weight: bold; text-align: center; }
p { line-height: 1.3em; }
p#author { font-size: small; margin-top: 30px; }
</style>

</head>

<body>

<h1>IE Mouseover Weirdness Test</h1>

<p>This page's JavaScript ensures that exactly one out of the four
possible links is a non-link at all times. (By "non-link" I mean it has
no href and doesn't look or behave linkishly.) Clicking on any link
should demote it to a non-link, and promote the previous non-link to a
link. This works in every browser I've tried.
</p>

<a id="PossibleLinkA1" class="nonlink">PossibleLink1</a>
<a id="PossibleLinkA2" href="#flub">PossibleLink2</a>
<a id="PossibleLinkA3" href="#dub">PossibleLink3</a>
<a id="PossibleLinkA4" href="#rub">PossibleLink4</a>

<p>Actually hovering the mouse pointer over any link should be the
<i>only</i> way to turn it red; this works properly in Firefox and
Safari. However, in IE6, try clicking the links in the following order,
being careful not to pass your mouse pointer over any link unless you're
clicking it:
</p>

<ol>
<li>Click PossibleLink<b>2</b></li>
<li>Click PossibleLink<b>3</b></li>
<li>Click PossibleLink<b>4</b></li>
<li>Click PossibleLink<b>1</b></li>
</ol>

<p>In IE6, do you see three of the links simultaneously red (the hover
style) even though there's no mouse pointer over them? If so, what do
you think is causing this? What would stop it?</p>

<p>Possibly related weirdness: when (in IE6) I first click
PossibleLink<b>2</b>, it turns PossibleLink<b>1</b> into a link (as it
should) but in the visited (purple) style as though I had clicked on it
before. Even stranger: if I reload (or shift-reload) this page in IE6 --
<i>without having clicked any of the links at all</i> -- it turns all
the links into the visited style as though I'd clicked them all. I have
to clear the cache before each reload in order to see them blue (i.e.,
in the unvisited style); otherwise, all subsequent reloads show them
purple, even if I've never clicked any of them! This happens even if I
disable JavaScript in the browser, so it has me completely mystified.</p>

<p>In Firefox and Safari, the behavior is the exact opposite of IE: they
<i>never</i> put any of the links in the visited style no matter what.
(This is actually the behavior I want.) Note that there are no "visited"
styles defined in the page's CSS.</p>

<p>BTW, this page validated for both CSS and HTML at the W3C, and did
not throw any JavaScript errors or warnings in Firebug or in IE.</p>

<p id="author">Thoughts? Please respond in comp.lang.javascript or to
jonassmithson-AT-gmail.com and many thanks.</p>

<script type="text/javascript">

var linksArray; /* In the real code it's in a custom object, but in
this test code it's a global */

function prepareLinks(){
var pl1 = document.getElementById("PossibleLinkA1");
pl1.onclick = function() { respondToClick(this) };
var pl2 = document.getElementById("PossibleLinkA2");
pl2.onclick = function() { respondToClick(this) };
var pl3 = document.getElementById("PossibleLinkA3");
pl3.onclick = function() { respondToClick(this) };
var pl4 = document.getElementById("PossibleLinkA4");
pl4.onclick = function() { respondToClick(this) };

linksArray = [ pl1, pl2, pl3, pl4 ];

for(var i=linksArray.length-1;i>=0;i--){
linksArray.onclick = function(){ respondToClick(this); }
}
} // end function prepareLinks()
prepareLinks(); // Call the func just defined

/* If user clicks a link, the following function runs. It contains two
nested funcs, each of which will need to be called once: one to demote
the just-clicked link to "nonlink" status, and one to promote the
previous nonlink so it becomes a link again. The other two links should
be left alone: */
function respondToClick(theCaller){

/* Loop through all the possible links, and find out which one needs to
be promoted and which one needs to be demoted: */
for(var i=linksArray.length-1;i>=0;i--){

// If the loop is examining the same item that was clicked
// on, it must have been a link. Send it to be un-linked:
if( linksArray.id == theCaller.id ) { unLink(theCaller); }

// If the loop is examining the sole nonlink, then
// send it to the other nested func to be linkified:
else if (!linksArray.href) { makeLink(); }

} // end for loop through linksArray


/* Two nested funcs, each of which will be called once by the above
loop: */

// Make whatever was just clicked the new "nonlink":
function unLink(clickedLink){
clickedLink.className = "nonlink"; /* <= for CSS styling
purposes; not used by JS */
if(clickedLink.href) { clickedLink.removeAttribute("href"); }
}

function makeLink(){
/* No arg needed; it sees the value of linksArray in the
parent func's loop. */
linksArray.className = "";
linksArray.href = "#foo";
}

} //end respondToClick()

</script>

</body>
</html>
 
J

Jonas Smithson

I said:
function prepareLinks(){
var pl1 = document.getElementById("PossibleLinkA1");
pl1.onclick = function() { respondToClick(this) };
var pl2 = document.getElementById("PossibleLinkA2");
pl2.onclick = function() { respondToClick(this) };
var pl3 = document.getElementById("PossibleLinkA3");
pl3.onclick = function() { respondToClick(this) };
var pl4 = document.getElementById("PossibleLinkA4");
pl4.onclick = function() { respondToClick(this) };

linksArray = [ pl1, pl2, pl3, pl4 ];

for(var i=linksArray.length-1;i>=0;i--){
linksArray.onclick = function(){ respondToClick(this); }


Oops... I just realized that code was redundant; no need to assign the
function to each item individually and then all over again in the loop.
But it shouldn't hurt anything.

Jonas
 
T

Thomas 'PointedEars' Lahn

Jonas said:
Henry said:
If you want people to look at this issue you should post a (cut-down/
minimal) test case that demonstrates your issue. That way it would be
possible for people to see exactly what you are doing (and how you are
doing it) and then they would have a basis for trying out alternatives
to see if they addressed the issue.

[...]
Below you'll find a test case I've constructed. The code will seem
excessively complicated for such a simple function, but it was extracted
from the project I'm working on and makes more sense in that context.
Please try loading it as an HTML file in Firefox and then in IE6. I
believe its instructions are self-explanatory.

IMHO, the instructions belong in the posting.
If you can't see the odd effects in IE6 that I see, I'll have to
consider the possibility that a really funky pair of Firebug wannabes
that I installed in IE6 (called Companion JS and DebugBar) may be
causing the problem. Unfortunately, I can't find a "disable" command

All the more reason to get rid of them. In any case: RTFM, SFTW.
and would rather not uninstall them entirely.

Try Firebug Lite instead.
[...]
- - - - - code follows: - - - - -
[...]

Your markup is Valid, but your indentation is wrong, your pretty-printing is
practically non-existent, and your overall style must be considered
atrocious. I have actually tried to make it legible to get an idea what it
might be really doing, but I gave up half the way. "A (cut-down/minimal)
test case that demonstrates your issue." surely looks a lot different than
this. Especially, try to be precise but more consise; people are reading
your articles in their (scarce) free time, among other articles.

FWIW, I noticed that you have placed a `script' element on the bottom of the
`body' element; you should not do that but you should declare your
functions within the `head' element and call them from the `onload' event
handler attribute value of the `body' element instead.


PointedEars
 
D

Dr J R Stockton

In comp.lang.javascript message <tcyel.13992$cu.4994@news-
Why don't you upload it to some free web host so each single one of us is
not required to copy/paste it to an editor, possibly with errors, save it to
the local file system and then point a browser at it.

You are making false assertions there. At most, the reference to
copy/paste is valid (unless you count a <textarea> as an editor).

And personally I prefer to see such code before I think about executing
it.

However, test code posted here should not be much bigger than that.

It's a good idea to read the newsgroup c.l.j and its FAQ. See below.
 
J

Jonas Smithson

Thomas 'PointedEars' Lahn said:
IMHO, the instructions belong in the posting....
Your markup is Valid, but your indentation is wrong, your pretty-printing is
practically non-existent, and your overall style must be considered
atrocious....

In other words, since you don't have a clue about the answer to the
actual issue I've raised, you decided to criticise the way I formatted
my code instead. You're a pleasant character.
 
T

Thomas 'PointedEars' Lahn

Jonas said:
In other words, since you don't have a clue about the answer to the
actual issue I've raised, you decided to criticise the way I formatted
my code instead. You're a pleasant character.

Believe what you wish, you are at fault here. First, for not posting
properly; second, for not reading properly; third, for not posting properly
again although notified before.

With such an attitude I doubt you are capable of recognizing any help you
are provided with as such, so it appears rather a waste of time to try.
Have a nice rest of life.


PointedEars
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]>,
Mon, 26 Jan 2009 22:23:16, Thomas 'PointedEars' Lahn
Believe what you wish, you are at fault here. First, for not posting
properly; second, for not reading properly; third, for not posting properly
again although notified before.

With such an attitude I doubt you are capable of recognizing any help you
are provided with as such, so it appears rather a waste of time to try.
Have a nice rest of life.

Jonas, don't take it personally. Thomas Lahn probably does not hate you
any more than he hates everybody else ; he just has a naturally
obnoxious personality. Just search this newsgroup for other responses
by him, and you will see what I mean. Perhaps in his youth he was
dropped on his head from an inadequate height.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,739
Latest member
Clint8040

Latest Threads

Top