alternative to javascript hrefs

A

Andy Fish

Hi,

I want to use an anchor tag to invoke some javascript and I've read that
it's bad form to use <a href="javascript:foo()">

I've read endless usenet posts and hint sites on the net, they all suggest
different things and I can't get any kind of consistency, and I can't find
any solution that works properly for IE, opera and mozilla.

many of the recommended solutions go something like this:

<a href="javascript:void(0);" onclick="foo()" />

this generates an <a> that looks like a hyperlink (good) and it invokes
foo() as well (also good). the problem is that if in function foo, I put

window.location.href = "some new url";

it just seems to get ignored. If I miss out the href altogether, the link
works but it's not formatted as a hyperlink.

All I'm trying to do is make something that looks like a normal hyperlink
but whereby I can build the URL with some javascript rather than having it
coded into the HTML, and I have to say it's driving me mad!!. any hints
gratefully received

Andy
 
R

Robin Goodall

Andy said:
Hi,

I want to use an anchor tag to invoke some javascript and I've read that
it's bad form to use <a href="javascript:foo()">

I've read endless usenet posts and hint sites on the net, they all suggest
different things and I can't get any kind of consistency, and I can't find
any solution that works properly for IE, opera and mozilla.

many of the recommended solutions go something like this:

<a href="javascript:void(0);" onclick="foo()" />

this generates an <a> that looks like a hyperlink (good) and it invokes
foo() as well (also good). the problem is that if in function foo, I put

window.location.href = "some new url";

it just seems to get ignored. If I miss out the href altogether, the link
works but it's not formatted as a hyperlink.

All I'm trying to do is make something that looks like a normal hyperlink
but whereby I can build the URL with some javascript rather than having it
coded into the HTML, and I have to say it's driving me mad!!. any hints
gratefully received

Andy

As I believe the FAQ says, use:
<a href="#" onclick="foo();return false;">foo</a>

There false returned from the onclick event should stop the browser
actually going to "#". Though I haven't checked this in opera.

Robin
 
L

Laurent Bugnion, GalaSoft

Hi,

Robin said:
As I believe the FAQ says, use:
<a href="#" onclick="foo();return false;">foo</a>

There false returned from the onclick event should stop the browser
actually going to "#". Though I haven't checked this in opera.

Robin

No.

As stated in
<URL:http://www.jibbering.com/faq/#FAQ4_24>

you should use:
<a href="something.html" onclick="somefunction();return false">

This has the advantage, if JavaScript is disabled, that the user's web
browser will do something. It can, for example, lead him to a page where
the user can find some content, but less functionality. It can also lead
the user to a page where you explain why he should switch JavaScript on.

The browser's status bar will (in most browsers) display the location of
the HREF attribute. If this is really a problem, you can use ONMOUSEOVER
and ONMOUSEOUT to set the window.status attribute. However, many users
dislike this. So use this with care.

HTH,

Laurent
 
R

Robin Goodall

Hi,





No.

As stated in
<URL:http://www.jibbering.com/faq/#FAQ4_24>

you should use:
<a href="something.html" onclick="somefunction();return false">

This has the advantage, if JavaScript is disabled, that the user's web
browser will do something. It can, for example, lead him to a page where
the user can find some content, but less functionality. It can also lead
the user to a page where you explain why he should switch JavaScript on.

The browser's status bar will (in most browsers) display the location of
the HREF attribute. If this is really a problem, you can use ONMOUSEOVER
and ONMOUSEOUT to set the window.status attribute. However, many users
dislike this. So use this with care.

HTH,

Laurent

I stand corrected (I should have checked myself first!).

I always kick non Javascript users out to somewhere else before they get
to the page does the work, so I just use "#" as a kind of null URL to
ensure that the browser treats the link properly.

Robin
 
M

Michael Winter

Andy Fish wrote on 18 Dec 2003 at Thu, 18 Dec 2003 09:44:08 GMT:

many of the recommended solutions go something like this:

<a href="javascript:void(0);" onclick="foo()" />

