I found this code working in Chrome, FF, and IE. However, I can't find any references to the "magic" event keyword on the web. See this
<html>
<head>
<script type="text/javascript">
function handler(e){
alert(e);
}
</script>
</head>
<body>
<h1 onclick="handler(event);alert(0)">Click on this text</h1>
</body>
</html>
This script STOPS working if I change event in brackets to something else. Is that a deprecated keyword?
The Event object is automatically passed to all event handlers. If you add event handlers with addEventListener, you can choose the parameter name (like you did in handler). But for code attached with the onclick attribute, you can only access the event object via the implicit variable event.
If you want to know more about event handling in general, I suggest to read about it at quirksmode.org.
Also have a look at MDC - Event handlers:
These are properties that correspond to the HTML 'on' event attributes.
Unlike the corresponding attributes, the values of these properties are functions (or any other object implementing the EventListener interface) rather than a string. In fact, assigning an event attribute in HTML creates a wrapper function around the specified code. For example, given the following HTML:
<div onclick="foo();">click me!</div>
If element is a reference to this div, the value of element.onclick is effectively:
function onclick(event) {
foo();
}
Note how the event object is passed as parameter event to this wrapper function.
When an event attribute is set, an implicit Function is created with event as the first argument. When the event fires, the event object is passed to that function. There wasn't a solid definition on this behavior until HTML 5 (which is still a draft), but it's been this way for a long time in the major browsers and that's how it made it into the spec:
When an event handler's Function object is invoked, its call() callback must be invoked with one argument, set to the Event object of the event in question.
That argument is aptly named event for obvious reasons. http://www.w3.org/TR/html5/webappapis.html#events
This really threw me. The following 'typo' works in Chromium, but not FF:
some_worker.onmessage = function(e) {
// do stuff
if (e.data instanceof ArrayBuffer)
intArray = new Uint8Array(event.data);
// do other stuff
};
Chromium was observing the implicit keyword for 'event' but FF threw an 'undefined variable' error! Just changed 'event' to 'e' and all is well.
I notice that even stackoverflow's code markup observes 'event' as an implicit keyword ... not to knock FF, since it detected the typo.
The word event is not only an "other reserved word" in JavaScript, it is a always reserved word in all JavaScript Events (Event). See here: https://developer.mozilla.org/en-US/docs/Web/API/Event
For an Event with a function like onclick="myFunction()", there are two solutions.
First: The onclick="myFunction(event)" passed the event to the function. This is similar by this.
You can test it with onclick="consloe.log(event)" and onclick="consloe.log(this)". event is here a reserved word equally this. this contains the (HTML) Element. event contains the Event.
Consider onclick="myFunction(evt)" don't work (Error: evt is undefined).
Whit the example below, the event passed not only into the myFunction(), but it can used as a variable inside the function. This is not necessary in simple matters like this, because event is always global inside the function.
example.com
<script>
function myFunction(evt) {
var confirmresult = confirm("Press a button!");
if (confirmresult == true) {
// OK = go away!
} else {
// Cancel = stay here!
evt.preventDefault(); // is in this case the same as event.preventDefault();
}
};
</script>
JSFiddle: https://jsfiddle.net/usfrc6dn/
Second: Nothing is vissible passed in the onclick="myFunction()". The event is used inside the function.
example.com
<script>
function myFunction() {
var confirmresult = confirm("Press a button!");
if (confirmresult == true) {
// OK = go away!
} else {
// Cancel = stay here!
event.preventDefault();
}
};
</script>
JSFiddle: https://jsfiddle.net/qczt587u/
Only the second methode is valide in the reference of the docs, because about the using of event as onclick="myFunction(event)" is nothing to find, respectively only for onclick="myFunction(this)". When you have other information, please make a correction.
When you use onclick="myFunction(event)", you can use the event inside the function as a variable like function myFunction(evt) { evt.preventDefault();}. But that have a little bit risk. Either, the event is automatically passed to functions that are embeeded or called inside the function. Also is only onclick="myFunction()" without risk and also valid.
Examples:
<div id="foo" onclick="foo();">click me!</div>
function foo(evt) {
console.log(evt); // undefined
console.log(event); // the Event "click" Object
}
<div id="foo" onclick="foo(evt);">click me!</div>
// ERROR: the variable "evt" is not defined!
<div id="foo" onclick="foo(event);">click me!</div>
function foo(evt) {
console.log(evt); // the Event "click" Object
console.log(event); // the Event "click" Object
}
<div id="foo" onclick="foo();">click me!</div>
function foo() {
console.log(this); // the Function "foo" Object
console.log(event); // the Event "click" Object
}
<div id="foo" onclick="foo(this);">click me!</div>
function foo() {
console.log(this); // the Function "foo" Object
console.log(event); // the Event "click" Object
}
<div id="foo" onclick="foo(this);">click me!</div>
function foo(element) {
console.log(element); // the Element "div" Object
console.log(this); // the Function "foo" Object
console.log(event); // the Event "click" Object
}
<div id="foo" onclick="foo(this);">click me!</div>
function foo(this) {
// ERROR: foo is not a function.
// Cause: 'this' is a reserved word.
console.log(element);
console.log(this);
console.log(event);
}
<div id="foo" onclick="foo(this);">click me!</div>
function foo(event) {
console.log(this); // the Function "foo" Object
console.log(event); // the Event "click" Object
}
There are also differences between this and event that are to consider.
Conclusion: Only onclick="myFunction()" is without risk and also valid in the matter of event.
I guess your are trying to pass the clicked HTML element to your handler() function. The correct way to do that i your code is:
<h1 onclick="handler(this);">Click on this text</h1>
However I strongly recommend avoid this approach. Avoid having styling and behavior defined on the HTML. Please read the following article:
Unobtrusive JavaScript
Related
This is my button element:
<button id="loginButton"
...
onclick="e.preventDefault(); return true;"/>
But this approach gives me after login button click error in console:
Uncaught ReferenceError: e is not defined
Do you know how to fix my button to avoid "e is not defined" error in console?
e is a variable commonly used in event handlers. However you never defined e in your code. I recommend using an event listener in JS.
document.getElementById('loginButton').addEventListener('click', function(e) {
e.preventDefault();
return true;
});
This will accomplish what you need.
in events (like onclick="...") you can specify either a function name, then this function has to have a single parameter, where the event object will be passed.
Or you can specify an JavaScript expression (as in your case), in this case there will be created implicit function (event) { ... } with your code placed inside.
I.e. in that case you have to use event (instead of e) as the name of the event object.
I am curious about how the content of the inline element attribute event works under the hood.
We start off with a simple function
function handler(e) {
console.log(e);
}
Use Case 1
If we would want to add this handler to our button we could do:
<button onclick="handler();">Click Me</button>
Which Logs on click: undefined
Fair enough, we called a function without passing arguments.
Use Case 2
If we now change the button to take the event as an argument:
<button onclick="handler(event);">Click Me</button>
We log on click: MouseEvent{ ... }
Now we log the event, as we could have expected
Use Case 3
But what if we just specify the function name?
<button onclick="handler">Click Me</button>
Nothing happens!, I was hoping just giving a reference to a function, would do the trick. So when "onlick" would happen, the referred function would be called with the proper event argument.
Use Case 4
When we add the handler in javascript:
const btn = document.getElementById('btn');
btn.onclick = handler;
it works, capturing the event and logs the related event object.
Concluding Question
Whatever text/content/statement that we pass to onclick="" inline, does it basically run eval() on it? And when we attach it in javascript (btn.onclick = ...) it goes through the proper process to intercept the event and then call bounded handler function and passes the corresponding event object with it (e.g. MouseEvent)?
Quick Note
To be clear, this is an informative question, to understand the fundamentals, disregarding if it's considered a bad or good practice. That's not being discussed at this point.
Yes, in an inline handler, the attribute text is essentially just evaled, with a few qualifications. What
<button onclick="handler">Click Me</button>
is roughly equivalent to would be if you had a (true) handler which referenced the handler function but didn't call it, for example:
btn.onclick = () => {
handler;
};
This doesn't throw an error (because handler is referenceable), but it doesn't run handler either, because you're only referencing the function, not calling it.
When you do
btn.onclick = handler;
you are passing a reference to handler to the onclick internals, which then call that reference later, when the button is clicked.
(If you had done btn.onclick = handler;, handler would be invoked immediately, and its return value would be added as a listener, which isn't what you'd want)
When you do
<button onclick="handler(event);">Click Me</button>
the event argument you're passing comes from window.event, which is why it's referenceable.
Like I said, there are a few qualifications, though: inline handlers implicitly use something like a with(this) around the whole text that is run, where this is the element in question. (it also uses with for the document and containing form, as you can see from Quentin's answer) For example:
<a onclick="search();">Click me!</div>
looks, to the interpreter, a bit like:
<a onclick="
with(this) {
search();
}
">Click me!</div>
which is problematic, because search is a property of HTMLAnchorElement.prototype. Referencing other variable names can have similar problems, if those variable names are properties anywhere on the element's prototype chain.
Best to avoid inline handlers entirely, and attach the event properly using Javascript instead.
This is not what happens, but you can imagine it like this:
Imagine that the javascript engines saves the content of the onclick attribute as a string, and when a user clicks the element, then evaluates the content.
For example:
function foo(a, b) {
alert(a + ' ' + b);
}
<button onclick="foo('hello', 'world')">click me</button>
<button onclick="(function () { alert ('I\'m an inline IIFE') })()">click me</button>
It's the same result of eval("foo('hello', 'world')". What if you pass event or this or other keywords?
Well, also here, you can imagine a javascript engines doing this:
var this = /* create context */;
var event = /* create event */;
eval("foo(this, event)");
This is what the specification says, the attribute needs to be evaluated! I'm not saying that the engine uses eval :P
Example:
<button onclick="alert('hello world')">Click me</button>
What about btn.onclick = handler;?
This is another pair of shoes. The onclick property is a callback, and it wants a function reference.
When you use HTML attribute for the event, you actually create a function under the hood which assigned as the handler of the relevant event.
The body of the function is the content of the attribute. It should be JavaScript code.
The function gets as parameter the event parameter
So,
In case 1, The generated handler :
function handlerHtml(event) {
handler()
}
In case 2, The generated handler :
function handlerHtml(event) {
handler(event)
}
In case 3, The generated handler :
function handlerHtml(event) {
handler
}
I have created the following function.
function showAllSelectOpts(select)
{
selectLength = select.children().length;
select.attr('size',selectLength);
select.css('height','auto');
select.focusout(function(){
select.attr('size','1');
});
}
When it is called directly on a select element like this showAllSelectOpts(mySelect); it works fine, but when called within another function, as below using the keyword "this", it returns the error. Type error: select.children not a function
$('select').on('focus',function(){
showAllSelectOpts(this);
})
Is this a scope issue or what, and how can I resolve it?
In an event handler, this is a reference to the DOM element, not a jQuery object. But your showAllSelectOpts expects its argument to be a jQuery object.
Either change the call to wrap the DOM element with $():
showAllSelectOpts($(this));
...or update showAllSelectOpts to do so itself:
function showAllSelectOpts(select)
{
select = $(select); // ***
selectLength = select.children().length;
select.attr('size',selectLength);
select.css('height','auto');
select.focusout(function(){
select.attr('size','1');
});
}
Side note: As A.Wolff points out, your function attaches a new focusout handler to the select every time it's called. You only want one.
I'd remove that part of the handler entirely, and replace it with a single focusout:
function showAllSelectOpts(select)
{
var selectLength = select.children().length;
select.attr('size',selectLength);
select.css('height','auto');
}
$('select')
.on('focus',function(){
showAllSelectOpts($(this));
})
.on('focusout', function(){
$(this).attr('size', '1');
});
Also note that I added a var for selectLength in showAllSelectOpts (although actually, you could just remove the variable entirely); without one, the code is falling prey to The Horror of Implicit Globals (that's a post on my anemic little blog). Be sure to declare your variables.
jQuery event listener callbacks set this as the HTMLElement that the event was fired on.
In your callback you are expecting a jQuery object, but you have the HTMLElement.
You can pass the HTMLElement to a jQuery constructor and pass it into the showAllSelectOpts function
$('select').on('focus',function(){
showAllSelectOpts($(this));
})
Try this one -
$('select').on('focus',function() {
showAllSelectOpts($(this)); })
Try this:
var myselect = $('select');
$('select').on('focus',function(){
showAllSelectOpts(myselect);
})
A better way could be:
$('select').on('focus',function(event){
showAllSelectOpts($(event.target));
})
Why your code not working?
$('select').on('focus',function(){
//Here `this` is bound with the dom html element, not the $('select') object.
showAllSelectOpts(this);
})
These previous answers fix it. I'd just add here to create it as an extension since $(this) refers to a prototype of one method call.
$.fn.showAllSelectOpts=function() {
$(this).on('focus',()=>{
$(this)
.css('height','auto')
.attr('size',$(this).children().length)
.focusout(()=>{
$(this).attr('size','1');
});
});
};
$('select').showAllSelectOpts();
Sorry for the vague title. I am using jQuery. I have a small scenario in my app and I am stuck.
Problem: I have two functions in my script named as func1 and func2. I want to execute both of these functions when ever an user clicks on the div element and also to access the value of the code attribute in these two functions.
<div id="testId" code="102">Click ME</div> .
Code:
<html>
<body>
<div id="testId" code="102">Click ME</div>
<script type='text/javascript' src='jquery.js'></script>
<script type='text/javascript' src='script.js'></script>
</body>
</html>
script.js:
var code1 = "";
var code2 = "";
func1 = function(){
code1 = $(this).attr('code');
alert("code1 is "+code1);
}
func2 = function(){
code2 = $(this).attr('code');
alert("code2 is "+code2+'2');
}
$('#testId').click(func1, func2);
/*$('#testId').click(function(){
func1();
func2();
});*/
I want to access the value of code="102"in my two functions. I tried two ways.
First I tried the following snippet:
$('#testId').click(func1, func2);
This only executes the func2. The value of the code attribute is also being accessed by func2. But the func1 is not executing! How to do this?
Then I tried a second way. I am able to execute the both functions when ever an user clicks on the div, by using the following snippet
$('#testId').click(function(){
func1();
func2();
});
but now I am unable to access the value of code attribute and it is undefined! How can I access the value of the code attribute in func1 and func2?
I know I can pass the parameters to func1 and func2 like below and later access the values,
$('#testId').click(function(){
func1('value of code');
func2('value of code');
});
But I am looking for a different solution if possible.
Finally I am looking for a way by which I can execute both of the functions and also have access to the value of the code attribute. Any suggestion will be appreciated!
First for all you are ussing the .Click() method so, if you use .click(func1, func2) it hopes that .click( [eventData ], handler ). becouse that only execute the function2 so It's a handlers.
Well you will need execute like:
$('#testId').click(function(){
func1();
func2();
});
If you need get the code, it's much better create a data attribute like:
<div id="testId" data-code="102">Click ME</div>
$('#testId').click(function(){
func1.call(this);
func2.call(this);
});
func1 = function(){ console.log($(this).data('code'));
code1 = $(this).data('code');
alert("code1 is "+code1);
}
With .call() you send who is calling the function.
Advantage:
Well the .data() attr is better becuse all data that you read you will know that it's aditional paramert, instead only code you maybe don't know where it comes from. unsing the .call keep the method clean of parameters.
Disadvantage
You need to know, What does the call do. and Maybe mixing Vanilla with jQuery. :)
LIVE DEMO
This is an issue of scope really. A proper solution can be seen at http://jsfiddle.net/dboots/dhd0dem7/.
In your code, you are referencing $(this) inside func1 and func2. These refer to the actual func1 and func2 scopes and they have no idea what "code" is.
The $(this) inside the click handler, actually refers to the div element you are clicking on so it's fitting to use it there.
In the jsfiddle, we declare code at the global level and set it in the click handler.
var code;
$('#testId').click(function() {
code = $(this).attr('code');
func1();
func2();
});
Then the func1 and func2 functions are able to access it as they see fit.
function func1() {
alert('func1 code: ' + code);
}
function func2() {
alert('func2 code: ' + code);
}
Alternate Solution
Pass the code to the individual functions as seen in http://jsfiddle.net/dboots/dhd0dem7/1/.
function func1(code) {
alert('func1 code: ' + code);
}
function func2(code) {
alert('func2 code: ' + code);
}
$('#testId').click(function() {
code = $(this).attr('code');
func1(code);
func2(code);
});
you can bind your function to the value of this
func1.bind(this)();
func2.bind(this)();
this way when your function tries to access $(this) it will point to the same object as in the click event
Hi I'm pretty new to javascript looking for some help on creating an argument and adding it to a click event in jquery
Heres a demo: http://jsfiddle.net/zidski/8VwAy/1/
Can someone help example what I have to do?
Thanks
First: Do not use arguments as a variable name, since every function already defines the arguments object.
Your code does not work, because you have injected the JavaScript through the onload setting in JSFiddle. This runs code after the document has loaded.
In the body section, you're calling a function which is not defined yet.
What happens?
Definition:
window.onload = function () {
// Defines window.demo.Alert...
}; ...
window.demo.Alert();
Calling order:
window.demo.Alert(); // Error: 'demo' is not defined.
window.onload = ...
Change onload to nowrap (head) to get your code to work: http://jsfiddle.net/8VwAy/7/
You can actually pass data to the event handler as the first parameter
$(".js-link").click("myne", function(e) {
alert(e.data);
alert("Hello world");
});
fiddle here http://jsfiddle.net/8VwAy/8/