Sorry if this may be deemed a slight duplicate, however I couldn't find an answer that helped me understand why myFunc() is firing on page load and not when I click el1 or el2. How can I make the following code behave as expected?
function myFunc(param){
//yadayada
}
el1.onclick = myFunc('string1');
el2.onclick = myFunc('string2');
Thanks.
document.getElementById('el1').onclick = function() { myFunc('string1'); };
document.getElementById('el2').onclick = function() { myFunc('string2'); };
You need to get the elements on the page first and then assign a function to them, otherwise the parser will execute them onload because it thinks that myFunc() is returning a value to be assigned to onclick as opposed to the actual function myFunc().
Related
I'm working on a plugin for Trumbowyg where I'm trying to store a function in a variable so it can be called later but also be over-writable without altering the included javascript file.
The problem is, the function is not being called when I try to call it.
Here is my relevant code:
init: function (trumbowyg) {
var plugins = trumbowyg.o.plugins;
...
if(!plugins.giphycrumbs.close_modal) {
plugins.giphycrumbs.close_modal = function() {
console.log('close modal');
$(plugins.giphycrumbs.modal_selector).modal('hide');
}
}
$(document).on('click', '.add_giphy', function() {
trumbowyg.execCmd('insertImage', $(this).attr('src'), false, true);
plugins.giphycrumbs.close_modal;
});
// If the plugin is a button
trumbowyg.addBtnDef('giphycrumbs', {
//this function is handled exactly the same way except it actually works
fn: plugins.giphycrumbs.open_modal
});
}
In my code above, you can see I am checking if plugins.giphycrumbs.close_modal is NOT set, and if thats true, I set it to a function which is supposed to close a modal.
In my click handler for .add_giphy, the insertImage code works, but plugins.giphycrumbs.close_modal is never executed (I don't get the console.log message embedded in the function)
If I do console.log(plugins.giphycrumbs.close_modal) the expected function is put into the console.
Why is the close_modal function not executed in my code?
Answer
Try adding parentheses to close_modal inside your click handler.
Explanation
It seems to me like you are not invoking (calling) this function.
In your click handler, there's this line plugins.giphycrumbs.close_modal;
In javascript, this is a reference to a property on the giphycrumbs object. Though it happens to be a function, it will not be invoked as such unless you use parentheses after it (and optionally give it some arguments).
Hope that helps! 👍
I'm facing a weird issue. The console.log() outside the onload function works, but the console.log() inside doesn't work... Would it mean that my page never fully loads ? I had a look at the developer tools of Chrome and it shows me that the page is loaded, so I don't really understand... (here is a screen of the devtool)
Here is my code:
console.log("hello1");
window.onload = function()
{
console.log("hello2");
};
(I'm using this in a WordPress website, but I don't think it changes anything)
Thanks in advance,
ArbreMojo.
Some other code is probably assigning another function value to the window.onload method, so it basically overrides your assignment.
Instead of window.onload = function you can do:
window.addEventListener('load', function() {
console.log('loaded')
})
which allows attaching an arbitrary number of handlers for that event. This ensures nothing can override your callback function.
See: EventTarget.addEventListener for more info.
I have a troublesome feature which probably has been answered somewhere before but i did some searching and brain totally froze. So i have this code:
function createTimeLink(){
var link = document.createElement('a');
link.id = "link_"+vooru_nr;
link.textContent = "VOOR "+vooru_nr;
link.onclick = timeHelper();
var headrow = document.getElementsByClassName("elem_"+vooru_nr);
headrow[0].textContent = "";
headrow[0].appendChild(link);
}
function timeHelper(){
console.log("clicked");
}
I create an element and try to give an onclick property to it. However if i call out function createTimeLink() in window.onload, "clicked" will be logged in the console but will not be logged each time i click the link again. How could i make it in a manner that if i click my link then something would happen? In future i would like to open a modal after clicking a link but currently it won't even display 'clicked' in console when clicking on the link.
you are setting link.onclick to the RESULT of a function call. Leave out the parentheses, and it will probably work:
link.onclick = timeHelper;
In JavaScript, functions are objects, so you can either call them (what you're usually doing with functions, that is what the parentheses do), or pass them around (in that case, you don't write parentheses!).
So these two are very different:
someFunction(); (runs the function, returns its result)
someFunction; (does not run the function)
#w3re correctly points out, that addEventListener is probably the cleanest approach. It does not change functionality here, but you may encounter examples later, where you would like to have more than one event listener.
If you haven't worked with addEventListener and its counterpart removeEventListener yet, i'd highly recommend it!
You're executing timeHelper() and assigning the result of that function to the onclick handler. On top of that, if you're working in JavaScript, the preferred method of adding events is the addEventListener() function.
So, change
link.onclick = timeHelper();
to
link.addEventListener("click", timeHelper);
This question already has answers here:
In JavaScript, does it make a difference if I call a function with parentheses?
(5 answers)
Closed 9 years ago.
Take the following code:
HTML
<button id="button>click me</button>
JS - VERSION 1
window.onload = init;
function init() {
console.log('init called');
var button = document.getElementById('button');
button.onclick = buttonClickHandler;
}
function buttonClickHandler() {
console.log('button clicked');
}
vs Same HTML
JS - VERSION 2
window.onload = init();
In both cases, 'init called' appears in the console "immediately", but in the second case, it is followed by an error stating button is null.
There are 2 things at play here. 1) In version 1, it waits for the DOM to load 2) in version 2, it's happening before the DOM is loaded, or so it seems.
My question. Please explain as clearly as possible what is happening in version 1 vs what is happening in version 2. What are the technical terms for what window.onload = init is vs what window.onload = init() is? Also please explain each versions behaviour. Why does 1 wait, but 2 doesn't?
The script needs to go before the button element e.g. in the head: http://jsfiddle.net/XMEjr/1/
Version 1 sets init function to be the one that's called on window.onload event. The function is not invoked on that line; it's just assigned (as a value) to a property.
Version 2 sets the result of init function to be the one that's called on window.onload event. It's the difference that () makes.
Apparently init function is called before onload is fired (to get that result and set it as onload handler). So the function starts, fails to find element by button id (as DOM is not ready yet), so getElementById returns null. Then trying to access onclick property of null stops it with an error.
in the second one you are assigning to onload the result of the call to init :)
It would be equivalent if you do:
window.onload="init()"
In this case you are assigning a String that gets evaluated upon DOM is ready.
If you do
window.onload=init
You are assigning a reference to a function. Then again, when DOM is ready, the function gets called
But if you do:
window.onload=init()
you could do
function init() { alert ("this is called before onload, dom is not ready, button doesnt exist"); return init2; }
function init2() { alert ("this is called on load, dom is ready, button and everything in the body is now created"); }
hope you get the point.
By the way, this case would be useful to do something like this:
window.onload=init()
function init() {
if (IS_IPHONE) return init_iphone;
if (IS_ANDROID) return init_android;
if (IS_WINDOWS) return init_not_supported;
}
so you select which init method to execute onload.
I'm working with a tabbed interface and have the following jQuery function set up to handle the click events of my tabs.
$(document).ready(function () {
$('a#foo').click(function() {
//content, various calls
return false;
});
});
The above is an example of one of my tabs, the others are also within the same document ready block. What I needed to do was make it so the currently selected tab could not be re-clicked and that in some other cases I could manually disable tabs if needed. I achieved this via the following:
$('a#play').unbind('click');
This works fine, and it certainly disables the tabs but the problem then becomes rebinding the click action that was once there. I achieved this via the bind function:
$('a#foo').bind('click', function() {
//the same content and calls as before
return false;
});
This also works fine, but it has become exceedingly cluttered as I have added tabs to my UI. The immediate solution appears to be to create the function as a variable and then pass it into the initial click creation and into the binding event. Like so:
var Foo = new function() {
//same content and calls as before
return false;
}
$('a#foo').click(Foo());
$('a#foo').bind(Foo());
This, for one reason or another, seems to be causing browser crashing issues. Is it not possible to pass a function as a var in this case or am I just doing it wrong? Alternatively, is there a better way to achieve the results I'm looking for? Thanks.
$('a#foo').click(Foo());
$('a#foo').bind(Foo());
The Foo gives you the function, but adding ()'s after it means you are calling the function instead of passing the function itself. Since you're calling the function, false ends up getting passed to click and bind, obviously not doing anything. Some of your other problems might result from the fact that you simulating switching to that tab twice (calling the event handler twice).
var Foo = function() {
//same content and calls as before
return false;
}
$('a#foo').click(Foo);
$('a#foo').bind(Foo);
^^ should do what you want.
Alternatively, is there a better way to achieve the results I'm looking for?
Currently all we really know about your design is that you are calling using a click event handler to switch tabs. That part is awesome, but we'll need more info to give you the deeper answer you really want. If you post the code inside Foo we should be able to help a bit more. :D
EDIT: credit to SLaks♦ for noticing the new in the function declaration that I missed. I'll add a little more detail to his explanation:
When you write var foo = new
function(...) { ... }, you're making a
function literal, then calling it as a
constructor.
It's equivalent to
var SomeClass = function(...) { ... };
var foo = new SomeClass;
without the SomeClass dummy variable.
The function() {} is an anonymous function as you would expect. new in javascript is a little more confusing. When you call a function and precede it with new, you are using that function to instantiate an instance of a class defined in the function. In JS, unlike most other languages, the entire definition of a class is in one constructor function, from which you set all the instance variables, like so:
Foo = function() {
this.a = "lala";
this.b = 5;
}
To make instance methods of the 'class', you use the prototype attribute. However I just realized I've gotten super off-topic. Read more on that here and here. :D
You need to remove new from the function definition and stop calling the function when using it.
When you write var foo = new function(...) { ... }, you're making a function literal, then calling it as a constructor.
It's equivalent to
var SomeClass = function(...) { ... };
var foo = new SomeClass;
without the SomeClass dummy variable.
You need to simply assign the function literal to the variable.
When you write .click(foo()), you're calling foo, and passing the result to click.
Unless foo returns a function, that's not what you want to do.
You need to pass foo itself by removing the parentheses.
So firstly, click accepts a function, but you call without the () as click runs the function when ready. By adding the () you call it straight up.
Secondly, bind takes a string (what event you are binding to) AND a function (as above)...
Use the following:
function Foo() {
//same content and calls as before
return false;
}
$('a#foo').click(Foo);
$('a#foo').bind('click', Foo);
Hope that helps :)
Try:
var foo = function() // not "new function", as this creates an object!
{
return false;
}
$("a#foo").click(foo); // not "Foo()", as you can't call an object!
As for a better way to achieve the result you're looking for, you could have a class on every tab, such as .tab. That way, you can just do:
$("a.tab").click(function() { return false; });
... without having to fluff around with a lot of ids.
Take a different approach, and do not unbind().
I assume the tabs are all in a common container. If so, just use the delegate()(docs) method to place a handler on the container.
Here's a generic code example:
$('#container').delegate('.tab:not(.selected)', 'click', function() {
$(this).addClass('selected')
.siblings('selected').removeClass('selected');
// rest of the tab code
});
This will only trigger clicks on .tab elements that do not have the .selected class. You'll need to modify for your specific code.
Adding the parenthesis calls the function, but if you wanted to make it cool and stuff, you could make it so that Foo returned the function to be bound.
function Foo(){
return function(){
//your onclick event handler here.
};
}
$('a#bar').bind(Foo())
This makes use of one on javascript's function programming aspects, closures, which is cool, but not as efficient as some of the other answers. You should do some research about closures, as they can be used to make some cool stuff.
http://www.javascriptkit.com/javatutors/closures.shtml