Using that href causes just as many problems as the original one you
posted. The use of JavaScript in anything other than intrinsic
events and SCRIPT elements is thoroughly discouraged.

The general reason for avoiding JavaScript URIs is that a user with
a JavaScript-disabled browser will get jibbish when that URI is
interpreted by the browser. Others in this group have indicated that
there are other pitfalls, but as I don't use JavaScript URIs, I've
never encountered them.
this generates an <a> that looks like a hyperlink (good) and it
invokes foo() as well (also good). the problem is that if in
function foo, I put

window.location.href = "some new url";

it just seems to get ignored. If I miss out the href altogether,
the link works but it's not formatted as a hyperlink.

<snip>

This is to be expected. When the user clicks on the link, the
onclick event will be executed then, by default, the browser will
navigate to the href URI. If you return false inside the event, this
default behaviour is cancelled:

<A ... onclick="foo(); return false">...</A>

or

<A ... onclick="return foo()">...</A>

function foo() {
...
return false;
}

Using return true will allow the normal behaviour.

As already mentioned by Mr Bugnion, it is not generally a good idea
to use a 'null' href attribute (usually, href="#"). The use of
JavaScript should always involve fallbacks so that the user can
continue to use a page, even if the code fails (either through
error, or by disabling JavaScript).

In this particular instance, as you are generating a URI, perhaps
you should provide a page that lists the various destinations that
you generate. Only if there is no logical destination should a href
be null.

One final point: if you use intrinsic events, you *must* specify the
default language for the page. This is done quite simply by
including the following META element in the document's HEAD block:

<META http-equiv="Content-Script-Type" content="text/javascript">

Mike
 
R

Richard Cornford

... . Others in this group have indicated that
there are other pitfalls, but as I don't use
JavaScript URIs, I've never encountered them.
<snip>

The javascript: pseudo-protocol[1] appears to be totally
un-standardised. I have certainly not been able to find any official
guidelines as to how it should be implemented, and that leaves
implementers reproducing what they recognise in other peoples
implementations with greater or lesser success. That was always going to
be a recipe for inconsistent behaviour across browsers.

However, some clues as to implementation mechanisms have come to light.
For example IE 4 & 5 (but not 5.5+) allow this page:-

<html>
<head><title></title>
</head><body>
<a href="javascript:'cc';" target="_blank">
JavaScript Pseudo-protocol test</a>
</body>
</html>

-which targets a _blank window with the results (the letters - cc - on a
white background), to expose part of the mechanism by viewing the source
of the resulting page:-

JavaScript pseudo-protocol page source from the new window (IE 4 & 5,
Win 98 and NT 4):-
<HTML>
<SCRIPT LANGUAGE=javascript>
var __w='cc';
if(__w!=null)document.write(__w);
</SCRIPT>
</HTML>

The - 'cc'; - that followed the javascript: prefix has been inserted
into the expression - var __w='cc'; - and because the resulting value
of - __w - is not equal to null that value is document.write-ed into the
new page.

Immediately this shows up a shortcoming in the common javascript URL
formulation - javascript:; - (the pseudo-protocol followed by an empty
statement (semicolon)) as the resulting expression would be - var
__w=; -, an assignment with no right hand side, and indeed when targeted
at a new window that javascript URL produces a syntax error on IE 4 & 5.
It is also clear why the use of a return statement within a javascript
URL produces the error - return statement outside of function -, an
error that IE produces even when the URL is targeted at the current
window.

The fact that IE produces the - return statement outside of function -
even when a javascript URL is targeted at the current window
demonstrates that the mechanism used when navigating the current window
is at least similar to the one used when targeting a new window.
However, when targeting the current window - javascript:; - does not
result in a - syntax error - report. It seems that syntax error reports
are internally suppressed while runtime errors are not. On the other
hand, the fact that - javascript:; - is known to be producing a syntax
error on IE 4 & 5, internally suppressed or not, should suggest that it
is a dangerous javascript URL formulation to use as any generated error
is likely to have a knock-on effect somewhere.

