Better understanding JavaScript parameters - javascript

I don't understand some parts of JavaScript code regarding parameters. I found this example on W3schools:
<!DOCTYPE html>
<html>
<body>
<a id="myAnchor" href="http://w3schools.com/">Go to W3Schools.com</a>
<p>The preventDefault() method will prevent the link above from following the URL.</p>
<script>
document.getElementById("myAnchor").addEventListener("click", function(event){
event.preventDefault()
});
</script>
</body>
</html>
I am confused with event parameter inside function. This code works although event parameter didn't become an argument, that is, it doesn't have any value. How can this "empty" parameter be used with a method. Why this code works? I am new to JavaScript so any simple answer would be appreciate.

Slit,
The function which is being called on "click" event is a "call-back" function. Once the event "click" raises then the anonymous "call-back" function which is "function(event){" is being called immediately with 1 parameter which is "event". In order to determine the parameters which will the anonymous function called with you should refer to documentation.
After you find the parameters, you may use and work with them inside this function, for example add "event.preventDefault(); alert('test')" and nothing will happen when you click on element, only popup window with "test" will arise.
Don't hesitate to ask any questions so I can improve my answer.. Just tried to explain in high level.

This function is also known as a callback. A callback is when you pass one function as an argument to another.
Try testing this code and then click anywhere on the page:
window.addEventListener("click", click);
function click() {
console.log(arguments);
}
If you open the console you should see [MouseEvent]. The special arguments object returns all the arguments received by the function. The click function received only one argument MouseEvent because the window method addEventListener sends an event to the event handler.
Here's a similar example:
init("abc", logArgs); //--> "abc"
init("abc", logDog); //--> "dog"
function logArgs(x) {
console.log(x);
}
function logDog(x) {
console.log("dog");
}
function init(x, callback) {
callback(x);
}
The confusing part about your example is that you can send a function an anonymous function. An anonymous function is one that is not named. Using the above example, you could do this:
init("abc", function(y) { //the y parameter comes from the init function
console.log(y); //"abc"
});
function init(x, callback) {
callback(x); //send the first argument to the anonymous function
}

Related

Parameter's purpose

Im doing a project right now where certain elements of the page change depending on the mouse positioning and made some code basing myself off an explanation I saw in Mozilla. I understand most of it, but there is still one part that is bothering me, which is the function parameter. Throughout my learning of basic Javascript, I have never understood parameters despite the countless explanations. What does a parameter do? How does the page know its purpose? To give an example here is the code:
<!doctype html>
<html>
<head>
<title>Change</title>
</head>
<body>
<p id="hurb"></p>
<script>
document.addEventListener('mousemove', movee);
function movee(a) {
var eub = a.clientX;
document.getElementById("hurb").innerHTML = eub;
}
</script>
</body>
</html>
What does a do here? How does the page know what it does?
Can someone please explain this in a way that can be understandable for a beginner? All the other explanations in pages dont really help me out.
Thanks!
The parameter, as its name suggests, is something upon which usually the function's return value depends. Hence, your function can have a parameter that is not used throughout the function. Here is an example:
function foo() {
console.log("foo");
}
function bar(par1, par2, par3) {
console.log("bar");
}
foo(); // foo
bar(); // bar
bar(45,100); // bar
Note that however you call bar() it logs "bar", since the parameter is never used inside the function and hence never contributes to the return value of the function.
In your case, the function is an event handler function, i.e. is called when some event (mousemove in your case) is fired. When an event is fired, the browser passes an Event object (particularly a MouseEvent object in your case) to the event handler function. This event object is a typical JS object, with properties such as clientX, clientY, pageX, pageY, etc.... By defining your function with a parameter, that parameter is going to take the value of the Event object. To access the Event object's properties, you do not need to define a parameter for your function. Hence, this function:
function movee(a) {
var eub = a.clientX;
document.getElementById("hurb").innerHTML = eub;
}
and this one:
function movee() {
var a = event;
var eub = a.clientX;
document.getElementById("hurb").innerHTML = eub;
}
are typical of each other.
How does the page know its purpose?
The page doesn't. All the page does is that it executes your function. If it encounters the parameter, it uses its value. Otherwise, it just continues execution.

