Passing argument to function I don't want to execute immediately - javascript

Sorry if my question seems naive (a bit of a newbie here), but I seem not to be able to get a simple answer to my question.
In JavaScript I try something like this
window.onload = init; *// ok, this assigns to the window load event a function that doesn't execute straight away*
// now I define my init()function
function init(){
// say...
alert('Noise!');
/* but here is my dillema...
Next say I want to assign to an button.onclick event a function that only executes when I click the button.
But (!here it is...!) I want to pass arguments to this function from here without causing to execute because it (obviously) has brackets.
Something like: */
var button = document.getElementById('button');
var promptInput = prompt("Name?");
button.onclick = printName(promtInput); // I only want to print name on button click
}
function printName(name){
alert(name);
}
So... OK, I know the example is stupid. Simply moving all prompt gathering inside printName() function and assign to button.onclick a bracketless printName function will solve the problem. I know. But, still. Is there a way to pass args to functions you don't want to execute immediately? Or it really is a rule (or 'by definition') you only use functions that await execution when you don't plan to pass args via it?
Or how do you best to this thing otherwise?
Thanks a lot!
Ty

button.onclick = function() {
printName(promptInput);
};

You can use Function.prototype.bind():
The bind() method creates a new function that, when called, has its
this keyword set to the provided value, with a given sequence of
arguments preceding any provided when the new function is called.
For example:
button.onclick = printName.bind(null, promtInput);

