what's the difference between <a onclick="someFunction"> and <a onclick="someFunction()"> - javascript

what is the difference between
<a onclick="someFunction">
and
<a onclick="someFunction()">
One uses the parenthesis and not the other, but what are the differences of using either? What is the "correct" option? And what happens if i dont use any href attribute?
As far as I know, in javascript, using something = someFunc(); assigns the return value of that function to the something variable. And using something = someFunc; assigns the function directly (not its result) to that variable (And it's mostly used to assign functions to events). e.g. I can assign a function to a onclick event.
But what I don't understand is what happens when using either in some html element inline event, as in the examples, since the assignation is not to a javascript variable, but to an html attribute, which happens to be an event? Please explain.
And also, is there a difference on assigning a inline onclick function to an anchor (a) that to other elements (e.g. span div label etc)? Do they have the same effect?
Sidenote:
I've been reading here about how to run a function when clicking on a link, and I already understood is that is should not be done "inline", but instead using unobtrusive javascript. (I mention it to avoid debate about that), but in the examples I've seen they don't mention the difference of both options I mention when doing it inline.
Edit: This question was made because here they gave an answer which doesn't use the parenthesis in the function for the event, and nobody mentioned the parenthesis were needed, so I assume it is valid. yet I don't know what is the difference of using () or not.

One uses the parenthesis and not the other, but what are the differences of using either?
<a onclick="someFunction"> won't do anything. The parenthesis cause a function to be called.
Having a statement consisting of nothing but an identifier (be it a function name, variable, or whatever) won't do anything (except throw a reference error if the variable doesn't exist).
And what happens if i dont use any href attribute?
Then I'd question why you were using an <a> element in the first place.
And also, is there a difference on assigning a inline onclick function to an anchor (a) that to other elements (e.g. span div label etc)?
Only that they aren't (by default) focusable elements (nor is an a element without an href attribute), so the click event couldn't be triggered by tabbing to the element and pressing enter. If you want an element that will do something with JS when triggered, and you don't have a sensible fallback for when JS isn't available, use a button.

The value of an event handler attribute is a sequence of Javascript statements, not an expression.
It isn't assigning a function value to the property; it's a piece of code to execute at that event.
Leaving out the parentheses, results in an expression statement that has no effect.

when writing inline on click functions, we assigning the code to be executed in the form of string on click of the element.
It is equivalent to eval('someFunction()');
we cannot write on click='someFunction' since it will be equivalent to eval('someFunction') which would do nothing.
if you intend to bind a click handler to an anchor tag, dont forget to add a href='#' attribute to the anchor tag.
There is no difference between assigning a click handler to span or divs as compared to anchor tag.

Related

What does Javascript: void%200 actually do? [duplicate]