Javascript, addEventListener callback function executes immediately and only once? [duplicate]

This question already has answers here:
addEventListener calls the function without me even asking it to
(5 answers)
Closed last month.
I've noticed a difference between function and function() for addEventListener's callback.
Which isn't a problem till I tried passing a parameter. Basically,
element.addEventListener("hover", logInput, false );
function logInput(){
console.log('registered!');
}
works as intended, but adding parenthesis will cause it log immediately, without continual response to the event trigger:
element.addEventListener("hover", logInput(), false );
function logInput(){
console.log('registered!');
}
Why is this? And how can I get it to work while passing a parameter such as:
element.addEventListener("hover", logOnInput(this), false );
function logOnInput(triggeredElement){
console.log(triggeredElement);
}
(If you really want the triggered element, don't pass anything. this will automatically be set to the triggered element.)
element.addEventListener("hover", logOnInput, false);
function logOnInput(){
console.log(this);
}
To answer your more general question...
There are a few ways to pass a function as an argument with certain arguments already set (this is referred to as "partial application"). If you are able to use modern JavaScript features, the simplest way is probably to use an arrow function.
element.addEventListener("hover", () => logOnInput(foo), false);
function logOnInput(message){
console.log(message);
}
This will only work on very modern browsers. It won't work, for example, in IE 11. In order to support older browsers, you can use the longer form of a function expression.
element.addEventListener("hover", function() {logOnInput(foo);}, false);
function logOnInput(message){
console.log(message);
}
Or you could define a separate function (won't work with this but will work with other variables).
element.addEventListener("hover", logFooOnInput, false);
function logOnInput(triggeredElement){
console.log(triggeredElement);
}
function logFooOnInput() {
logOnInput(foo);
}
Or you could use bind.
element.addEventListener("hover", logOnInput.bind(null, foo), false);
function logOnInput(message){
console.log(message);
}
Its a javascript when you want to call a function you use parentheses. Without parentheses outside a function is useless. But inside a function as argument you use the function without the parentheses so that when that event occurs then only it would run. If you call a function using parentheses inside function argument it will be executed immediately and would also run when the event occurs. To call a function with its parameters inside a function and just to invoke in that event you need to use the bind method like below:
element.addEventListener("hover", logOnInput.bind(null, argument1, argument2, etc), false );
However, if you want to select the context as this then I would recommend you to use like this:
function logOnInput(elem,arguments) {
//now you can use **elem** to refer **this**
}
And use the anonymous function for the hover event like this:
element.addEventListener("hover", function(){
logOnInput(this,arguments)
}, false );
The bind function is probably the cleanest option if you are targeting on modern browsers only. Some blogs talk about the loss of performance comparing bind with anonymous functions. Some blogs talk bad about anonymous functions.
On the anonymous function. All goes well passing arguments on the addEventListener. But when you get to removeEventListener passing the arguments won't work the same way as in the addEventListener.
I found this dude, in 2005, with the answer:
http://www.codingforums.com/dom-and-json-scripting/5909-how-pass-arguments-independently-using-addeventlistener.html
In resume, set your anonymous function to be equal to a newly declared "thing". Idk if this is a var or an expression. I tested var and it wont' work. Idk the technicalities of this at this point, but it works.
function addhoverIn(SELECTED) {
SELECTED.addEventListener("mouseover", addHIn = function() { hoverIn(SELECTED); }, false);
}
function hoverIn(SELECTED) {
SELECTED.removeEventListener("mouseover", addHIn, false);
}

jQuery .click() function called automatically

I have an event listener set up on a button using jQuery, and for some reason the function within the click listener is called without the button being clicked. I know that usually functions are anonymous in listeners, but it won't work as an anonymous function. The function I am calling also has to accept parameters, which is why I don't think I can just call a reference to the function. Any ideas on how I can fix the problem of the function getting called without a click even registered and still pass the necessary parameters to the function?
$('#keep-both').click(keepBothFiles(file, progress, audioSrc));
calls this function
function keepBothFiles(file, progress, audioSrc) {
...
...
}
You're referencing the function incorrectly. Try this instead:
$('#keep-both').click(function(){
keepBothFiles(file, progress, audioSrc);
});
Whenever you use the syntax funcName(), the () tell the interpreter to immediately invoke the function. The .click method requires that you pass it a reference to a function. Function references are passed by name only. You could also do:
$('#keep-both').click(keepBothFiles);
But you can't pass it your other arguments. It's given an event object by default
You must pass a function reference to the .click() function, not the result of calling a function. When you include the () like this keepBothFiles(...) at the end of the function name, you are telling javascript to execute the function now. When you just use the name of the function like keepBothFiles, you are getting a reference to the function (which can be called later).
You are currently calling your function immediately and then passing the return value of that function (which is not a function reference) to the .click() function, thus it does not do what you want.
The click handler callback function is passed exactly one parameter (the event) in jQuery so you cannot have it call your keepBothFiles(file, progress, audioSrc) function directly like you have it.
Instead, it could be done like this with a second wrapper function:
$('#keep-both').click(function(e) {
keepBothFiles(file, progress, audioSrc);
});

Capturing events in javascript

<!doctype html>
<html>
<body>
<div id = 'div' style = 'width:100px;height:100px;background:#000000;'></div>
<script type = 'text/javascript'>
document.getElementById('div').addEventListener('click',happen(),true);
function happen()
{
alert(1)
}
</script>
</body>
</html>
In the above code why the event is triggered when the page loads and not triggered when i click on the div...Also which is the correct event name click or onclick....
It's because you've immediately called the function, and passed its null result to addEventListener().
It should be:
document.getElementById('div').addEventListener('click',happen,true);
If you want to pass arguments to happen, you'd have to write this:
document.getElementById('div').addEventListener('click', function() {
happen(args_here, ...);
}, true);
You're calling the function immediately and passing its return value to addEventListener, just like any other function call.
Take out the ().
This should work:
document.getElementById('div').addEventListener('click',happen,true);
The problem is with this line:
document.getElementById('div').addEventListener('click',happen(),true);
You should should only be passing the name of the function happen but since you added the parentheses, you are passing the result.
Try this instead:
document.getElementById('div').addEventListener('click',happen,true);
As the other answerers have said, taking out the () will fix the problem.
An alternative, and a good practice for OO Javascript, is to wrap the function inside a function(){ }, like so:
document.getElementById('div').addEventListener('click',function(){happen()},true);
That will retain scope if the callback needs to execute within an object (in this case it does not).
The event handler does not need parenthesis
document.getElementById('div1').addEventListener('click',happen,true);

Can a click handler be an object?

I'm trying to register on +1 clicks from within my module, which is wrapped as an annonymous function.
For this end, I created a global object MyModule, and exported my click handler function through it. The problem is - my click handler doesn't get called.
Live demo. Code:
// Initialize +1 button
gapi.plusone.go();
(function(){
window.MyModule = {};
function plusOneClicked() {
alert("+1!");
}
window.MyModule.plusOneClicked = plusOneClicked;
})()
...
<g:plusone callback='window.MyModule.plusOneClicked'></g:plusone>
When I give as a callback an external function, whose only purpose is to forward the calls to window.MyModule.plusOneClicked, it works:
function foo() {
window.MyModule.plusOneClicked();
}
...
<g:plusone callback='foo'></g:plusone>
Why would the click handler miss window.MyModule.plusOneClicked(), but find foo()?
Google is probably writing
window[callback]();
in their code.
This requires that the callback string refer to a property of window, not a property of another object.
I believe because callback expects a direct handler method (as in foo()) rather than a reference (as in window.MyModule.plusOneClicked). So basically, you cannot simply assign such a reference to click handler, but write a (wrapper) method as the handler and have it perform the necessary invocation.

Categories

Resources