Calling a Javascript only with the button class - javascript

I am new to Javascript and also new to this Website.
I have about 40 Buttons which are all in the class "foo".
I also have a Javascript function named "run".
How can I set the Javascript to run whenever one of the buttons in class "foo" is pressed without actually setting the button to run it?
Is this even Possible?

Yes. Here is an example using jQuery.
$('.foo').click(function() {
run();
});
OR, using plain old JavaScript (see the jsfiddle):
//generates a "NodeList" of all buttons
var foo = document.getElementsByTagName('button'),
//then, we turn it into an actual array
foo = Array.prototype.slice.call(foo);
foo.forEach(function(button) {
//check to see if that button has the class "foo"
if(button.classList.contains('foo')) {
button.onclick = function() {
return run();
};
}
});
function run() {
console.log('run');
}
You could use
getElementsByClassName
but the downside of that, is that the only version of IE in which it is supported is 9+ (including all other major browsers), which is fine, if that's what you decide to go with.

Live Demo
You can copy + paste this right into your code and should work perfectly.
var buttons = document.getElementsByClassName('foo');
for (var i = 0; i < buttons.length; i++) {
addEvent(buttons[i], 'click', run);
}
function addEvent(element, myEvent, fnc) {
return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false));
};

Without jQuery:
var foos = document.getElementsByClassName('foo');
for (var i=0; i<foos.length; i++) {
foos[i].onclick = function() { run() };
}
JSFiddle: http://jsfiddle.net/8AKeP/

There are 3 simple ways to accomplish this.
First, you can just use plain vanilla Javascript. No external libraries are required.
// Get all buttons
var buttons = document.getElementsByClassName('foo');
// Loop through the buttons
for(var i = 0; i < buttons.length; i++){
// Tell each button that when it is clicked, call the "run" function.
buttons[i].onclick = run;
}
Second, You can specify the onclick methods in your HTML. This is a bad approach as it forces you to define global methods (functions that are accessible from anywhere), and also ties your code with your markup, making it hard to change one without changing the other.
<!-- Old HTML -->
<button class="foo">Text</button>
<!-- New HTML -->
<button class="foo" onclick="run()">Text</button>
Lastly, You can include the very helpful jQuery library to handle it for you. jQuery provides an easy way to handle binding events, selecting elements, etc.:
// One line (deconstruction below)
// $(".foo") => Find me all elements with a class name of "foo"
// .on("click", => When those elements are clicked
// run); => Call the "run" method.
$(".foo").on("click", run);
The last approach, using jQuery has become the sort of de facto standard way of doing this.

Try this:
var run = function(){
//your function goes here
}
$(document).on('click', '.foo', run);

I would use jQuery, for example:
$('.foo').click(function(){
run();
});
it is simpler to program. However, without using jQuery:
var buttons = document.getElementsByClassName('foo');
function run(){
alert('hi');
}
for(var i = 0; i < elements.length; i++){
buttons[i].onclick = function() { run() };
}

Related

get this node value after added event listener by looping

Let's say I have several textareas, and I want to add event listener to each textarea. When I type inside a textarea, I need to console the value typed inside it. I just can't figure out how to refer "this" to each textarea called in looping when being added event listener. The code below results in "undefined" in the browser console. Maybe you can set it right. Appricated the help. Thank you very much.
window.addEventListener("load", function(){
var char_max_inputs = document.querySelectorAll('.char_max');
for (var i = 0; i < char_max_inputs.length; i++){
var max_char = char_max_inputs[i].getAttribute("max_char");
var counter_id = char_max_inputs[i].getAttribute("counter_id");
char_max_inputs[i].addEventListener("keyup", function(){count_char(counter_id, max_char);}, false);
}
});
function count_char(counter_id, max_char) {
console.log(this.value);
}
You can solve it like this by using Function.prototype.bind
window.addEventListener("load", function() {
var char_max_inputs = document.querySelectorAll('.char_max');
for (var i = 0; i < char_max_inputs.length; i++) {
var max_char = char_max_inputs[i].getAttribute("max_char");
var counter_id = char_max_inputs[i].getAttribute("counter_id");
char_max_inputs[i].addEventListener("keyup", count_char.bind(char_max_inputs[i], counter_id, max_char), false);
}
});
function count_char(counter_id, max_char) {
console.log(this.value);
}
<textarea class="char_max"></textarea>
<textarea class="char_max"></textarea>
<textarea class="char_max"></textarea>
this can be very confusing in JavaScript, if not read about properly. An excellent resource to understand it is here
UPDATE
As pointed out in the comments, the example using call and bind together was incomplete. Removing it.

