Related
Is it possible to use Javascript inside CSS?
If it is, can you give a simple example?
IE and Firefox both contain ways to execute JavaScript from CSS. As Paolo mentions, one way in IE is the expression technique, but there's also the more obscure HTC behavior, in which a seperate XML that contains your script is loaded via CSS. A similar technique for Firefox exists, using XBL. These techniques don't exectue JavaScript from CSS directly, but the effect is the same.
HTC with IE
Use a CSS rule like so:
body {
behavior:url(script.htc);
}
and within that script.htc file have something like:
<PUBLIC:COMPONENT TAGNAME="xss">
<PUBLIC:ATTACH EVENT="ondocumentready" ONEVENT="main()" LITERALCONTENT="false"/>
</PUBLIC:COMPONENT>
<SCRIPT>
function main()
{
alert("HTC script executed.");
}
</SCRIPT>
The HTC file executes the main() function on the event ondocumentready (referring to the HTC document's readiness.)
XBL with Firefox
Firefox supports a similar XML-script-executing hack, using XBL.
Use a CSS rule like so:
body {
-moz-binding: url(script.xml#mycode);
}
and within your script.xml:
<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl" xmlns:html="http://www.w3.org/1999/xhtml">
<binding id="mycode">
<implementation>
<constructor>
alert("XBL script executed.");
</constructor>
</implementation>
</binding>
</bindings>
All of the code within the constructor tag will be executed (a good idea to wrap code in a CDATA section.)
In both techniques, the code doesn't execute unless the CSS selector matches an element within the document. By using something like body, it will execute immediately on page load.
I think what you may be thinking of is expressions or "dynamic properties", which are only supported by IE and let you set a property to the result of a javascript expression. Example:
width:expression(document.body.clientWidth > 800? "800px": "auto" );
This code makes IE emulate the max-width property it doesn't support.
All things considered, however, avoid using these. They are a bad, bad thing.
To facilitate potentially solving your problem given the information you've provided, I'm going to assume you're seeking dynamic CSS. If this is the case, you can use a server-side scripting language to do so. For example (and I absolutely love doing things like this):
styles.css.php:
body
{
margin: 0px;
font-family: Verdana;
background-color: #cccccc;
background-image: url('<?php
echo 'images/flag_bg/' . $user_country . '.png';
?>');
}
This would set the background image to whatever was stored in the $user_country variable. This is only one example of dynamic CSS; there are virtually limitless possibilities when combining CSS and server-side code. Another case would be doing something like allowing the user to create a custom theme, storing it in a database, and then using PHP to set various properties, like so:
user_theme.css.php:
body
{
background-color: <?php echo $user_theme['BG_COLOR']; ?>;
color: <?php echo $user_theme['COLOR']; ?>;
font-family: <?php echo $user_theme['FONT']; ?>;
}
#panel
{
font-size: <?php echo $user_theme['FONT_SIZE']; ?>;
background-image: <?php echo $user_theme['PANEL_BG']; ?>;
}
Once again, though, this is merely an off-the-top-of-the-head example; harnessing the power of dynamic CSS via server-side scripting can lead to some pretty incredible stuff.
Not in any conventional sense of the phrase "inside CSS."
IE supports CSS expressions:
width:expression(document.body.clientWidth > 955 ? "955px": "100%" );
but they are not standard and are not portable across browsers. Avoid them if possible. They are deprecated since IE8.
I ran into a similar problem and have developed two standalone tools to accomplish this:
CjsSS.js is a Vanilla Javascript tool (so no external dependencies) that supports back to IE6.
ngCss is an Angular Module+Filter+Factory (aka: plugin) that supports Angular 1.2+ (so back to IE8)
Both of these tool sets allow you to do this in a STYLE tag or within an external *.css file:
/*<script src='some.js'></script>
<script>
var mainColor = "#cccccc";
</script>*/
BODY {
color: /*{{mainColor}}*/;
}
And this in your on-page style attributes:
<div style="color: {{mainColor}}" cjsss="#sourceCSS">blah</div>
or
<div style="color: {{mainColor}}" ng-css="sourceCSS">blah</div>
NOTE: In ngCss, you could also do $scope.mainColor in place of var mainColor
By default, the Javascript is executed in a sandboxed IFRAME, but since you author your own CSS and host it on your own server (just like your *.js files) then XSS isn't an issue. But the sandbox provides that much more security and peace of mind.
CjsSS.js and ngCss fall somewhere in-between the other tools around to accomplish similar tasks:
LESS, SASS and Stylus are all Preprocessors only and require you to learn a new language and mangle your CSS. Basically they extended CSS with new language features. All are also limited to plugins developed for each platform while CjsSS.js and ngCss both allow you to include any Javascript library via <script src='blah.js'></script> straight in your CSS!
AbsurdJS saw the same problems and went the exact opposite direction of the Preprocessors above; rather than extending CSS, AbsurdJS created a Javascript library to generate CSS.
CjsSS.js and ngCss took the middle ground; you already know CSS, you already know Javascript, so just let them work together in a simple, intuitive way.
This turns out to be a very interesting question. With over a hundred properties being set, you'd think that you'd be allowed to type
.clickable { onclick : "alert('hi!');" ; }
in your CSS, and it'd work. It's intuitive, it makes so much sense. This would be amazingly useful in monkey-patching dynamically-generated massive UIs.
The problem:
The CSS police, in their infinite wisdom, have drawn a Chinese wall between presentation and behavior. Any HTML properly labeled on-whatever is intentionally not supported by CSS. (Full Properties Table)
The best way around this is to use jQuery, which sets up an interpreted engine in the background to execute what you were trying to do with the CSS anyway. See this page:
Add Javascript Onclick To .css File.
Good luck.
The following are two methods of building a link that has the sole purpose of running JavaScript code. Which is better, in terms of functionality, page load speed, validation purposes, etc.?
function myJsFunc() {
alert("myJsFunc");
}
Run JavaScript Code
or
function myJsFunc() {
alert("myJsFunc");
}
Run JavaScript Code
I use javascript:void(0).
Three reasons. Encouraging the use of # amongst a team of developers inevitably leads to some using the return value of the function called like this:
function doSomething() {
//Some code
return false;
}
But then they forget to use return doSomething() in the onclick and just use doSomething().
A second reason for avoiding # is that the final return false; will not execute if the called function throws an error. Hence the developers have to also remember to handle any error appropriately in the called function.
A third reason is that there are cases where the onclick event property is assigned dynamically. I prefer to be able to call a function or assign it dynamically without having to code the function specifically for one method of attachment or another. Hence my onclick (or on anything) in HTML markup look like this:
onclick="someFunc.call(this)"
OR
onclick="someFunc.apply(this, arguments)"
Using javascript:void(0) avoids all of the above headaches, and I haven't found any examples of a downside.
So if you're a lone developer then you can clearly make your own choice, but if you work as a team you have to either state:
Use href="#", make sure onclick always contains return false; at the end, that any called function does not throw an error and if you attach a function dynamically to the onclick property make sure that as well as not throwing an error it returns false.
OR
Use href="javascript:void(0)"
The second is clearly much easier to communicate.
Neither.
If you can have an actual URL that makes sense use that as the HREF. The onclick won't fire if someone middle-clicks on your link to open a new tab or if they have JavaScript disabled.
If that is not possible, then you should at least inject the anchor tag into the document with JavaScript and the appropriate click event handlers.
I realize this isn't always possible, but in my opinion it should be striven for in developing any public website.
Check out Unobtrusive JavaScript and Progressive enhancement (both Wikipedia).
Doing Link or Link or whatever else that contains an onclick attribute - was okay back five years ago, though now it can be a bad practice. Here's why:
It promotes the practice of obtrusive JavaScript - which has turned out to be difficult to maintain and difficult to scale. More on this in Unobtrusive JavaScript.
You're spending your time writing incredibly overly verbose code - which has very little (if any) benefit to your codebase.
There are now better, easier, and more maintainable and scalable ways of accomplishing the desired result.
The unobtrusive JavaScript way
Just don't have a href attribute at all! Any good CSS reset would take care of the missing default cursor style, so that is a non-issue. Then attach your JavaScript functionality using graceful and unobtrusive best practices - which are more maintainable as your JavaScript logic stays in JavaScript, instead of in your markup - which is essential when you start developing large scale JavaScript applications which require your logic to be split up into blackboxed components and templates. More on this in Large-scale JavaScript Application Architecture
Simple code example
// Cancel click event
$('.cancel-action').click(function(){
alert('Cancel action occurs!');
});
// Hover shim for Internet Explorer 6 and Internet Explorer 7.
$(document.body).on('hover','a',function(){
$(this).toggleClass('hover');
});
a { cursor: pointer; color: blue; }
a:hover,a.hover { text-decoration: underline; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="cancel-action">Cancel this action</a>
A blackboxed Backbone.js example
For a scalable, blackboxed, Backbone.js component example - see this working jsfiddle example here. Notice how we utilize unobtrusive JavaScript practices, and in a tiny amount of code have a component that can be repeated across the page multiple times without side-effects or conflicts between the different component instances. Amazing!
Notes
Omitting the href attribute on the a element will cause the element to not be accessible using tab key navigation. If you wish for those elements to be accessible via the tab key, you can set the tabindex attribute, or use button elements instead. You can easily style button elements to look like normal links as mentioned in Tracker1's answer.
Omitting the href attribute on the a element will cause Internet Explorer 6 and Internet Explorer 7 to not take on the a:hover styling, which is why we have added a simple JavaScript shim to accomplish this via a.hover instead. Which is perfectly okay, as if you don't have a href attribute and no graceful degradation then your link won't work anyway - and you'll have bigger issues to worry about.
If you want your action to still work with JavaScript disabled, then using an a element with a href attribute that goes to some URL that will perform the action manually instead of via an Ajax request or whatever should be the way to go. If you are doing this, then you want to ensure you do an event.preventDefault() on your click call to make sure when the button is clicked it does not follow the link. This option is called graceful degradation.
'#' will take the user back to the top of the page, so I usually go with void(0).
javascript:; also behaves like javascript:void(0);
I would honestly suggest neither. I would use a stylized <button></button> for that behavior.
button.link {
display: inline-block;
position: relative;
background-color: transparent;
cursor: pointer;
border: 0;
padding: 0;
color: #00f;
text-decoration: underline;
font: inherit;
}
<p>A button that looks like a <button type="button" class="link">link</button>.</p>
This way you can assign your onclick. I also suggest binding via script, not using the onclick attribute on the element tag. The only gotcha is the psuedo 3d text effect in older IEs that cannot be disabled.
If you MUST use an A element, use javascript:void(0); for reasons already mentioned.
Will always intercept in case your onclick event fails.
Will not have errant load calls happen, or trigger other events based on a hash change
The hash tag can cause unexpected behavior if the click falls through (onclick throws), avoid it unless it's an appropriate fall-through behavior, and you want to change the navigation history.
NOTE: You can replace the 0 with a string such as javascript:void('Delete record 123') which can serve as an extra indicator that will show what the click will actually do.
The first one, ideally with a real link to follow in case the user has JavaScript disabled. Just make sure to return false to prevent the click event from firing if the JavaScript executes.
Link
If you use Angular2, this way works:
<a [routerLink]="" (click)="passTheSalt()">Click me</a>.
See here https://stackoverflow.com/a/45465728/2803344
Neither if you ask me;
If your "link" has the sole purpose of running some JavaScript code it doesn't qualify as a link; rather a piece of text with a JavaScript function coupled to it. I would recommend to use a <span> tag with an onclick handler attached to it and some basic CSS to immitate a link. Links are made for navigation, and if your JavaScript code isn't for navigation it should not be an <a> tag.
Example:
function callFunction() { console.log("function called"); }
.jsAction {
cursor: pointer;
color: #00f;
text-decoration: underline;
}
<p>I want to call a JavaScript function <span class="jsAction" onclick="callFunction();">here</span>.</p>
Ideally you'd do this:
Link text
Or, even better, you'd have the default action link in the HTML, and you'd add the onclick event to the element unobtrusively via JavaScript after the DOM renders, thus ensuring that if JavaScript is not present/utilized you don't have useless event handlers riddling your code and potentially obfuscating (or at least distracting from) your actual content.
Using just # makes some funny movements, so I would recommend to use #self if you would like to save on typing efforts of JavaScript bla, bla,.
I use the following
Link
instead
Link
I recommend using a <button> element instead, especially if the control is supposed to produce a change in the data. (Something like a POST.)
It's even better if you inject the elements unobtrusively, a type of progressive enhancement. (See this comment.)
I agree with suggestions elsewhere stating that you should use regular URL in href attribute, then call some JavaScript function in onclick. The flaw is, that they automaticaly add return false after the call.
The problem with this approach is, that if the function will not work or if there will be any problem, the link will become unclickable. Onclick event will always return false, so the normal URL will not be called.
There's very simple solution. Let function return true if it works correctly. Then use the returned value to determine if the click should be cancelled or not:
JavaScript
function doSomething() {
alert( 'you clicked on the link' );
return true;
}
HTML
link text
Note, that I negate the result of the doSomething() function. If it works, it will return true, so it will be negated (false) and the path/to/some/URL will not be called. If the function will return false (for example, the browser doesn't support something used within the function or anything else goes wrong), it is negated to true and the path/to/some/URL is called.
# is better than javascript:anything, but the following is even better:
HTML:
For great justice
JavaScript:
$(function() {
$(".some-selector").click(myJsFunc);
});
You should always strive for graceful degradation (in the event that the user doesn't have JavaScript enabled...and when it is with specs. and budget). Also, it is considered bad form to use JavaScript attributes and protocol directly in HTML.
Unless you're writing out the link using JavaScript (so that you know it's enabled in the browser), you should ideally be providing a proper link for people who are browsing with JavaScript disabled and then prevent the default action of the link in your onclick event handler. This way those with JavaScript enabled will run the function and those with JavaScript disabled will jump to an appropriate page (or location within the same page) rather than just clicking on the link and having nothing happen.
Definitely hash (#) is better because in JavaScript it is a pseudoscheme:
pollutes history
instantiates new copy of engine
runs in global scope and doesn't respect event system.
Of course "#" with an onclick handler which prevents default action is [much] better. Moreover, a link that has the sole purpose to run JavaScript is not really "a link" unless you are sending user to some sensible anchor on the page (just # will send to top) when something goes wrong. You can simply simulate look and feel of link with stylesheet and forget about href at all.
In addition, regarding cowgod's suggestion, particularly this: ...href="javascript_required.html" onclick="... This is good approach, but it doesn't distinguish between "JavaScript disabled" and "onclick fails" scenarios.
I usually go for
Link description
It's shorter than javascript:void(0) and does the same.
I choose use javascript:void(0), because use this could prevent right click to open the content menu. But javascript:; is shorter and does the same thing.
I would use:
Link
Reasons:
This makes the href simple, search engines need it. If you use anything else ( such as a string), it may cause a 404 not found error.
When mouse hovers over the link, it doesn't show that it is a script.
By using return false;, the page doesn't jump to the top or break the back button.
Don't use links for the sole purpose of running JavaScript.
The use of href="#" scrolls the page to the top; the use of void(0) creates navigational problems within the browser.
Instead, use an element other than a link:
<span onclick="myJsFunc()" class="funcActuator">myJsFunc</span>
And style it with CSS:
.funcActuator {
cursor: default;
}
.funcActuator:hover {
color: #900;
}
So, when you are doing some JavaScript things with an <a /> tag and if you put href="#" as well, you can add return false at the end of the event (in case of inline event binding) like:
Run JavaScript Code
Or you can change the href attribute with JavaScript like:
Run JavaScript Code
or
Run JavaScript Code
But semantically, all the above ways to achieve this are wrong (it works fine though). If any element is not created to navigate the page and that have some JavaScript things associated with it, then it should not be a <a> tag.
You can simply use a <button /> instead to do things or any other element like b, span or whatever fits there as per your need, because you are allowed to add events on all the elements.
So, there is one benefit to use <a href="#">. You get the cursor pointer by default on that element when you do a href="#". For that, I think you can use CSS for this like cursor:pointer; which solves this problem also.
And at the end, if you are binding the event from the JavaScript code itself, there you can do event.preventDefault() to achieve this if you are using <a> tag, but if you are not using a <a> tag for this, there you get an advantage, you don't need to do this.
So, if you see, it's better not to use a tag for this kind of stuff.
It would be better to use jQuery,
$(document).ready(function() {
$("a").css("cursor", "pointer");
});
and omit both href="#" and href="javascript:void(0)".
The anchor tag markup will be like
<a onclick="hello()">Hello</a>
Simple enough!
Usually, you should always have a fall back link to make sure that clients with JavaScript disabled still has some functionality. This concept is called unobtrusive JavaScript.
Example... Let's say you have the following search link:
Search
You can always do the following:
var link = document.getElementById('searchLink');
link.onclick = function() {
try {
// Do Stuff Here
} finally {
return false;
}
};
That way, people with JavaScript disabled are directed to search.php while your viewers with JavaScript view your enhanced functionality.
If you happen to be using AngularJS, you can use the following:
Do some fancy JavaScript
Which will not do anything.
In addition
It will not take you to the top of the page, as with (#)
Therefore, you don't need to explicitly return false with JavaScript
It is short an concise
Depending on what you want to accomplish, you could forget the onclick and just use the href:
Link Text
It gets around the need to return false. I don't like the # option because, as mentioned, it will take the user to the top of the page. If you have somewhere else to send the user if they don't have JavaScript enabled (which is rare where I work, but a very good idea), then Steve's proposed method works great.
Link text
Lastly, you can use javascript:void(0) if you do not want anyone to go anywhere and if you don't want to call a JavaScript function. It works great if you have an image you want a mouseover event to happen with, but there's not anything for the user to click on.
I believe you are presenting a false dichotomy. These are not the only two options.
I agree with Mr. D4V360 who suggested that, even though you are using the anchor tag, you do not truly have an anchor here. All you have is a special section of a document that should behave slightly different. A <span> tag is far more appropriate.
I tried both in google chrome with the developer tools, and the id="#" took 0.32 seconds. While the javascript:void(0) method took only 0.18 seconds. So in google chrome, javascript:void(0) works better and faster.
I personally use them in combination. For example:
HTML
Link
with little bit of jQuery
$('a[href="#"]').attr('href','javascript:void(0);');
or
$('a[href="#"]').click(function(e) {
e.preventDefault();
});
But I'm using that just for preventing the page jumping to the top when the user clicks on an empty anchor. I'm rarely using onClick and other on events directly in HTML.
My suggestion would be to use <span> element with the class attribute instead of
an anchor. For example:
<span class="link">Link</span>
Then assign the function to .link with a script wrapped in the body and just before the </body> tag or in an external JavaScript document.
<script>
(function($) {
$('.link').click(function() {
// do something
});
})(jQuery);
</script>
*Note: For dynamically created elements, use:
$('.link').on('click', function() {
// do something
});
And for dynamically created elements which are created with dynamically created elements, use:
$(document).on('click','.link', function() {
// do something
});
Then you can style the span element to look like an anchor with a little CSS:
.link {
color: #0000ee;
text-decoration: underline;
cursor: pointer;
}
.link:active {
color: red;
}
Here's a jsFiddle example of above aforementioned.
On a modern website the use of href should be avoided if the element is only doing JavaScript functionality (not a real link).
Why?
The presence of this element tells the browser that this is a link with a destination.
With that, the browser will show the Open In New Tab / Window function (also triggered when you use shift+click).
Doing so will result in opening the same page without the desired function triggered (resulting in user frustration).
In regards to IE:
As of IE8, element styling (including hover) works if the doctype is set. Other versions of IE are not really to worry about anymore.
Only Drawback:
Removing HREF removes the tabindex.
To overcome this, you can use a button that's styled as a link or add a tabindex attribute using JS.
When I've got several faux-links, I prefer to give them a class of 'no-link'.
Then in jQuery, I add the following code:
$(function(){
$('.no-link').click(function(e){
e.preventDefault();
});
});
And for the HTML, the link is simply
Faux-Link
I don't like using Hash-Tags unless they're used for anchors, and I only do the above when I've got more than two faux-links, otherwise I go with javascript:void(0).
Faux-Link
Typically, I like to just avoid using a link at all and just wrap something around in a span and use that as a way to active some JavaScript code, like a pop-up or a content-reveal.
It's nice to have your site be accessible by users with JavaScript disabled, in which case the href points to a page that performs the same action as the JavaScript being executed. Otherwise I use "#" with a "return false;" to prevent the default action (scroll to top of the page) as others have mentioned.
Googling for "javascript:void(0)" provides a lot of information on this topic. Some of them, like this one mention reasons to NOT use void(0).
I am working on a web site project which requires that the web page display tooltips on hover. For reasons I won't go into here, I decided to use a library from a site called dyn-web.com. The library works great but I need to make one small change to the way it works, which will make it a perfect fit for my application. Trouble is, I can't figure out how it works!
Everything I've read says that you can't execute javascript code from within CSS. But that seems to be exactly what this library does. To create a tooltip for any element (anchor, div, span, etc), all this library requires you to do is:
Include a <script src= > tag to the library file
Add two class names to the HTML element that will host the tooltip, one called "showTip" and the other is a key into a JSON object containing the tooltip text
Add the tooltip text to the JSON object mentioned above
Create a style to format the tooltip how you want it to look
If you'll notice, nowhere in these steps is mention of any event handlers. Moreover, there's no class (that I can find) called showTip. There's no JQuery or other dependencies. So how does the javascript get executed?
I don't want to jump in and start changing the library willy-nilly without knowing how it works, and I've been pulling out my hair trying to figure it out. Can one of you smarter-than-me folks explain it?
You can't run JavaScript from a "CSS Class".
The example you give runs JavaScript by including a <script> element.
I'm not going to reverse engineer it because it is not formatted in a way that is particularly human readable. That said, searching the file finds showTip so it presumably searches the DOM for that HTML class (maybe with querySelectorAll since it certainly uses that method for something) and binds event handlers with JavaScript (probably with addEventLister since it contains a call to that method).
If you'll notice, nowhere in these steps is mention of any event handlers.
The JS file uses addEventListener
Moreover, there's no class (that I can find) called showTip.
You said you added it to an HTML element in a previous step. As mentioned above, the string appears in the JavaScript file.
From the steps you listed, it seems as if Dynamic Web Coding library uses the JavaScript to apply CSS attributes into elements. You can not run JavaScript inside CSS, but you can certainly apply CSS using JavaScript!
What the library probably does is look at all of the elements with class showTip with JavaScript using document.getElementsByClassName("showTip"). Then, it looks at the other class on that element and assumes that as the key to the tooltip with the tooltip text.
Then, it probably creates an element for the tooltip using document.createElement() and then injects that into the document using document.appendChild() or document.insertBefore(). They can probably add some class to the tooltip so your CSS rules are applied using the .className property.
It also likely used document.addEventListener() to listen for when the user hovers over and leaves the element. You don't need to add this code because the <script> tag you added has called document.addEventListener() for you.
All of these things require something known as the DOM which is something JavaScript coders use to manipulate the HTML document. This is actually really powerful and cool, so you can check out a good tutorial on it at TutorialsPoint.
It works with event delegation, it listens to events on the entire body and ignores events on elements without the magic class names (showTip).
Excerpt from http://www.dyn-web.com/code/tooltips/js/dw_tooltip_c.js:
initHandlers: function() {
var _this = dw_Tooltip;
if (_this.ready) {
return;
}
if (!_this.forTouch) {
if (_this.activateOnClick) {
dw_Event.add(document, 'click', _this.checkForActuator, true);
dw_Event.add(document, "mouseup", _this.checkDocClick, true);
} else {
dw_Event.add(document, 'mouseover', _this.checkForActuator, true);
}
dw_Event.add(document, "keydown", _this.checkEscKey, true);
if (!_this.activateOnClick && _this.activateOnFocus) {
if (window.addEventListener) {
dw_Event.add(document, 'focus', _this.checkForActuator, true);
} else if (window.attachEvent) {
dw_Event.add(document, 'focusin', _this.checkForActuator);
}
}
} else {
dw_Event.add(document, 'mouseover', _this.checkForActuator, true);
}
_this.ready = true;
}
}
There is one way by which you can make custom tool-tip(s). This is little out of box & requires only HTML and CSS to perform the magic.
"Use JS to add more interactivity".
<html>
<style>
h1 { position: relative; }
h1:hover:after {
content: attr(data‐hover‐response);
color: black;
position: absolute;
left: 250px;
top: -40px;
border: solid 2px gray;
background-color: red;
}
</style>
<body>
<br><br>
<h1 data‐hover‐response="I am tooltip !"> I will show tooltip on Hover! </h1>
<body>
</html>
CodePen : http://codepen.io/anon/pen/bdPQxP
In trying to understand javascript best practices, I'm attempting to recreate a piece of inline javascript by adding an event listener from an external javascript file.
The inline code works fine and looks like this:
<p id="inline" align="left">
This is a body paragraph which changes alignment
when a user clicks on a link below
</p>
<p>
Align Right
</p>
Concerning my problem, the important thing to note here is that return false; prevents the page from reloading (I'm not actually sure why, and wouldn't mind finding out, especially if it relates to the solution to my problem...). This is what I want. I don't need the page to reload to move the text to the right.
However, I have no idea what the best way to keep the page from reloading is when my javascript is in an external file. Here's what my first attempt looks like. I started with html that looks like this:
<p id="external" align="left">
This is a body paragraph which changes alignment
when a user clicks on a link below. It uses an
external .js file.
</p>
<p>
Align Right
</p>
And javascript that looks like this:
function alignListener () {
document.getElementById('external').setAttribute('align', 'right');
}
function installListeners () {
var aRight = document.getElementById('aRight');
aright.addEventListener('click', alignListener, false);
}
This almost works, but not at all how I would expect. When I click on the 'Align Right' link, the text briefly aligns right, but then, I follow the link to the current page, which resets the alignment back to the left.
I found a way to sort of fix that problem, by using <a href="#" ... instead of <a href="" .... While this doesn't reload the page (so the text stays aligned), it does take me to the top, which isn't really what I want. I'd like a solution similar to the return false; that works with the inline javascript. Is there a simple way to do this? Or am I doing it wrong completely?
I highly recommend the mozilla developer network for most of these types of answers. It's easy to read and will help you understand JavaScript and the DOM. (JavaScript is good!, DOM is awkward...)
Specifically, for events: https://developer.mozilla.org/en/DOM/event
In general, https://developer.mozilla.org/
There are a few ways to stop events, preventDefault(), stopPropagation(), return false;, or use a JavaScript framework as suggested above. jQuery is good, there are many many others out there (YUI, Dojo, MooTools, etc.), and they all endeavor to make your JavaScript more compatible with different browsers.
Use <button> instead of <a> tag.
That helped me.
You can use:
function event(e){
var e=window.event||e;
//do stuff
if(e.preventDefault){e.preventDefault()}else{e.returnValue=false}
}
Note that this doesn't need to go on a new function: .addEventListener("click",function(e){/*the above function*/})
Cross-compatible event listener:
if(element.addEventListener){
element.addEventListener(eventName, function, false);
}else{
element.attachEvent("on"+eventName, function);
}
The following are two methods of building a link that has the sole purpose of running JavaScript code. Which is better, in terms of functionality, page load speed, validation purposes, etc.?
function myJsFunc() {
alert("myJsFunc");
}
Run JavaScript Code
or
function myJsFunc() {
alert("myJsFunc");
}
Run JavaScript Code
I use javascript:void(0).
Three reasons. Encouraging the use of # amongst a team of developers inevitably leads to some using the return value of the function called like this:
function doSomething() {
//Some code
return false;
}
But then they forget to use return doSomething() in the onclick and just use doSomething().
A second reason for avoiding # is that the final return false; will not execute if the called function throws an error. Hence the developers have to also remember to handle any error appropriately in the called function.
A third reason is that there are cases where the onclick event property is assigned dynamically. I prefer to be able to call a function or assign it dynamically without having to code the function specifically for one method of attachment or another. Hence my onclick (or on anything) in HTML markup look like this:
onclick="someFunc.call(this)"
OR
onclick="someFunc.apply(this, arguments)"
Using javascript:void(0) avoids all of the above headaches, and I haven't found any examples of a downside.
So if you're a lone developer then you can clearly make your own choice, but if you work as a team you have to either state:
Use href="#", make sure onclick always contains return false; at the end, that any called function does not throw an error and if you attach a function dynamically to the onclick property make sure that as well as not throwing an error it returns false.
OR
Use href="javascript:void(0)"
The second is clearly much easier to communicate.
Neither.
If you can have an actual URL that makes sense use that as the HREF. The onclick won't fire if someone middle-clicks on your link to open a new tab or if they have JavaScript disabled.
If that is not possible, then you should at least inject the anchor tag into the document with JavaScript and the appropriate click event handlers.
I realize this isn't always possible, but in my opinion it should be striven for in developing any public website.
Check out Unobtrusive JavaScript and Progressive enhancement (both Wikipedia).
Doing Link or Link or whatever else that contains an onclick attribute - was okay back five years ago, though now it can be a bad practice. Here's why:
It promotes the practice of obtrusive JavaScript - which has turned out to be difficult to maintain and difficult to scale. More on this in Unobtrusive JavaScript.
You're spending your time writing incredibly overly verbose code - which has very little (if any) benefit to your codebase.
There are now better, easier, and more maintainable and scalable ways of accomplishing the desired result.
The unobtrusive JavaScript way
Just don't have a href attribute at all! Any good CSS reset would take care of the missing default cursor style, so that is a non-issue. Then attach your JavaScript functionality using graceful and unobtrusive best practices - which are more maintainable as your JavaScript logic stays in JavaScript, instead of in your markup - which is essential when you start developing large scale JavaScript applications which require your logic to be split up into blackboxed components and templates. More on this in Large-scale JavaScript Application Architecture
Simple code example
// Cancel click event
$('.cancel-action').click(function(){
alert('Cancel action occurs!');
});
// Hover shim for Internet Explorer 6 and Internet Explorer 7.
$(document.body).on('hover','a',function(){
$(this).toggleClass('hover');
});
a { cursor: pointer; color: blue; }
a:hover,a.hover { text-decoration: underline; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a class="cancel-action">Cancel this action</a>
A blackboxed Backbone.js example
For a scalable, blackboxed, Backbone.js component example - see this working jsfiddle example here. Notice how we utilize unobtrusive JavaScript practices, and in a tiny amount of code have a component that can be repeated across the page multiple times without side-effects or conflicts between the different component instances. Amazing!
Notes
Omitting the href attribute on the a element will cause the element to not be accessible using tab key navigation. If you wish for those elements to be accessible via the tab key, you can set the tabindex attribute, or use button elements instead. You can easily style button elements to look like normal links as mentioned in Tracker1's answer.
Omitting the href attribute on the a element will cause Internet Explorer 6 and Internet Explorer 7 to not take on the a:hover styling, which is why we have added a simple JavaScript shim to accomplish this via a.hover instead. Which is perfectly okay, as if you don't have a href attribute and no graceful degradation then your link won't work anyway - and you'll have bigger issues to worry about.
If you want your action to still work with JavaScript disabled, then using an a element with a href attribute that goes to some URL that will perform the action manually instead of via an Ajax request or whatever should be the way to go. If you are doing this, then you want to ensure you do an event.preventDefault() on your click call to make sure when the button is clicked it does not follow the link. This option is called graceful degradation.
'#' will take the user back to the top of the page, so I usually go with void(0).
javascript:; also behaves like javascript:void(0);
I would honestly suggest neither. I would use a stylized <button></button> for that behavior.
button.link {
display: inline-block;
position: relative;
background-color: transparent;
cursor: pointer;
border: 0;
padding: 0;
color: #00f;
text-decoration: underline;
font: inherit;
}
<p>A button that looks like a <button type="button" class="link">link</button>.</p>
This way you can assign your onclick. I also suggest binding via script, not using the onclick attribute on the element tag. The only gotcha is the psuedo 3d text effect in older IEs that cannot be disabled.
If you MUST use an A element, use javascript:void(0); for reasons already mentioned.
Will always intercept in case your onclick event fails.
Will not have errant load calls happen, or trigger other events based on a hash change
The hash tag can cause unexpected behavior if the click falls through (onclick throws), avoid it unless it's an appropriate fall-through behavior, and you want to change the navigation history.
NOTE: You can replace the 0 with a string such as javascript:void('Delete record 123') which can serve as an extra indicator that will show what the click will actually do.
The first one, ideally with a real link to follow in case the user has JavaScript disabled. Just make sure to return false to prevent the click event from firing if the JavaScript executes.
Link
If you use Angular2, this way works:
<a [routerLink]="" (click)="passTheSalt()">Click me</a>.
See here https://stackoverflow.com/a/45465728/2803344
Neither if you ask me;
If your "link" has the sole purpose of running some JavaScript code it doesn't qualify as a link; rather a piece of text with a JavaScript function coupled to it. I would recommend to use a <span> tag with an onclick handler attached to it and some basic CSS to immitate a link. Links are made for navigation, and if your JavaScript code isn't for navigation it should not be an <a> tag.
Example:
function callFunction() { console.log("function called"); }
.jsAction {
cursor: pointer;
color: #00f;
text-decoration: underline;
}
<p>I want to call a JavaScript function <span class="jsAction" onclick="callFunction();">here</span>.</p>
Ideally you'd do this:
Link text
Or, even better, you'd have the default action link in the HTML, and you'd add the onclick event to the element unobtrusively via JavaScript after the DOM renders, thus ensuring that if JavaScript is not present/utilized you don't have useless event handlers riddling your code and potentially obfuscating (or at least distracting from) your actual content.
Using just # makes some funny movements, so I would recommend to use #self if you would like to save on typing efforts of JavaScript bla, bla,.
I use the following
Link
instead
Link
I recommend using a <button> element instead, especially if the control is supposed to produce a change in the data. (Something like a POST.)
It's even better if you inject the elements unobtrusively, a type of progressive enhancement. (See this comment.)
I agree with suggestions elsewhere stating that you should use regular URL in href attribute, then call some JavaScript function in onclick. The flaw is, that they automaticaly add return false after the call.
The problem with this approach is, that if the function will not work or if there will be any problem, the link will become unclickable. Onclick event will always return false, so the normal URL will not be called.
There's very simple solution. Let function return true if it works correctly. Then use the returned value to determine if the click should be cancelled or not:
JavaScript
function doSomething() {
alert( 'you clicked on the link' );
return true;
}
HTML
link text
Note, that I negate the result of the doSomething() function. If it works, it will return true, so it will be negated (false) and the path/to/some/URL will not be called. If the function will return false (for example, the browser doesn't support something used within the function or anything else goes wrong), it is negated to true and the path/to/some/URL is called.
# is better than javascript:anything, but the following is even better:
HTML:
For great justice
JavaScript:
$(function() {
$(".some-selector").click(myJsFunc);
});
You should always strive for graceful degradation (in the event that the user doesn't have JavaScript enabled...and when it is with specs. and budget). Also, it is considered bad form to use JavaScript attributes and protocol directly in HTML.
Unless you're writing out the link using JavaScript (so that you know it's enabled in the browser), you should ideally be providing a proper link for people who are browsing with JavaScript disabled and then prevent the default action of the link in your onclick event handler. This way those with JavaScript enabled will run the function and those with JavaScript disabled will jump to an appropriate page (or location within the same page) rather than just clicking on the link and having nothing happen.
Definitely hash (#) is better because in JavaScript it is a pseudoscheme:
pollutes history
instantiates new copy of engine
runs in global scope and doesn't respect event system.
Of course "#" with an onclick handler which prevents default action is [much] better. Moreover, a link that has the sole purpose to run JavaScript is not really "a link" unless you are sending user to some sensible anchor on the page (just # will send to top) when something goes wrong. You can simply simulate look and feel of link with stylesheet and forget about href at all.
In addition, regarding cowgod's suggestion, particularly this: ...href="javascript_required.html" onclick="... This is good approach, but it doesn't distinguish between "JavaScript disabled" and "onclick fails" scenarios.
I usually go for
Link description
It's shorter than javascript:void(0) and does the same.
I choose use javascript:void(0), because use this could prevent right click to open the content menu. But javascript:; is shorter and does the same thing.
I would use:
Link
Reasons:
This makes the href simple, search engines need it. If you use anything else ( such as a string), it may cause a 404 not found error.
When mouse hovers over the link, it doesn't show that it is a script.
By using return false;, the page doesn't jump to the top or break the back button.
Don't use links for the sole purpose of running JavaScript.
The use of href="#" scrolls the page to the top; the use of void(0) creates navigational problems within the browser.
Instead, use an element other than a link:
<span onclick="myJsFunc()" class="funcActuator">myJsFunc</span>
And style it with CSS:
.funcActuator {
cursor: default;
}
.funcActuator:hover {
color: #900;
}
So, when you are doing some JavaScript things with an <a /> tag and if you put href="#" as well, you can add return false at the end of the event (in case of inline event binding) like:
Run JavaScript Code
Or you can change the href attribute with JavaScript like:
Run JavaScript Code
or
Run JavaScript Code
But semantically, all the above ways to achieve this are wrong (it works fine though). If any element is not created to navigate the page and that have some JavaScript things associated with it, then it should not be a <a> tag.
You can simply use a <button /> instead to do things or any other element like b, span or whatever fits there as per your need, because you are allowed to add events on all the elements.
So, there is one benefit to use <a href="#">. You get the cursor pointer by default on that element when you do a href="#". For that, I think you can use CSS for this like cursor:pointer; which solves this problem also.
And at the end, if you are binding the event from the JavaScript code itself, there you can do event.preventDefault() to achieve this if you are using <a> tag, but if you are not using a <a> tag for this, there you get an advantage, you don't need to do this.
So, if you see, it's better not to use a tag for this kind of stuff.
It would be better to use jQuery,
$(document).ready(function() {
$("a").css("cursor", "pointer");
});
and omit both href="#" and href="javascript:void(0)".
The anchor tag markup will be like
<a onclick="hello()">Hello</a>
Simple enough!
Usually, you should always have a fall back link to make sure that clients with JavaScript disabled still has some functionality. This concept is called unobtrusive JavaScript.
Example... Let's say you have the following search link:
Search
You can always do the following:
var link = document.getElementById('searchLink');
link.onclick = function() {
try {
// Do Stuff Here
} finally {
return false;
}
};
That way, people with JavaScript disabled are directed to search.php while your viewers with JavaScript view your enhanced functionality.
If you happen to be using AngularJS, you can use the following:
Do some fancy JavaScript
Which will not do anything.
In addition
It will not take you to the top of the page, as with (#)
Therefore, you don't need to explicitly return false with JavaScript
It is short an concise
Depending on what you want to accomplish, you could forget the onclick and just use the href:
Link Text
It gets around the need to return false. I don't like the # option because, as mentioned, it will take the user to the top of the page. If you have somewhere else to send the user if they don't have JavaScript enabled (which is rare where I work, but a very good idea), then Steve's proposed method works great.
Link text
Lastly, you can use javascript:void(0) if you do not want anyone to go anywhere and if you don't want to call a JavaScript function. It works great if you have an image you want a mouseover event to happen with, but there's not anything for the user to click on.
I believe you are presenting a false dichotomy. These are not the only two options.
I agree with Mr. D4V360 who suggested that, even though you are using the anchor tag, you do not truly have an anchor here. All you have is a special section of a document that should behave slightly different. A <span> tag is far more appropriate.
I tried both in google chrome with the developer tools, and the id="#" took 0.32 seconds. While the javascript:void(0) method took only 0.18 seconds. So in google chrome, javascript:void(0) works better and faster.
I personally use them in combination. For example:
HTML
Link
with little bit of jQuery
$('a[href="#"]').attr('href','javascript:void(0);');
or
$('a[href="#"]').click(function(e) {
e.preventDefault();
});
But I'm using that just for preventing the page jumping to the top when the user clicks on an empty anchor. I'm rarely using onClick and other on events directly in HTML.
My suggestion would be to use <span> element with the class attribute instead of
an anchor. For example:
<span class="link">Link</span>
Then assign the function to .link with a script wrapped in the body and just before the </body> tag or in an external JavaScript document.
<script>
(function($) {
$('.link').click(function() {
// do something
});
})(jQuery);
</script>
*Note: For dynamically created elements, use:
$('.link').on('click', function() {
// do something
});
And for dynamically created elements which are created with dynamically created elements, use:
$(document).on('click','.link', function() {
// do something
});
Then you can style the span element to look like an anchor with a little CSS:
.link {
color: #0000ee;
text-decoration: underline;
cursor: pointer;
}
.link:active {
color: red;
}
Here's a jsFiddle example of above aforementioned.
On a modern website the use of href should be avoided if the element is only doing JavaScript functionality (not a real link).
Why?
The presence of this element tells the browser that this is a link with a destination.
With that, the browser will show the Open In New Tab / Window function (also triggered when you use shift+click).
Doing so will result in opening the same page without the desired function triggered (resulting in user frustration).
In regards to IE:
As of IE8, element styling (including hover) works if the doctype is set. Other versions of IE are not really to worry about anymore.
Only Drawback:
Removing HREF removes the tabindex.
To overcome this, you can use a button that's styled as a link or add a tabindex attribute using JS.
When I've got several faux-links, I prefer to give them a class of 'no-link'.
Then in jQuery, I add the following code:
$(function(){
$('.no-link').click(function(e){
e.preventDefault();
});
});
And for the HTML, the link is simply
Faux-Link
I don't like using Hash-Tags unless they're used for anchors, and I only do the above when I've got more than two faux-links, otherwise I go with javascript:void(0).
Faux-Link
Typically, I like to just avoid using a link at all and just wrap something around in a span and use that as a way to active some JavaScript code, like a pop-up or a content-reveal.
It's nice to have your site be accessible by users with JavaScript disabled, in which case the href points to a page that performs the same action as the JavaScript being executed. Otherwise I use "#" with a "return false;" to prevent the default action (scroll to top of the page) as others have mentioned.
Googling for "javascript:void(0)" provides a lot of information on this topic. Some of them, like this one mention reasons to NOT use void(0).