You could put the data that you would normally pass as an argument into some other holding location. You can either put it in a hidden HTML element, or you can use the sessionStorage API to keep it. So your code would look like this:
var button = document.getElementById('button');
var promptInput = prompt("Name?");
sessionStorage.setItem('MyName', promptInput);
button.onclick = printName; // I only want to print name on button click
}
function printName(){
alert(sessionStorage.getItem('MyName');
}

Related

Why is alert is working only for a single time when not in function?

document.querySelector('html').onclick = function() {
alert('Hy');
}
works each time I click on the webpage displaying a dialogue box.
but if I were to remove function declaration and instead write
document.querySelector('html').onclick = alert('Hey');
it works only for once.
I don't understand this because I am asking javascript to alert by Hey each time I click on the webpage but it does the same only for once.
What effect does function declaration having on this snippet of code?
You need to distinguish between a function and the result of calling a function. In the second case, you're running the alert function immediately, and then setting the onclick to its result (which isn't a function and doesn't do anything useful).
Because what this does:
document.querySelector("html").onclick = alert("Hey");
It runs the code alert("Hey"), then sets the onclick of the element to the return value of alert("hey"). This will only work as a proper event handler if alert("Hey") returns a function. It doesn't:
console.log(alert("Hey"));
So you need to attach a function or function reference like so:
document.body.onclick = () => alert("Hey");
<p>Click Me</p>
The above works and is only a small addition to your wanted syntax - we're using ES6 arrow functions for this.

Remove event listener from an element with parameters

I'd like to remove an event listener from an element but its function has to take a parameter and it seems to not work. I was trying to find a solution on internet but anyone seems to have the same problem as me.
The role of the function is to simply change the visibility of the element
It doesn't make much sense to remove the listener immediatly but it's only for the example.
function createHoverEqElts() {
slotElts.forEach(function(slot, i) {
if(existValueElts[i].value == "true") {
let infoElt = document.createElement('div');
infoElt.style.position = "relative";
infoElt.style.bottom = "71px";
slot.appendChild(infoElt);
slotListenersElts.push(infoElt);
slot.addEventListener('mouseover', _slotListener(infoElt));
slot.removeEventListener('mouseover', _slotListener(infoElt));
slot.addEventListener('mouseout', function() {
infoElt.style.visibility = "hidden";
});
}
});
}
let _slotListener = function(elt) {
return function() {
elt.style.visibility = "visible";
}
}
I think your problem is that you return a function for some reason. You should pass a function that does something. Try this.
let _slotListener = function(elt) {
elt.style.visibility = "visible";
}
And then do this. In this scenario, you can also pass null instead of this, try either one.
slot.addEventListener('mouseover', _slotListener.bind(this, infoElt));
Since your function returns an anonymous function, you lose its reference. removeEventListener needs the same occurrence to work properly.
In other words _slotListener(infoElt) == _slotListener(infoElt) will always return false, so removeEventListener('event', _slotListener(infoElt)) will never work.
Store the function returned by _slotListener() somewhere and use it back to remove the event. In your example, it could be in a variable. In a more complex example, it could be in an object with some kind of reference or in a property in the DOM element.
var callback = _slotListener(infoElt); // save reference
slot.addEventListener('mouseover', callback);
slot.removeEventListener('mouseover', callback);
The reason you cannot remove the event listener effectively is because the function that you are passing to addEventListener is not the same as the function that you are passing to removeEventListener. JavaScript cannot compare two functions that have the exact same contents and tell they are the same function. Every single time you call _slotlistener, it creates a new function that is not the same as functions that were previously returned by _slotlistener. Instead, the proper way to do this would be to assign the result of _slotlistener to a variable, and then pass that variable into addEventListener and removeEventListener. For example,
var myListenerFunc = _slotListener(elt);
slot.addEventListener("mouseover", myListenerFunc);
slot.removeEventListener("mouseover", myListenerFunc);

How to access function inside of function?

today my question is asking how I would access a function inside a function. So, for example, I have a button, and if I click it, it would alert. The thing is, if you have a function surrounding the function, the inside function with the alert would not alert.
Here's an example:
html:
<button onclick="doStuff()">Alert</button>
js:
function nothing() {
var doStuff = function() {
alert("This worked!")
}
}
so the doStuff() function would not work. Can someone help me find a way to access it?
#Joseph the Dreamer is ultimately correct, but if you were dead set on calling a function that's nested in another function you could use an OOP approach.
Create a javascript "class" object and scope your function to "this":
function Nothing() {
this.doStuff = function() {
alert("works");
}
}
Next you add an id to your button,
along with a click event listener
Then, inside your click event you can call doStuff within the Nothing "Class" function like this:
var object = new Nothing();
object.doStuff();
https://jsfiddle.net/me7fek5f/
You can't. That's because it's enclosed in a scope that you can't really access globally. The only way you can access it is to expose it somewhere outside nothing.
Is this a homework question?
You're probably asked to do something like this:
function nothing() {
var doStuff = function() {
alert("This worked!")
}
var yourButton = getYourButton();
attachClickListener(yourButton, doStuff);
The implementations of getYourButton and attachClickListener are left to the reader.

Alter an existing onClick function with Javascript

My query is regarding using Javascript to change the value of an onclick function that already exists on the page.
There's a button. This button has the following onclick function:
onclick="if (confirm('Yahdy Yahdy yah?')) { someFunction(); }; return false;"
I would like to change the onclick function using Javascript to just be as follows and or extract the someFunction(); and run that directly without having to go through the confirmation. As I understand it, you can't confirm a confirm through scripting, so my only option is to run someFunction(); directly. My question is, how do I access someFunction() directly as someFunction() contains randomly generated values each time the page loads.
onclick="someFunction();"
That's basically what I'd like, so I can then call onclick() directly. I'm happy to use vanilla or jQuery to go about this.
TLDR: I want to extract PART of the old onclick function and make a new onclick function with JUST that part.
You can do this:
var code = obj.onclick.toString();
That will give you the javascript code assigned to that click handler to which you can search through it, find what you're looking for and reassign the click handler to something else.
I have no idea if this is the best way to do it, but here's something that worked for me:
function nullConfirm() { return true;};
(function() {
var obj = document.getElementById("test");
var code = obj.onclick.toString();
code = code.replace("confirm(", "nullConfirm(");
var matches = code.match(/\{(.*)\}/);
if (matches) {
obj.onclick = function() {
eval(matches[1]);
}
}
})();

onclick function runs automatically

Using google apps script I'm having trouble running a js function which passes parameters. When I add the parameters it will always run the code when the page loads instead of when the button is clicked.
Direct from the HtmlService example, it is OK - it runs when the button is pressed...
document.getElementById('button1').onclick = doSomething;
But when I add a parameter to the call (and function) as below, it runs just once when the page loads (and not when the button is pressed)...
document.getElementById('button1').onclick = doSomething('with_this_parameter');
Any insight into this behaviour would be greatly appreciated... sorry if the answer is obvious!
When you say
document.getElementById('button1').onclick = doSomething('with_this_parameter');
This means call doSomething('with_this_parameter') and then assign the returned value to document.getElementById('button1').onclick. Hence that is why it gets called when code reaches that line. Whether the value is assignable to that property or not is another question, but that is why it gets called.
Use it like this
document.getElementById('button1').onclick = function(){
doSomething('with_this_parameter');
}
Reference: This solution was given by Mark Linus.
Do like this:
document.getElementById('button1').onclick = function(){
doSomething('with_this_parameter');
}
To assign a reference of function to some variable, you do:
var a = doSomething;
where doSomething is a function.
But when you have to pass parameters and assign that function
var a = doSomething(b);
this will cause trouble as while assigning the function to the variable, it gets called and not when it is intended to be called.
To overcome this, you can use arrow functions or simple function to call your own function with params.
var c = () => doSomething(d);
This actually is understood as var c = anonymous_function;
or
var c = function() {
doSomething(d);
}
Hence you can do:
document.getElementById('button1').onclick = () => doSomething('with_this_parameter');
I usually do clickHandlers like so:
// create button here or get button...
var button1 = document.getElementById('button1').setName('button1');
var clickHandler = app.createServerClickHandler('doSomething');
button.addClickHandler(clickHandler);
function doSomething(e){
var button1 = e.parameter.button1;
<do something with var button>
}
I'm not sure what parameter you are adding, but you need to add a callback element to pass it if it isn't passed by the button itself via a .setId/getId or .setTag/getTag. If it is from a textbox:
var textbox = app.createTextBox();
var button1 =
app.createButton.setName('button1');
var clickHandler =
app.createServerClickHandler('doSomething').addCallbackElement(textBox);
button1.addClickHandler(clickHandler);
Hope this helps!

Categories

Resources