JS onClick not working

Just don't know why this piece of code is not working: (onClick not working, click() is working (using console))
function click(ID)
{
if(cost[ID] <= currency[costID[ID]])
{
currency[costID[ID]] -= cost[ID];
currency[ID] += buyamout[ID];
document.getElementById(x[costID[ID]]).innerHTML = "<center>"+(Math.round(notyfication(currency[costID[ID]])*100)/100)+not+"</center>";
document.getElementById(x[gainID[ID]]).innerHTML = "<center>"+(Math.round(notyfication(currency[gainID[ID]])*100)/100)+not+"</center>";
}
}
...'<button onClick="click('+i+');">'+button+x[i]+'</button>'
this gives output <button onClick="click(0);">Make DNA</button>
and after clicking button nothing happens.
There could be a namespace conflict with your click. Use another name like button_click below
var i = 0;
var button = "Make ";
var x = [['DNA']]
document.writeln('<button onclick="button_click('+i+');" >'+(button+x[i])+'</button>');
function button_click(ID) { // notice the function name change
alert(ID);
}
Code below not working:
var i = 0;
var button = "Make ";
var x = [['DNA']]
document.writeln('<button onclick="click('+i+');" >'+(button+x[i])+'</button>');
function click(ID) { // the function name click may have been used already
alert(ID);
}
indeed onclick="click('+i+');" executes the javaScript code between the double brackets: click('+i+');: it calls the javaScript click() function, but this does not work if you declare function click() and someone else did that elsewhere in javaScript code.
if onClick is not working you can also use addEventListener will do the same job.
for e.g.
element.addEventListener('click', function() { /* do stuff here*/ }, false);
To answer your question you must do the following.
Change:
onClick="click(0)"
To:
onclick="click(0)"
That will most probably fix your problem.

My own javascript class and addeventlistener template not working

So here I am experimenting with native javascript. What I am trying to achieve, but failed to do is to create some sort of shortcut for scenarios where I want to add an event listener to a div class.
Here I am trying to say: If the user clicked on a class then show an alert.
Why doesnt my code work?
function click(red){
var source = document.getElementsByClassName(red);
for (i = 0; i < source.length; i++) {
source[i].addEventListener('click', err, false);
}
function err() {
var x = 0;
}
}
if (click('red')) {
alert('rrr');
}
http://jsfiddle.net/y66wh26k/3/
I would use document.querySelectorAll instead of document.getElementsByClassName because it is more versatile.
But the main issue is that your click function actually wasn't returning anything, so your if(click('red')) would never execute. As well, your callback for the event listener being added wasn't really doing anything. So what I've done is made a callback argument, then passed that to addEventListener.
function click(selector, callback){
var source = document.querySelectorAll(selector);
for (var i = source.length-1; i >= 0; --i) {
source[i].addEventListener('click', callback, false);
}
}
click('.red', function() {
alert('rrr');
});
<div class='red'>xxx</div>
<div class='red'>xxx</div>
<div class='red'>xxx</div>

Do I need multiple event listeners for multiple audio elements-JavaScript?

I'm writing a silly page where I have 5 audio elements named myAudio1 thru myAudio5, and I want to display hello/goodbye messages when each of these audios are played/ended.
My current (certainly not the best) approach is having a JavaScript snippet for each of my audio tags: (this is for the first one)
var aud1 = document.getElementById("myAudio1");
aud1.onplay = function() {
console.log("myAudio1 says hello");
};
aud1.onended = function() {
console.log("myAudio1 says goodbye");
};
so I have five of these snippets with their own identifiers, all the way to myAudio5.
Apparently it's a long and cumbersome approach, so I tried to simplify it and came up with this:
var audList = document.getElementsByTagName("audio");
console.log(audList.length);
for (var i = 0; i < audList.length; i++) {
audList[i].addEventListener("load", audCheck, false);
}
function audCheck(e) {
var aud = e.target;
var audID = e.target.id;
aud.onplay = function() {
console.log(audID+" says hello");
};
aud.onended = function() {
console.log(audID+" says goodbye");
};
}
For whatever reason it's not working (Help! http://jsfiddle.net/8176ccnk/); if it did, I would wonder if creating multiple event listeners is a necessity in these kind of scenarios, where the event handler itself sort of acts like an event listener. (I don't think having one event handler that handles all child audio DOM events at the parent DOM level works...)
In general, what's the best way of interacting with DOMs during these events?
There is no load event in the media events so your handler audCheck is not getting called.
You can directly add the start/stop/ended listeners
var audList = document.getElementsByTagName("audio");
console.log(audList.length); //prints out how many audio elements there are
for (var i = 0; i < audList.length; i++) {
audList[i].addEventListener("play", onPlay, false);
audList[i].addEventListener("ended", onEnded, false);
}
function onPlay(e) {
console.log(e.target.id + " says hello");
};
function onEnded(e) {
console.log(e.target.id + " says goodbye");
};
Demo: Fiddle