It seems that the javascript: pseudo-protocol was originally intended to
allow a JavaScript string to represent the source code for a replacement
HTML page. And that is clearly the primary intention of the IE 4 & 5
implementation code. So - javascript:someFunction(); - becomes - var
__w=someFunction(); - and if the function call returns a string that
string will become the new document source. In allowing the execution of
a function to return the replacement source string this mechanism
facilitates the execution of the function to produce "side effects" and
by ensuring that the function returns a value that equates to null
(usually undefined) the actual replacement of the current document can
be avoided. Ancient browsers did not provide an onclick alternative so
the execution of functions for the "side effect" was the only method of
getting a link element to execute JavaScript when clicked. And that has
become the main use that the javascript: pseudo-protocol is put to.
Though these days you would be hard pressed to find a browser still in
serious use that did not support onclick attributes on link elements.

The javascript: pseudo-protocol implementation on IceBrowser seems to
have been designed around this shift of emphasis to the execution
functions for the "side effects" and while it does execute the function
it does not ever use any returned string as new document source. Exactly
how many other browsers may have implemented the javascript:
pseudo-protocol in a way that only works for "side effects" but cannot
provide new source for the document is impossible to say, but it is not
surprising that this has happened given no clear documentation on what -
href="javascript:someFunction();" - is supposed to do.

But even with inconsistent, undocumented and ill-defined implementations
the biggest problem with the javascript: pseudo-protocol is that
clicking on <a href="javascript:someFunction();">...</a> may represent
navigation to the browser, even when the current page will never be
replaced by the "side effect" code. The most widely complained of
consequence of this type of "navigation" is that some browsers
(including some version of Windows IE) will immediately stop playing GIF
animations (though many others have come up in c.l.j questions from time
to time [2]). What seems to happen is that once the HREF has been
activated the browser, thinking that it is navigating, puts the current
page into a new state, pending replacement, in which it stops to do
seemingly redundant resource hungry activity.

As a result some features may become unavailable to JavaScript or just
cease to work. Exactly which, if any, features stop working when a
JavaScript URL is clicked on seems to depend entirely on the version of
the browser in use, with browsers for Linux and Mac seeming to manifest
more problems in this area than browsers for Window. That is a bit of a
problem in itself as many do not do much testing on non-windows systems
and may write a lot of code before encountering any manifestation of a
problem resulting from the use of the javascript pseudo-protocol, and
even when encountered may not be able to associate the cause with the
effect (or be willing to recognise the relationship given years of
apparently successful use of javascript URLs).

Unfortunately this leaves only two options if the goal is to write
reliable cross-browser/platform JavaScript, 1. using javascript URLs and
then testing on every version of ever browsers on every platform to
ensure that the consequences of any implied navigation do not manifest
themselves in a way that effects the script (not really a practical
option), or 2. follow the general advice and just *never* use a
javascript URL in an HREF.

Richard.

[1] It has been suggested that "javascript: pseudo-protocol" might not
be the most accurate term to be using. I quite like it, it does not seem
to result in any misidentification of its subject and the "pseudo"
prefix is appropriately deprecating.

[2] I did consider going through the google archives and trying to turn
up some other concrete examples of the results of the "navigation"
aspects of the use of the javascript: pseudo-protocol but I could not
think of a search that would find those and not be swamped with
thousands of posts that just recommend that it is not used.
 
A

Andy Fish

Thanks folks for all the answers

What I was missing was the 'return false' at the end of the onclick event.
when I put this in it all starts working whether the href itself is '#' or
'javascript:void(0)'

at least now I understand how it's interpreting the javascript, and how the
onClick and href attributes interact. Like Richard mentioned in his post, I
have also been frustrated by the lack of any standards in this area. It
seems that whilst ECMAScript and HTML DOM are well documented (even though
there may be differences in implementation), there are quite a few areas in
terms of javascript integration with the browser that nobody has even tried
to make a standard for

Andy
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top