login
I've seen such hrefs many times, but I don't know what exactly that means.
The void operator evaluates the given
expression and then returns undefined.
The void operator is often used merely
to obtain the undefined primitive
value, usually using “void(0)” (which
is equivalent to “void 0”). In these
cases, the global variable undefined
can be used instead (assuming it has
not been assigned to a non-default
value).
An explanation is provided here: void operator.
The reason you’d want to do this with the href of a link is that normally, a javascript: URL will redirect the browser to a plain text version of the result of evaluating that JavaScript. But if the result is undefined, then the browser stays on the same page. void(0) is just a short and simple script that evaluates to undefined.
In addition to the technical answer, javascript:void means the author is Doing It Wrong.
There is no good reason to use a javascript: pseudo-URL(*). In practice it will cause confusion or errors should anyone try things like ‘bookmark link’, ‘open link in a new tab’, and so on. This happens quite a lot now people have got used to middle-click-for-new-tab: it looks like a link, you want to read it in a new tab, but it turns out to be not a real link at all, and gives unwanted results like a blank page or a JS error when middle-clicked.
<a href="#"> is a common alternative which might arguably be less bad. However you must remember to return false from your onclick event handler to prevent the link being followed and scrolling up to the top of the page.
In some cases there may be an actual useful place to point the link to. For example if you have a control you can click on that opens up a previously-hidden <div id="foo">, it makes some sense to use <a href="#foo"> to link to it. Or if there is a non-JavaScript way of doing the same thing (for example, ‘thispage.php?show=foo’ that sets foo visible to begin with), you can link to that.
Otherwise, if a link points only to some script, it is not really a link and should not be marked up as such. The usual approach would be to add the onclick to a <span>, <div>, or an <a> without an href and style it in some way to make it clear you can click on it. This is what StackOverflow [did at the time of writing; now it uses href="#"].
The disadvantage of this is that you lose keyboard control, since you can't tab onto a span/div/bare-a or activate it with space. Whether this is actually a disadvantage depends on what sort of action the element is intended to take. You can, with some effort, attempt to mimic the keyboard interactability by adding a tabIndex to the element, and listening for a Space keypress. But it's never going to 100% reproduce the real browser behaviour, not least because different browsers can respond to the keyboard differently (not to mention non-visual browsers).
If you really want an element that isn't a link but which can be activated as normal by mouse or keyboard, what you want is a <button type="button"> (or <input type="button"> is just as good, for simple textual contents). You can always use CSS to restyle it so it looks more like a link than a button, if you want. But since it behaves like a button, that's how really you should mark it up.
(*: in site authoring, anyway. Obviously they are useful for bookmarklets. javascript: pseudo-URLs are a conceptual bizarreness: a locator that doesn't point to a location, but instead calls active code inside the current location. They have caused massive security problems for both browsers and webapps, and should never have been invented by Netscape.)
It means it’ll do nothing. It’s an attempt to have the link not ‘navigate’ anywhere. But it’s not the right way.
You should actually just return false in the onclick event, like so:
hello
Typically it’s used if the link is doing some ‘JavaScript-y’ thing. Like posting an AJAX form, or swapping an image, or whatever. In that case you just make whatever function is being called return false.
To make your website completely awesome, however, generally you’ll include a link that does the same action, if the person browsing it chooses not to run JavaScript.
<a href="backup_page_displaying_image.aspx"
onclick="return coolImageDisplayFunction();">hello</a>
It is a very popular method of adding JavaScript functions to HTML links.For example: the [Print] links that you see on many webpages are written like this:
Print
Why do we need href while onclick alone can get the job done? Because when users hover over the text 'Print' when there's no href, the cursor will change to a caret (ꕯ) instead of a pointer (👆). Only having href on an a tag validates it as a hyperlink.
An alternative to href="javascript:void(0);", is the use of href="#". This alternative doesn't require JavaScript to be turned on in the user's browser, so it is more compatible.
There is a huge difference in the behaviour of # vs javascript:void(0);.
# scrolls you to the top of the page but javascript:void(0); does not.
This is very important if you are coding dynamic pages because the user does not want to go back to the top when they click a link on the page.
You should always have an href on your a tags. Calling a JavaScript function that returns 'undefined' will do just fine. So will linking to '#'.
Anchor tags in Internet Explorer 6 without an href do not get the a:hover style applied.
Yes, it is terrible and a minor crime against humanity, but then again so is Internet Explorer 6 in general.
I hope this helps.
Internet Explorer 6 is actually a major crime against humanity.
It's worth mentioning that you'll sometimes see void 0 when checking for undefined, simply because it requires fewer characters.
For example:
if (something === undefined) {
doSomething();
}
Compared to:
if (something === void 0) {
doSomething();
}
Some minification methods replace undefined with void 0 for this reason.
Usage of javascript:void(0) means that the author of the HTML is misusing the anchor element in place of the button element.
Anchor tags are often abused with the onclick event to create
pseudo-buttons by setting href to "#" or "javascript:void(0)" to
prevent the page from refreshing. These values cause unexpected
behavior when copying/dragging links, opening links in a new
tabs/windows, bookmarking, and when JavaScript is still downloading,
errors out, or is disabled. This also conveys incorrect semantics to
assistive technologies (e.g., screen readers). In these cases, it is
recommended to use a <button> instead. In general you should only use
an anchor for navigation using a proper URL.
Source: MDN's <a> Page.
Web Developers use javascript:void(0) because it is the easiest way to prevent the default behavior of a tag. void(*anything*) returns undefined and it is a falsy value. and returning a falsy value is like return false in onclick event of a tag that prevents its default behavior.
So I think javascript:void(0) is the simplest way to prevent the default behavior of a tag.
void is an operator that is used to return a undefined value so the browser will not be able to load a new page.
Web browsers will try and take whatever is used as a URL and load it unless it is a JavaScript function that returns null. For example, if we click a link like this:
Click Me
then an alert message will show up without loading a new page, and that is because alert is a function that returns a null value. This means that when the browser attempts to load a new page it sees null and has nothing to load.
An important thing to note about the void operator is that it requires a value and cannot be used by itself. We should use it like this:
I am a useless link
To understand this concept one should first understand the void operator in JavaScript.
The syntax for the void operator is: void «expr» which evaluates expr and returns undefined.
If you implement void as a function, it looks as follows:
function myVoid(expr) {
return undefined;
}
This void operator has one important usage that is - discarding the result of an expression.
In some situations, it is important to return undefined as opposed to the result of an expression. Then void can be used to discard that result. One such situation involves javascript: URLs, which should be avoided for links, but are useful for bookmarklets. When you visit one of those URLs, many browsers replace the current document with the result of evaluating the URLs “content”, but only if the result isn’t undefined. Hence, if you want to open a new window without changing the currently displayed content, you can do the following:
javascript:void window.open("http://example.com/")
A link must have an href target to be specified to enable it to be a usable display object.
Most browsers will not parse advanced JavaScript in the href of an <a> element, for example:
Get element
Because the href tag in most browsers does not allow whitespace or will convert whitespace to %20 (the HEX code for space), the JavaScript interpreter will run into multiple errors.
So if you want to use an <a> element's href to execute inline JavaScript, you must specify a valid value for href first that isn't too complex (doesn't contain whitespace), and then provide the JavaScript in an event attribute tag like onClick, onMouseOver, onMouseOut, etc.
The typical answer is to do something like this:
Get element
This works fine but it makes the page scroll to the top because the # in the href tells the browser to do this.
Placing a # in the <a> element's href specifies the root anchor, which is by default the top of the page, but you can specify a different location by specifying the name attribute inside an <a> element.
<a name="middleOfPage"></a>
You can then change your <a> element's href to jump to middleOfPage and execute the JavaScript in the onClick event:
Get element
There will be many times where you do not want that link jumping around, so you can do two things:
Get element
Now it will go nowhere when clicked, but it could cause the page to re-centre itself from its current viewport.
The best way to use in-line javascript using an <a> element's href, but without having to do any of the above is JavaScript:void(0);:
Get element
This tells the browser no to go anywhere, but instead execute the JavaScript:void(0); function in the href because it contains no whitespace, and will not be parsed as a URL. It will instead be run by the compiler.
void is a keyword which, when supplied with a parameter of 0 returns undefined, which does not use any more resources to handle a return value that would occur without specifying the 0 (it is more memory-management/performance friendly).
The next thing that happens is the onClick gets executed. The page does not move, nothing happens display-wise.
The void operator evaluates the given expression and then returns undefined.
It avoids refreshing the page.
From what I've seen, the void operator has 3 common uses in JavaScript. The one that you're referring to, <a href="javascript:void(0)"> is a common trick to make an <a> tag a no-op. Some browsers treat <a> tags differently based on whether they have a href , so this is a way to create a link with a href that does nothing.
The void operator is a unary operator that takes an argument and returns undefined. So var x = void 42; means x === undefined. This is useful because, outside of strict mode, undefined is actually a valid variable name. So some JavaScript developers use void 0 instead of undefined. In theory, you could also do <a href="javascript:undefined"> and it would so the same thing as void(0).

Is it bad practice to dynamically set/change event handlers?

I am trying to replace confirm() boxes with bootstrap modals for save/delete operations in a page.There is a button(call it action-button) for each of these operation which then triggers the respective modal. On clicking the confirm button on the modal,the respective function is triggered.
Instead of writing modals for each of these operations,I was thinking if I could use just one confirm modal and change the event handler when the "action-button" is clicked.
Like this:
$("#confirm-button").attr('onclick',save_all());
when save_all button is clicked.
Is it bad practice?And what are some alternatives to this? Thanks!
I don't think changing the event handler is a good choice as you should handle the previous attached handlers in order to avoids memory leak and weird behaviours.
A better approach could be defining a generic handler that will read from a data attribute on the DOM, what to do in case of confirmation.
The main part is that such handler should not been coupled with the working staff.
To achieve this you could define custom events that will be fired from your generic handler.
I mean something like:
function confirmAction(ev) {
// you can save in the HTML the name of the proper event
var whatEv = $(this).data('my-key');
// Here you could fire a custom event.
$(this).trigger(whatEv);
}
Last thing, as #trincot pointed, your code in the OP is wrong.
It will not even do what you intend, because you call save_all at the moment you set the attribute, and it will be the function's return value that is stored in the onclick attribute, converted to string if it is not yet a string. This most probably is not what you intended to do.
Even if the attribute value would be correct, it is not the best practice, because:
That attribute value needs to be evaluated/parsed, which means you can get late syntax errors
It replaces the previous value of the onclick attribute, which might be an undesired effect (although I understand in your case that is what you want)
Instead bind event handlers the jQuery way and make sure you don't call the function, but pass its reference:
$("#confirm-button").on('click', save_all);
If the purpose is to replace any previous click handler, then chain in an off call:
$("#confirm-button").off('click').on('click', save_all);

Why does Chrome use `with` for inline events

If you take a look at this fiddle in Chrome and click the Trigger text with the js console open you will see this:
What is the reason of all those with blocks and what is it's value?
It looks to me as if it's how the browser creates a function for the event handler when it's specified as an HTML "onclick" attribute. I think what that does is:
make an event handler function with a single parameter for the event object and your supplied code;
make properties of the element (the <a> tag), an empty object (?), and the document object appear to be available symbols for the code in that function.
That is, this[0] is the <a> element itself, this[1] looks like an empty Object instance, and this[2] is the document object. What this means is that in code you write as part of an "onfoo" event handler attribute (and not code in any ordinary event handler bound from straight JavaScript code), it's possible to refer to the properties of the target element (the element for which you're setting the attribute) and the properties of the document element as if they were present in the scope chain.
If you change the code a little:
$('<a href=# onclick="console.log(baseURI);"> ...
then you get the value of the "baseURI" property of the <a> element. No need to prefix "baseURI" with anything that explicitly refers to the DOM node for the <a> element; it's just "there" as if it were declared with var in some enclosing scope.
(checking w3c specs now ...) edit — I haven't found anything that stipulates what symbols are supposed to be available to the script code in event handlers. This is really weird.
edit again — Firefox seems to do the same thing, though I don't see the explicit with statements anywhere.
with moves it's argument on top of scope stack. So it's even higher than global object, function params, etc. No idea why they use it. Perhaps it is a generated code.

What does "this" refer to in an HTML anchor

I am trying to do something in JavaScript before following the link in the href part of a link:
<a href="open.this.page" onclick="doStuff(this);return false; title="follow me">
Question is what does this in doSuff(this) refer to? I was expecting to have to get the href part of the anchor out of it, but when examining it looks like it IS the href and nothing else.
function doSutff(my_arg) {
alert (my_arg);
// do stuff
// follow the href in the link
}
In the above alert I get exactly the href as "http://my.domain/open.this.page".
Is this expected or am I getting it in one browser, but probably not in another?
If that is the normal behavior then how would one get, for example, the rel or title part of an anchor? DOM only?
In this case this refers to the DOM node.
"in the above alert I get exactly the href as "http://my.domain/open.this.page".
Is this expected or am I getting it in one browser, but probably not in another?"
This is expected. The reason you get "http://my.domain/open.this.page" in the alert is that that is what the default .toString() value is of an <a> element.
It's an unusual case. Other elements don't show an attribute as the .toString() representation.
If you want to actually do work with the href, you'd need to do this.toString(), or see below...
"...how would one get, for example, the REL or TITLE part of an anchor?"
To get other attributes or properties, you'd just do it the usual ways.
To get the attribute, you can do:
onclick="doStuff(this.getAttribute('title')); return false;"
Most of the standard attributes map directly to a property on the node, so you could also do this:
onclick="doStuff(this.title); return false;"
Or since you're in an inline handler, you can actually do this:
onclick="doStuff(title); return false;"
The reason that last one works is that handlers assigned from an attribute have a unique scope chain that includes the element itself. This means that properties on the element actually show up as variables.
Note that this doesn't work for any other kind of event handler.
With regard to this, it refers to the element to which the handler is bound.
What happens to the attribute is that it basically becomes the body of a function assigned to the onclick property.
So you end up with something like this:
elem.onclick = function(event) {
doStuff(this);return false; // Your onclick attribute value
}
So you can see that this is actually just the normal value found in an event handler assigned to a property.
Notice also that there's an event parameter defined. This means that you could change your attribute like this:
onclick="doStuff(this, event);return false;"
...and it will pass on that parameter, because now your function looks like this:
elem.onclick = function(event) {
doStuff(this, event);return false; // Your onclick attribute value
}
So you can see that your string is actually referencing the normal event parameter of the function.
This also works in older IE. In IE, the event parameter won't be defined, so it'll pick up the global event object.
// ---------------v----no parameter
elem.onclick = function() {
// v---now it picks up the global event
doStuff(this, event);return false; // Your onclick attribute value
}
this in the context of any event (onclick or otherwise) refers to the DOM element that triggered the event.
In your case, it is the anchor tag itself.

Event/object in JavaScript function

If I have some HTML like this:
<a onmouseover='SetTopLeft(this);'href='#'>Click me!</a>
Can I get both the object AND the event in the function? So, for example, can I have a method signature like this?
function SetTopLeft(e, o)
...where e is the event and o is 'this'? I may actually not need the object, but I think I probably DO need the event. I wouldn't mind understanding a little better how this works in JavaScript - i.e., when/how can I pass an event and when/how can I pass the calling object? Can I choose which to pass? Can I pass both?
Basically, what I really need to do is get the mouse coordinates within the DIV within which the anchor is located (even if that DIV is only a portion of a web page and whether or not the browser is full-screen) and I'm having a terrible time getting it done. Most of the examples I have seen for getting these coordinates within some element use the event and the pageX and pageY properties of that event.
By the way, this must work in IE 6 onward. Firefox would be good, too. Others are not necessary.
Yes, in the inline code this refers to the HTML DOM object for the element, and event refers to the event object. So you could do the following:
HTML
<a onmouseover='SetTopLeft(event, this);' href='#'>Click me!</a>
JavaScript
function SetTopLeft(e, obj) {...}
In general you should avoid using inline event handlers. It mixes representation (HTML) with logic (JavaScript). quirksmode.org offers a nice collection of articles of all there is to know about event handling.
Since inside an event handler, this typically refers to element the handler is bound to, you can also explicitly set this to the element and pass the event object as first argument:
<a onmouseover='SetTopLeft.call(this, event);'href='#'>Click me!</a>
See .call() [MDN] for more information.
Besides that, if your link is not linking to anything, better use a simple span element or a button and style it accordingly.

Categories

Resources