Jquery - binding click event to a variable

All,
I am really stuck/ confused at this point.
I have an array with 6 items in it. Each item in the array is dynamically filled with elements using jquery '.html' method. However, I cannot seem to be able to attach/ bind an event to this dynamically created variable.
As soon as the browser gets to the problem line (see the area labeled 'PROBLEM AREA'), I get a 'undefined' error, which is really confusing as all the previous code on the very same variable works just fine.
var eCreditSystem = document.getElementById("creditSystem");
var i = 0;
var eCreditT = new Array(6); // 6 members created which will be recycled
function createCreditTransaction () // func called when a transaction occurs, at the mo, attached to onclick()
{
if (i < 6)
{
eCreditT[i] = undefined; // to delete the existing data in the index of array
addElements (i);
} else
if (i > 5 || eCreditT[i] != undefined)
{
...
}
}
function addElements (arrayIndex) // func called from within the 'createCreditTransaction()' func
{
eCreditT[i] = $(document.createElement('div')).addClass("cCreditTransaction").appendTo(eCreditSystem);
$(eCreditT[i]).attr ('id', ('trans' + i));
$(eCreditT[i]).html ('<div class="cCreditContainer"><span class="cCreditsNo">-50</span> <img class="cCurrency" src="" alt="" /></div><span class="cCloseMsg">Click box to close.</span><div class="dots"></div><div class="dots"></div><div class="dots"></div>');
creditTransactionSlideOut (eCreditT[i], 666); // calling slideOut animation
console.log(eCreditT[i]); // this confirms that the variable is not undefined
/* ***** THE PROBLEM AREA ***** */
$(eCreditT[i]).on ('click', function () // if user clicks on the transaction box
{
creditTransactionSlideBackIn (eCreditT[i], 150); // slide back in animation
});
return i++;
}
Try this:
$(eCreditT[i]).bind('click', function() {
creditTransactionSlideBackIn(eCreditT[i], 150);
});
Edit: use ++i instead of i++ like this:
return ++i;
/*
or
i += 1;
return i;
*/
retrurn ++i performs the increment first then return i after the increment.
While return i++ return i then icrement it.
Try to add click event out of addElements() function and try once.
Nonsense create an element using JavaScript and then use jQuery function to transform it into a jQuery object. You can let jQuery create the element directly for you.
eCreditT[i] = $('<div>').addClass("cCreditTransaction").appendTo(eCreditSystem);
Also, since eCretitT[i] is already a jQuery element, no need to call the jQuery function again.
eCreditT[i].on('click', function () {
creditTransactionSlideBackIn(eCreditT[i], 150);
});
If you already tried on, bind, live and click methods, then maybe the called function is your problem. Try to put a console.log() or an alert() inside the function to make sure the click event is actually happening. If it happens then the function creditTransactionSlideBackIn() is your problem.
EDIT
The problem is when the event takes place, i is not the original variable anymore.
function addElements (arrayIndex)
{
eCreditT[i] = $('<div>').addClass("cCreditTransaction").appendTo(eCreditSystem);
eCreditT[i].attr ('id', ('trans' + i));
eCreditT[i].data ('id', i); // Store the id value to a data attribute
Then when you call the function you can refer to the data attribute instead of the i variable:
/* ***** THE PROBLEM AREA ***** */
eCreditT[i].on ('click', function () // if user clicks on the transaction box
{
creditTransactionSlideBackIn ($(this).data('id'), 150); // slide back in animation
});
return i++;
}
try to bind parent div and then use if($e.target).is('some')){}, it will act as .live, like this:
$(eCreditSystem).bind('click', function (e){
if($(e.target).is('.cCreditTransaction')) {
creditTransactionSlideBackIn ($(e.target), 150);
}
});
of course you'll need in a minute larger if for checking if clicked dom el is a child of .cCreditTransaction, like this:
if($(e.target).parents().is('.cCreditTransaction')){}
Try this:
$(eCreditT[i]).live('click', function() {
creditTransactionSlideBackIn(eCreditT[i], 150);
});

Categories