A few weeks ago I was painfully able to dynamically add buttons to an HTML DOM object that has its own .on('click'.. handler, and use e.stopPropgation to stop these new child elements from firing the event.
The weird thing I did was call a function without any parenthesis. I have no idea why I did this or why it works, or why it does not work when I do attach parenthesis. I want to know if I am doing something by fluke and not design (and now I will add comments to it).
It goes as such:
//Container is the parent element
// var buttons stores the buttons with class 'buttons'
$('.container').on('click', function(){
$(buttons).appendTo($(this)).fadeIn(500).find('.buttons').click(tableButton);
});
function tableButton(e){
e.stopPropagation();
//do stuff
}
I can't figure out why I wrote the call to tableButton with no arguements or why it works perfectly. I tried to change the syntax to
.find('.buttons').on('click', function(e){
tableButton(e);
});
but then it no longer works.
Any help appreciated!
It works because you're passing a function to the click handler rather than calling the function yourself (the ()) An example of that:
var testFunction = function(msg) {
alert(msg);
}
var functionCaller = function(functionToCall) {
functionToCall('hello!');
}
functionCaller(testFunction);
functionCaller passes the message argument to testFunction(), but we only pass testFunction to functionCaller (without arguments)
For the part which doesn't work, isn't the function name tableButton() instead of tableButtons()?
See http://jsfiddle.net/g2PAn/
You don't actually call it, you just declare it and the arguments it accepts. The click callback is called with an argument indeed, but not by you.
The problem probably comes from the fact that jQuery calls your function with the element clicked bound as this, you could call table button like this:
.find('.buttons').on('click', function(e){
tableButton.call(this, e);
});
Related
When I call editWorkout function for the first time, the variable 'workout' gets passed in the editWorkout2 function, but then, during the second time, when the same thing happens, but in this case 'workout' has new value, this value for some reason won't change in editWorkout2 function. How can I fix that?
function editWorkout(e, workout) {
e.stopImmediatePropagation();
saveBtn.addEventListener("click", function (e) {
console.log(workout);
editWorkout2(e, workout);
}.bind(this)
);
}
on each call of your editWorkout function, you're adding a new event listener to your "saveBtn" element with the same event type.
I recommend you read the usage notes of addEventListener.
So, the problem was as follows: because during the second call and all of the consecutive calls of the function editWorkout the event listener was going on top of the previous one, for some reason variable workout was not changing in that eventListener as a parameter. So I removed event listener in the editWorkout2 function, and everything started working fine
I need to execute code from 3 different places on my website when an event gets triggered. I've added 3x listeners but for some reason only the first listener gets called.
Here's the code I'm testing at the moment: JSFiddle
window.addEventListener('tompina_event', function (e) {
document.write("triggered 1");
});
window.addEventListener('tompina_event', function (e) {
document.write("triggered 2");
});
window.addEventListener('tompina_event', function (e) {
document.write("triggered 3");
});
var evt = new CustomEvent('tompina_event');
window.dispatchEvent(evt);
Result:
triggered 1
This is the result I was hoping for:
triggered 1triggered 2triggered 3
It works, but the document.write destroys the original page and thus the execution of other code.
Please rewrite so the result is set in an other way like alert("triggered 1") or console.log("triggered 1").
The problem is with document.write(). Each call is overriding the strings from the previous call, and it appears that only one is firing. Change to console.log(), or document.body.innerHTML += "" and you will see them all firing.
The write() method is mostly used for testing: If it is used after an HTML document is fully loaded, it will delete all existing HTML.
as soon as Notification instantiates onclick function fires but I want prevent this event before actual click occures on notification
var message = new Notification("RandomString");
message.onclick(alert("Random Message"))
Try this:
var message = new Notification("RandomString");
message.onclick = function(){alert("Random Message")};
I'm going to break this down a little bit to make it more clear what your code is doing.
message.onclick() will invoke the onclick property of message, which is probably currently null and therefore can't be called as a function.
Inside of the () you have alert("Random Message"), which is going to be called right then. This means that the value of that function call will be passed in to the onclick function call as a parameter. alert() doesn't return anything, so the alert fires, then you're left with this:
message.onclick('undefined')
What you wanted to do was make onclick a function and have it call the alert.
message.onclick = function() {
alert("Random Message")
};
Now you can fire that function by clicking the element it is attached to, or you can still fire it directly with message.onclick().
The best practice now is to use addEventListener rather than onclick. addEventListener will allow you to register multiple events of the same type.
message.addEventListener('click', function() {
alert("Random Message");
});
Another thing that newer programmers often don't realize is that you don't have to make the function while attaching it as the event listener. Here's an example using both methods:
function foo() {
alert("Random Message");
}
message.onclick = foo;
message.addEventListener('click', foo);
I have been teaching myself JavaScript over the last Month now, not super consistently since my work has been all over the place, when I get downtime my job is to work on extensions for our sales team.
Right now I don't have a specific issue that i can't solve, but I have a question that makes me think that there is something very different about functions in javascript that I am still missing.
Look at this code, and I will explain what confuses me about it:
function click(e) {
var selection = e.target.id;
}
document.addEventListener('DOMContentLoaded', function () {
var divs = document.querySelectorAll('div');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', click);
}
});
So, in this code, I understand what is going on except how the click(e) part. The 'e' is an event object correct? It is not clear to me how that got passed, and how it knows that 'e' means that. I assume I could replace the e with "foo" and it would work still, but exactly what is happening is not clear.
I am pretty sure it has to do with this line of code:
divs[i].addEventListener('click', click);
But I don't understand what is happening behind the scenes to make that happen the way it does.
Another example is this from the message passing at http://developer.chrome.com/extensions/messaging.html:
contentscript.js
================
chrome.extension.sendMessage({greeting: "hello"}, function(response) {
console.log(response.farewell);
});
background.html
===============
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
console.log(response.farewell);
});
});
'response' in this is not clear to me where it is coming from, much like 'e' in the other example. Any help demystifying how this works would be appreciated, I am open to learning, and I haven't found a good explanation about this.
The event object is passed through the function by the browser itself.
In case there is an event and a respective event handler is attached, the browser calls that event handler and passes an event object with some (more or less) relevant information about the event to the event handler.
So with respect to your first example:
First the function click( e ) is defined in a regular way.
Afterwards two event handlers are registered:
for the event DOMContentLoaded
for a click event on multiple <div> elements.
For the first handler an anonymous function is used.
document.addEventListener('DOMContentLoaded', function () {
// do stuff here
});
Here the event object is omitted as it is probably not needed.
In the second case the <div> elements all get the same event handler, namely click(e).
divs[i].addEventListener('click', click);
Here, however, the event object is captured as a parameter by the function as it is needed inside the function body.
In general in JavaScript you don't have to define all parameters either in the function declaration nor in the call of a function. You just define the parameters needed and they are applied in the order given. That's why in the first event handler's definition the parameter for the event object can be omitted without any errors.
The click function is invoked by the browser in response to a click event. The browser passes the appropriate event object as the first argument.
Also, you're correct that e can be anything. You can give the parameter any (legal) name you want.
In my javascript code ( which is too long , so i can`t put it here ), functions are calling more than once , like suppose :
$("#button").bind({ click : Call }); // bind the Call with button click event
function Call()
{
alert("This message shows me more than once when i clicked the button");
}
if this alert message shows me more than once it means function Call() is calling more than once. Can anybody guess or tell me what's going on in my code? (Please don't ask me for code)
Works for me: http://jsfiddle.net/aC8Bm/
I'm guessing that you are binding more than once somewhere.
Also, I'd recommend either returning false from the Call function, or stopping event propagation.
One more thing: avoid naming functions with an uppercase -- that's reserved for constructor functions by convention.
You're hooking the event handler to the button the number of times 'Call' is being called. Do you have this code in something like a template or partial file?
Instead of doing this inside any function:
$("#button").bind({ click : Call });
Place the following somewhere outside:
$("#button").live("click", Call);
It will bind once for all existing and ever added #button