I am creating some divs dynamically and Im attaching onclick functions to them.
Is there any way to attach functions which take parameters in this way?
If I just create the div in html I can attach a function and it works perfectly. I can also attach simple functions without parameters dynamically and they work perfectly.
How could I attach this function which takes 'this' as a parameter to my div??
Would anyone have any suggestions???
onclick="playSound(this)"
function playSound(el){
var soundId = $(el).html();
if ( soundId == ('d')){
d.playclip()
}
else if ( soundId == ('a')){
a.playclip()
}
else if ( soundId == ('n')){
n.playclip()
}
I can attach a function like this and it works fine.
$(".myDiv").live("click", function(){
alert('hello');
});
Any help would be hugely appreciated!!!
Thanks!!
For this specific case you could use something like:
$(".myDiv").click(function(){
playSound(this);
});
If you refactor your code dropping el and using this in this way:
function playSound() {
var soundId = $(this).html();
if (soundId == ('d')) {
d.playclip()
} else if (soundId == ('a')) {
a.playclip()
} else if (soundId == ('n')) {
n.playclip()
}
}
You could use it directly.
$(".myDiv").click(playSound);
You can attach some data to your elements using $(el).data('some-key', 'some-value') and
$(".myDiv").live("click", function() {
alert($(this).data('some-key'));
})
In this way you can attach data to an element and make use of it later.
absolutely. It's called javascript's bind function:
playSound.bind(this, arg1, arg2, ...)
Another useful function that is similar is jquery's proxy function. This only keeps track of the scope though and doesn't allow you to send other parameters:
$.proxy(playSound, this)
Related
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);
});
I am a somewhat green programmer, and quite new to javascript/jquery, but I thought I understood javascript events. Apparently not. I am not able to get event listeners to work as I'd like.
Given javascript:
var Thing = {
//stuff
update: function() {
$.event.trigger({type:'stateUpdate', more:stuff});
}
};
var Room = {
//more stuff
updateHandler: function (e) {
//handle event here
}
};
If I do jquery:
$(document).on('stateUpdate', $Room.updateHandler);
then it works fine, but I can't do either
$(Room).on('stateUpdate', $Room.updateHandler);
or
Room.addEventListerner('stateUpdate', $Room.updateHandler);
The first does nothing, the second gives .addEventListerner is not a function error.
I've googled for hours and can't figure it out. I found something that said .addEventListener only works on objects that implement EventListener, something about handleEvent, and something about functions automatically implementing EventListener. Nothing on how to make an object implement it. Is there no way to add listeners to javascript objects that aren't functions? Am I going to have to create an event handler object, or use 'document' or 'window' and have it call handlers? That seems really ugly.
Should the objects be functions in the first place? Would that work? It seems the current opinion is that making everything functions is just trying to make javascript into something it isn't.
AFAIK there are no way to add a event listener to the plain object, as it is not placed inside DOM. Events are firing inside DOM, and bubbling so your event listener for custom object won't receive it.
There is a http://www.bobjs.com/ framework that can help you implement custom events.
In response to #Barmar (sort of) I believe I worked this out. Confirmation on if this is a a good alternative or not would be nice, though. Basically, I have to do a subscriber thing, right? Almost event/listener, but not quite.
var thing = {
callbacks: {},
regCallback: function (key, which) {
callbacks[key] = which;
},
remCallback: function (key) {
callbacks[key].delete;
}
update: function(e) {
for(var i = 0, len = callbacks.length; i < len;i++){
callbacks[i](e);
};
}
};
var Room = {
updateHandler: function () {
//handle stuff
},
subscribe: function (which, callback) {
which.regCallback('room', callback);
}
unsub: function (which) {
which.remCallback('room');
}
};
//wherever/whenever I need to get updates something like
Room.subscribe(thing, Room.updateHandler);
//unsub
Room.unsub(thing);
Second error is caused by typo: addEventListerner has extra r in it.
I have this code:
$('#email').keyup(function() {
if(true || false)) {
} else {
}
});
I need include this function also in blur event.
I've tried to create a jquery function but I could not. Somebody give me a light.
You can do this -
$('#email').on('keyup blur',function() {
http://api.jquery.com/on/
Use the on method to attach multiple events, which are specified in the first argument passed to the function.
$('#email').on('keyup blur', function() {
if(true || false) { //there was an extra ) here
} else {
}
});
Working Example http://jsfiddle.net/nv39M/
One thing to be aware of, the keyup event is going to fire prior to the blur event firing.
Make a separate function as follows
function funcName(){
//Your code
}
Now,use jQuery on
$("#email").on("keyup",funcName);
$("#email").on("blur",funcName);
For reference,check
http://api.jquery.com/on/
There are (at least) two ways you could achieve this.
Specify multiple, space separated events as the first argument:
$('#email').on('keyup blur',function() {
// your logic
});
Use a named function:
function yourFunction() {
// your logic
}
$('#email').on('keyup', yourFunction);
$('#email').on('blur', yourFunction);
Option 1 is probably the best choice assuming you don't want to use the function anywhere else, and that you want to bind the event handlers at the same time. If, however, you wanted to bind the blur event at a later point (perhaps in response to another event), or to a different element, then the named function method would be the best choice.
I have no control over when and how this element is added to the DOM. But when it does get added I would like to call a call a jQuery function on it. I am looking to match form[data-validate] elements then call a jQuery function I wrote: validate
A temporary solution I have come up with:
document.addEventListener('DOMNodeInserted', function(event) {
if (event.target.nodeName === 'FORM' && $(event.target).data('validate')) {
return $(event.target).validate();
}
}, false);
According to https://developer.mozilla.org/en-US/docs/DOM/Mutation_events this code will "profoundly degrades the performance of further DOM modifications to that document (making them 1.5 - 7 times slower!)" and the browser compatibility is rather poor.
Can anybody do better?
Try delegating the event..
$(document).on('DOMNodeInserted' , 'form' , function(event){
if (event.target.nodeName === 'FORM' && $(event.target).data('validate')) {
return $(event.target).validate();
}
return false;
});
This will make sure that the function will be called when a new form is created...
What is the best way to share one function between two different event handlers? I want the same outcome but some situation dependent variables will need to be defined within the function depending on which element was clicked.
I could hack a solution but want to know the best practice for such a scenario. Simple problem must have a simple answer.
EXAMPLE
var onMyEvent = function(e){
if(click triggered from 'a'){
//do that
}
if(click triggered from 'div'){
//do that
}
}
$('a').click(onMyEvent);
$('div').click(onMyEvent);
FIDDLE: http://jsfiddle.net/f6C92/
I guess there'd be several ways to achieve this, such as checking the e variable for target objects, etc, but for your scenario, the easiest and most readable would be using the is() function, to which you can pass any CSS selector to test if the object of interest matches it.
var onMyEvent = function(e){
if($(this).is('a')){
//do that
}
if($(this).is('div')){
//do that
}
}
$('a').click(onMyEvent);
$('div').click(onMyEvent);
There are those who would argue that the above takes an unnecessary round-trip to jQuery, when you could achieve the same by testing this.tagName == 'A', but I usually recommend to delegate these things to jQuery as well, for browser compatibility reasons.
Another neat way would be to pass the relevant information as event data:
var onMyEvent = function(e){
if(e.data.type == 'a'){
//do that
}
...
}
$('a').click({ type: 'a' }, onMyEvent);
$('div').click({ type: 'div' }, onMyEvent);
It depends how complicated the differences are, but I don't really like checking element type in the handler. I would probably do something like this:
function doSomething(...){
// do stuff
}
$('a').click(function(){
// set some variables and send them as parameters to doSomething
doSomething(...);
});
$('div').click(function(){
// set some variables and send them as parameters to doSomething
doSomething(...);
});
Where doSomething contains the common code.
The target property of the event will contain the element that was clicked. In this updated fiddle, I alert the id of the clicked element, using e.target.id.
This ought to do the trick:
var onMyEvent = function(e) {
if (this.tagName == "A") {
alert("a");
} else if (this.tagName == "DIV") {
alert("div");
}
}
var onMyEvent = function(e){
if(this.tagName == 'A'){
alert("a");
}
if(this.tagName == 'DIV'){
alert("div");
}
}
$('a').click(onMyEvent);
$('div').click(onMyEvent);
Even if this will work in my opinion it's better to set a different handler for each tag, and call the same function inside it, like kingjiv suggested