I have multiple buttons (generated by php) for a shopping cart application:
<button class="addtocart" id="<?php echo $code; ?>">
<span id="addtocartbutton">Add to cart</span>
</button>
I want to update my cart using a function:
function AddtoCart() {
alert("Added!");
}
Later, I want to find the id ($code) created by the button which called it (not sure how to do that also, but maybe that's another question). And so I tried this:
document.getElementsByClassName("addtocart").addEventListener("click", AddtoCart());
But it doesn't work. It was working using an onclick, but I understand that the right way to do it by creating an EventListener. Also, I cannot use the on() function in jQuery, because I am forced to use jQuery Version 1.6 which does not have it.
I have looked at https://stackoverflow.com/a/25387857/989468 and I can't really assign it to the parent which is a p tag, because I obviously don't want the other elements in the p tag to be assigned this function.
While the answers given are correct, there is another way: Event Delegation
Attach the listener to a SINGLE thing, in this case the document body and then check to see what element was actually clicked on:
Warning: Typed on the fly: Untested
// Only needed *once* and items may be added or removed on the fly without
// having to add/remove event listeners.
document.body.addEventListener("click", addtoCart);
function addtoCart(event) {
var target = event.target;
while(target) {
if (target.classList.contains('addtocart')) {
break;
}
// Note: May want parentElement here instead.
target = target.parentNode;
}
if (!target) {
return;
}
var id = target.dataset.id;
alert(id + " added!");
}
You should attach click event to every element with class addtocart, since getElementsByClassName() return an array of all objects with given class name so you could use for to loop through everyone of them and associate it with function you want to trigger on click (in my example this function called my_function), check example bellow :
var class_names= document.getElementsByClassName("addtocart");
for (var i = 0; i < class_names.length; i++) {
class_names[i].addEventListener('click', my_function, false);
}
Hope this helps.
function my_function() {
alert(this.id);
};
var class_names= document.getElementsByClassName("addtocart");
for (var i = 0; i < class_names.length; i++) {
class_names[i].addEventListener('click', my_function, false);
}
<button class="addtocart" id="id_1">button 1</button>
<button class="addtocart" id="id_2">button 2</button>
<button class="addtocart" id="id_3">button 3</button>
<button class="addtocart" id="id_3">button 4</button>
I'll show some of the errors you had in your code, then I'll show you how can you improve it so that you can achieve what you want, and I also show that it works with buttons dynamically added later:
First and foremost, you need to pass the function reference (it's name) to the addEventListener! You have called the function, and passed whatever it returned. Instead of:
document.getElementsByClassName("addtocart").addEventListener("click", AddtoCart());
It should've been:
document.getElementsByClassName("addtocart").addEventListener("click", AddtoCart);
Second: document.getElementsByClassName("addtocart") returns a NodeList, you can't operate on it, you need to operate on it's elements: document.getElementsByClassName("addtocart")[0], [1],....
Third, I would suggest you to use the data-... html attribute:
<button class="addtocart" id="addtocart" data-foo="<? echo $code; ?>">
This way you can pass even more data. Now you can get the $code as:
document.getElementById('addtocart').dataset.foo
// el: the button element
function AddtoCart(el) {
// this is the id:
var id = el.id;
// and this is an example data attribute. You can have as many as you wish:
var foo = el.dataset.foo;
alert(id + " (" + foo + ") added!");
}
// Try add a div or something around the area where all the buttons
// will be placed. Even those that will be added dynamically.
// This optimizes it a lib, as every click inside that div will trigger
// onButtonClick()
document.getElementById("buttons").addEventListener("click", onButtonClick);
// this shows that even works when you dynamically add a button later
document.getElementById('add').onclick = addButton;
function addButton() {
var s = document.createElement("span");
s.text = "Add to cart";
var b = document.createElement("button");
b.innerHTML = 'Third <span class="addtocartbutton">Add to cart</span>';
b.className = "addtocart";
b.id="third";
b.dataset.foo="trio";
// note the new button has the same html structure, class
// and it's added under #buttons div!
document.getElementById("buttons").appendChild(b);
}
// this will gett triggered on every click on #buttons
function onButtonClick(event) {
var el = event.target;
if (el && el.parentNode && el.parentNode.classList.contains('addtocart')) {
// call your original handler and pass the button that has the
// id and the other datasets
AddtoCart(el.parentNode);
}
}
<div id="buttons">
<button class="addtocart" id="first" data-foo="uno">First <span class="addtocartbutton">Add to cart</span></button>
<button class="addtocart" id="second" data-foo="duo">Second <span class="addtocartbutton">Add to cart</span></button>
</div>
<button id="add">Add new button</button>
<html>
<head>
<script>
window.onload=function{
var btn = document.getElementsByName("addtocartbtn")[0];
btn.addEventListener("click", AddtoCart());
}
function AddtoCart() {
alert("Added!");
}
</script>
</head>
<body >
<button class="addtocart" name ="addtocartbtn" id="<?php echo $code; ?>" > <span id="addtocartbutton">Add to cart</span></button>
</body>
</html>
Actually class in Javascript is for multiple selection you should provide index like an array.
<button class="addtocart"> <span id="addtocartbutton">Add to cart</span></button>
<script type="text/javascript">
document.getElementsByClassName("addtocart")[0].addEventListener("click", AddtoCart);
function AddtoCart() {
alert("Added!");
}
</script>
Also your second parameter was wrong don't use parentheses.
Applying parentheses means it will call the function automatically when loaded, and will not call the function after that.
Related
Sorry in advance if my code is really bad but I am just a beginner. I would like to create a word search puzzle using buttons. When the person is finished finding by clicking on all of the words which I am going to make from buttons I want a message to come up that they have completed the puzzle. So I created a sample here with 4 buttons but I can't seem to get my code to work. I want the message to come up in the div container once all the buttons have been clicked on. Am I on the right track here or way off? Any insight would be so much appreciated!
<html>
<p onclick="myFunction()" id="1" value=false >Button1</p>
<p onclick="myFunction()" id="2" value=false >Button2</p>
<p onclick="myFunction()" id="3" value=false >Button3</p>
<p onclick="myFunction()" id="4" value=false >Button4</p>
<div id="demo">Message displays here if all 4 buttons are clicked</div>
<script>
function myFunction(){
value = true;}
if(p 1){
value = true;}
if(p 2){
value = true;}
if(p 3){
value = true;}
if(p 4){
value = true;}
else{
document.getElementById("demo").innerHTML = "Congratulations you clicked on all of the buttons";}
}
</script>
</html>
You could use the buttons' data attributes to hold their state. (Note: for a more complex project, you probably don't want to do this)
Also, putting JS inline like onclick="myfunction()" is somewhat bad for your code - it encourages globals and makes JS logic harder to follow. So, I've shown an alternative using an IIFE, .querySelectorAll(), and .addEventListener():
// IIFE to keep variables out of the global scope
;(() => {
// NOTE: These are more flexible when they are arrays (thus, Array.from())
const btnEls = Array.from(document.querySelectorAll('.js-button'))
const msgEls = Array.from(document.querySelectorAll('.js-message'))
const handleButtonClick = ({ target: btnEl }) => {
btnEl.disabled = true // optional
btnEl.dataset.toggled = 'true' // using the DOM to hold data
if (btnEls.some(el => el.dataset.toggled !== 'true')) return
msgEls.forEach(el => {
el.textContent = 'Congratulations you clicked on all of the buttons'
})
}
// Our "onclick" equivalent
btnEls.forEach(el => el.addEventListener('click', handleButtonClick))
})()
<button class="js-button">Button1</button>
<button class="js-button">Button2</button>
<button class="js-button">Button3</button>
<button class="js-button">Button4</button>
<p class="js-message">Message displays here if all 4 buttons are clicked</p>
...There's probably a lot of syntax there you don't know but that example should be helpful for those learning from a more modern source. Since you're learning from something that uses older JS syntax, here's some older JS code that works about the same (but isn't as easy to maintain):
// IIFE to keep variables out of the global scope
;(function () {
// NOTE: These are more flexible when they are arrays (thus, Array.from())
var btnEls = Array.from(document.querySelectorAll('.js-button'))
var msgEls = Array.from(document.querySelectorAll('.js-message'))
function handleButtonClick(event) {
var btnEl = event.target
btnEl.disabled = true // optional
btnEl.dataset.toggled = 'true' // using the DOM to hold data
if (btnEls.some(function (el) {
return el.dataset.toggled !== 'true'
})) return
msgEls.forEach(function (el) {
el.textContent = 'Congratulations you clicked on all of the buttons'
})
}
// Our "onclick" equivalent
btnEls.forEach(function (el) {
el.addEventListener('click', handleButtonClick)
})
})()
<button class="js-button">Button1</button>
<button class="js-button">Button2</button>
<button class="js-button">Button3</button>
<button class="js-button">Button4</button>
<p class="js-message">Message displays here if all 4 buttons are clicked</p>
Here was my solution.
var set = []; //decalre an empty array
function myFunction(Id) {
console.log(Id); //the Id will be the vlaue from the button. For example button 1 has an Id of one as passed into by 'myFunction(1)
if (set.indexOf(Id) == -1) { //here we check to see if the Id number is in the array
set.push(Id); //if it's not in the array, we add it in
console.log(set);
console.log("length: " + set.length);
if (set.length > 3) { //if the lengthof the array is greater than three, all 4 buttons have been clicked.
document.getElementById("demo").innerHTML = "Congratulations you clicked on all of the buttons";
}
}
}
<p onclick="myFunction(0)">Button0</p>
<p onclick="myFunction(1)">Button1</p>
<p onclick="myFunction(2)">Button2</p>
<p onclick="myFunction(3)">Button3</p>
<div id="demo">Message displays here if all 4 buttons are clicked</div>
An easier way of doing this is with an event listener that listens to each button click, then makes the value of that button true, and then checks all the buttons to see if they are all clicked and if so output the congrats message
HTML
added classes to each button and removed the onclick function
<html>
<p class='button' id="1" value=false >Button1</p>
<p class='button' id="2" value=false >Button2</p>
<p class='button' id="3" value=false >Button3</p>
<p class='button' id="4" value=false>Button4</p>
<div id="demo">Message displays here if all 4 buttons are clicked</div>
</html>
JS
window.addEventListener('click', (e)=>{
var bool = true
if (e.target.classList.contains('button')) {
e.target.setAttribute('value', "true")
}
buttons = document.querySelectorAll('.button')
for (let i = 0; i < buttons.length; i++) {
console.log(buttons[i].getAttribute('value'))
if (buttons[i].getAttribute('value') == "false") {
bool = false
}
}
if (bool == true) {
document.getElementById("demo").innerHTML = "Congratulations you clicked on all of the buttons";
}
})
I would suggest this as an easy answer to understand javascript and html a little better:
HTML
<html>
<body>
<button onclick="myFunction(event)" name="button1">Button1</button>
<button onclick="myFunction(event)" name="button2">Button2</button>
<button onclick="myFunction(event)" name="button3">Button3</button>
<button onclick="myFunction(event)" name="button4">Button4</button>
<div id="demo">Message displays here if all 4 buttons are clicked</div>
</body>
</html>
JS
var foundButtons = {
button1: false,
button2: false,
button3: false,
button4: false,
};
function myFunction(event) {
foundButtons[event.target.name] = true;
for (var button in foundButtons) {
if (foundButtons.hasOwnProperty(button)) {
if (!foundButtons[button]) {
return
}
}
}
document.getElementById("demo").innerHTML = "Congratulations you clicked on all of the buttons";
}
What this does is that you have an object of the buttons or rather the words that must be clicked to show the message. Now when one of the buttons gets clicked, its property gets set to true. Then it iterates over the properties and ends the function with a return statement, if it finds a false value, which means there is a button that has not been clicked. When the function does not get stopped it will show the success message.
Is there a way to dynamically remove elements with javascript or jquery. Suppose I have a function createElements() which creates new element and another function removeElement() which is suppose to remove the corresponding element. You will notice that when you run the snippet that when you click on the remove button all the element is gone! How could I implement this code? Isn't there a jquery selector where i could simply use removeElement(this) or somenething like that? Any suggestions are most welcome :) thank you.
function createElements() {
const boom = document.getElementById('boom');
boom.insertAdjacentHTML(
'beforeend', '<div class="newElem"><p >new element created dynamically yay!</p><button onclick="removeElement()">remove</button></div>'
);
}
function removeElement() {
alert('element removed dynamically boOoOoOoOooo!')
$('.newElem').remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="boom">
</div>
<br>
<button onclick="createElements()">Create new element</button>
You can do it like this:
function createElements() {
const boom = document.getElementById('boom');
boom.insertAdjacentHTML(
'beforeend', '<div class="newElem"><p >new element created dynamically yay!</p><button onclick="removeElement(this)">remove</button></div>'
);
}
function removeElement(element) {
alert('element removed dynamically boOoOoOoOooo!')
$(element).parent(".newElem").remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="boom">
</div>
<br>
<button onclick="createElements()">Create new element</button>
You just need to follow one single API. Use either pure JavaScript or jQuery. I would also suggest you to use unobstructive approach. Also, the way you remove the elements is wrong. You are removing everything.
See this way:
$(function() {
$("button#add").click(function() {
$("#boom").after('<div class="newElem"><p >new element created dynamically yay!</p><button class="remove">remove</button></div>');
});
$(document).on("click", ".remove", function() {
alert('element removed dynamically boOoOoOoOooo!')
$(this).closest(".newElem").remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="boom">
</div>
<button id="add">Create new element</button>
To be able to always delete the div that encompasses the remove button, you have to traverse the DOM tree. There are lots of jQuery goodies for this: http://api.jquery.com/category/traversing/
In this particular case, I would do the following:
var elementCounter = 0;
function createElements() {
const boom = document.getElementById('boom');
boom.insertAdjacentHTML(
'beforeend', '<div class="newElem"><p >'+elementCounter+': new element created dynamically yay!</p><button onclick="removeElement(event)">remove</button></div>'
);
elementCounter++;
}
function removeElement(event) {
alert('element removed dynamically boOoOoOoOooo!')
$(event.target).closest('.newElem').remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="boom">
</div>
<br>
<button onclick="createElements()">Create new element</button>
So you pass on the click event to the function as a parameter, and then with event.target you find out which button was clicked. $(event.target).closest(".newElem") will get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
I am learning Javascript and I'm trying to clean up my code. The code is pretty simple: it simply changes the color of some text by clicking some different buttons. When you click the red button the text turns red, the blue button the text turns blue, etc. Here is the code:
HTML:
<h1 id="title">Change my color!</h1>
<button id="btn" onclick="colorRed()">Red</button>
<button id="btn" onclick="colorGreen()">Green</button>
<button id="btn" onclick="colorBlue()">Blue</button>
<button id="btn" onclick="colorBlack()">Black</button>
Javascript:
var title = document.getElementById("title");
function colorRed() {
title.style.color = "red";
}
function colorGreen() {
title.style.color = "green";
}
function colorBlue() {
title.style.color = "blue";
}
function colorBlack() {
title.style.color = "black";
}
This code works. My question is how do I clean up my Javascript; in a case where I would've had 20 buttons, coding 20 different functions would obviously not be the way to go.
I did try the following for every single color, but that didn't work:
Javascript:
var title = document.getElementById("title");
var btn = document.getElementById("btn");
function changeColor() {
if(btn.innerHTML == "Red") {
title.style.color = "red";
} else if ...
}
I think it goes wrong when I try to identify which button has been clicked by seeing if their inner HTML is equal to a certain color, but I'm not sure how to fix that. Help would be much appreciated!
EDIT: My question isn't a duplicate of Change an element's background color when clicking a different element as the code I wrote works already, and I just want to learn how to clean it up.
Might be easiest to just make one changeColor function and pass it a color in the event:
var title = document.getElementById("title");
function changeColor(color) {
console.log(color);
title.style.color = color;
}
<h1 id="title">Change my color!</h1>
<button class="btn" onclick="changeColor('red')">Red</button>
<button class="btn" onclick="changeColor('green')">Green</button>
<button class="btn" onclick="changeColor('blue')">Blue</button>
<button class="btn" onclick="changeColor('black')">Black</button>
Side note: you really shouldn't repeat id's and should use class instead.
It is generally not advisable to use inline event handlers, use addEventListener instead. Rather than adding an event listener for each element, I would recommend adding a common parent element, attaching one event listener to that and inspect the event ("event delegation") to determine which color to apply:
var title = document.querySelector('#title');
document.querySelector('#button-container').addEventListener('click', function(event) {
var color = event.target.getAttribute('data-color')
title.style.color = color;
}, false)
<h1 id="title">Change my color!</h1>
<div id="button-container">
<button data-color="red">Red</button>
<button data-color="green">Green</button>
<button data-color="blue">Blue</button>
<button data-color="black">Black</button>
</div>
Don't use inline HTML event attributes, such as onclick. There are a variety of reasons why and if you are just starting with JavaScript, you don't want to pick up any bad habits. Instead, keep your JavaScript completely separate from your HTML and follow modern standards using the .addEventListener() JavaScript method for setting up event handlers.
Also, id values must be unique within a document (the whole point of them is to uniquely identify elements). To be able to group just the buttons that relate to this operation, you can give them all the same CSS class and then query on that class in JavaScript (shown below).
Next, you only need one function, but if your individual buttons were storing the color they should produce, that one function could extract it and use it without the need for any arguments to be passed to your function:
var title = document.getElementById("title");
// When you query your document for groups of matching elements (using methods
// like: getElementsByTagName or getElementsByClassName) you get back an object
// that is similar to an array, called a "node list". Although these "array-like"
// objects support some of the standard array object's features, they are not
// true arrays and don't implement many of the powerful array methods out there.
// But, we can convert the node list returned from .querySelectorAll into an array
// and then we can iterate the array with .forEach() looping method later.
var buttonArray = Array.prototype.slice.call(document.querySelectorAll(".colorBtn"));
// Loop through the button array (the function provided as an argument will be
// executed for each element in the array)
buttonArray.forEach(function(button){
// Set up click event handlers for each button
button.addEventListener("click", function(){
// Just set the color to the "data-color" attribute value on the element
title.style.color = button.dataset.color;
})
});
.colorBtn {
box-shadow:2px 2px 1px grey;
border-radius:4px;
width:100px;
display:inline-block;
margin:4px;
}
.colorBtn:hover, .colorBtn:active {
box-shadow:-2px -2px 1px #e0e0e0;
outline:none;
}
<h1 id="title">Change my color!</h1>
<!-- Putting related elements into the same class allows you to
not only style them identically, but also find them in
JavaScript more easily. -->
<button id="btn1" class="colorBtn" data-color="red">Red</button>
<button id="btn2" class="colorBtn" data-color="green">Green</button>
<button id="btn3" class="colorBtn" data-color="blue">Blue</button>
<button id="btn4" class="colorBtn" data-color="black">Black</button>
Another way to do this is the following:
function changeColor() {
title.style.color = btn.style.backgroundColor;
}
and set each buttons background to the appropriate color.
Rather than have the function figure out what color to change to, you could pass that color to the changeColor function. Your function would become:
function changeColor(color) {
title.style.color = color;
}
Then in your HTML, you would change the onclick properties to pass that in:
<button id="btn" onclick="changeColor('red')">Red</button>
...
Also, I wanted to mention that your issues before weren't just related to checking the innerHTML like you suggested in your post. One issue would be that you have multiple HTML elements with the same id. That isn't going to work well when using document.getElementById().
When you need a dynamic number of elements, we need an easy way to find them in the DOM. There are some helper methods out there, like getElementsByClassName() on the document object. The first thing I would do is drop the IDs on your buttons (which should be unique, by the way), in favor of a class name:
<button class="btn" onclick="colorRed()">Red</button>
<button class="btn" onclick="colorGreen()">Green</button>
<button class="btn" onclick="colorBlue()">Blue</button>
<button class="btn" onclick="colorBlack()">Black</button>
The second thing I would do is refactor this so that you can use good unobtrusive JavaScript practices (basically getting the JavaScript good out of the HTML markup and wiring it up all in a JavaScript code block). First, we need a way for the JavaScript to know which color you want to change the button text to. Let's introduce a custom HTML data- attribute in place of the hard-coded onclick handlers:
<button class="btn" data-color="red">Red</button>
<button class="btn" data-color="green">Green</button>
<button class="btn" data-color="blue">Blue</button>
<button class="btn" data-color="black">Black</button>
Now, we need a way to find these buttons so we can loop over them and apply an onclick handler. This can be done with the method I mentioned earlier:
var title = document.getElementById("title");
var buttons = document.getElementsByClassName("btn");
This will build you an array of the four buttons (or however many you have).
Then we need to loop over them and assign a click handler that retrieves the color from the data-color attribute and assigns it to the <h1> element's style.color property:
for (var btnIndex = 0; btnIndex < buttons.length; btnIndex++)
{
buttons[btnIndex].onclick = function() {
title.style.color = this.getAttribute('data-color');
}
}
And that's it! We eliminated all of the duplicate and practiced some better JavaScript techniques at the same time. Try the code out below:
var title = document.getElementById("title");
var buttons = document.getElementsByClassName("btn");
for (var btnIndex = 0; btnIndex < buttons.length; btnIndex++)
{
buttons[btnIndex].onclick = function() {
title.style.color = this.getAttribute('data-color');
}
}
<h1 id="title">Change my color!</h1>
<button class="btn" data-color="red">Red</button>
<button class="btn" data-color="green">Green</button>
<button class="btn" data-color="blue">Blue</button>
<button class="btn" data-color="black">Black</button>
Hi I need a bit of help modifying my script. What I want to do:
I have a small and easy script. It changes the class of an container so I have influence on the behaviour and looking of the container. In my scenario the buttons open a div with a music player.
My problem is that I need to declare all buttons as a script. The button ID is in my case the onclick function (see code).
So when I have 10 or twenty links I need also everytime to modify the script. My idea is to have a script wich gets feed their variables by id's and classes of containers. So I need not to modify the script file.
// JavaScript Document
function AudioFF() {
var FFplayer = document.getElementById(x);
if (FFplayer.classList.contains("audio-hidden")) {
FFplayer.classList.remove("audio-hidden");
FFplayer.classList.add("audio-shown");
} else {
FFplayer.classList.remove("audio-shown");
FFplayer.classList.add("audio-hidden");
Array.prototype.slice.call(document.querySelectorAll('audio')).forEach(function(audio) {audio.pause();});
}
};
dbbtn.onclick = function() {
x = "deepblue";
AudioFF();
};
swbtn.onclick = function() {
x = "spacewalk";
AudioFF();
};
fbtn.onclick = function() {
x = "forest";
AudioFF();
};
drbtn.onclick = function() {
x = "dreamrhythm";
AudioFF();
};
My idea was to use the same class of a button as an id for the container who needs to fade in with a string. The button has e.g. the class btn_a, btn_b … etc. The containers has the id btn_a, btn_b … I wanted the script to catch the class of the button and use this classname as a variable for getElementById. The closebutton is also using the same script to close the container. Thanks for help :-)
I will recommend to use data attribute instead
example like this:
//register listener like this
var btns = document.querySelectorAll('[data-music]');
btns.forEach(function(elm) {
elm.addEventListener('click', function(e) {
//your function
console.log(this.dataset.music);
})
})
<!--your links-->
<div id="m1"></div>
<div id="m2"></div>
<div id="m3"></div>
<!--just add data-music attribute make it the same with your div id and all set-->
<button data-music="m1">play m1</button>
<button data-music="m2">play m2</button>
<button data-music="m3">play m3</button>
You should be able to set a data tag attribute to the buttons and just read the variable from that:
<button id="myButton" data="variableForMyButton" />
document.getElementById(myButton).onClick = function(e){
x = e.target.getAttribute('data')
}
If multiple params are required you add additional data tags:
<button id="myButton" data="variableForMyButton" data-action="someSweetAction" />
Thanks guys, that was what I was looking for. My function is now like this:
The play button and closebutton are working.
<button data-music="m1">Deep Blue</button>
<div id="m1">Container Content</div>
var btns = document.querySelectorAll('[data-music]');
btns.forEach(function(elm) {
elm.addEventListener('click', function(e) {
//function
var FFplayer = document.getElementById((this.dataset.music));
if (FFplayer.classList.contains("audio-hidden")) {
FFplayer.classList.remove("audio-hidden");
FFplayer.classList.add("audio-shown");
} else {
FFplayer.classList.remove("audio-shown");
FFplayer.classList.add("audio-hidden");
Array.prototype.slice.call(document.querySelectorAll('audio')).forEach(function(audio) {audio.pause();});
}
})
})
And here in jquery. Thanks to you all. You show me the way :-)
jQuery (document).ready(function($){
var btns = $('[data-music]');
$(btns).each(function() {
$('[data-music]').on('click', function(e) {
var FFplayer = $(this).data('music');
$("#" + FFplayer).toggleClass("audio-hidden audio-shown");
});
});
})
I have two IDs in same name ! if any one clicked among them , i need to change the class name of the both IDs. i know we should use ID for single use. Because of my situation(I have two classes for button ) so i have moved to ID.
Her is my code if i click one id that name only changes another one is remains same
<button class="success" id="1" onClick="reply(this.id)"> Added </button>
<button class="success" id="1" onClick="reply(this.id)"> Added </button>
js function
function reply(clicked_id)
{
document.getElementById(clicked_id).setAttribute('class', 'failed');
var el = document.getElementById(clicked_id);
if (el.firstChild.data == "Added")
{
el.firstChild.data = "Add";
}
}
if i use instead of 'class' to id while renaming class which one will be renamed success class or 'class name 1' ?
You can't. Getelementbyid will only return one element. Probably the first one.
Pure JS Is Second Example
My JS Fiddle Example: http://jsfiddle.net/eunzs7rz/
This example will use the class attribute only to perform the switching that you need, its a extremely basic example as do not want to go beyond what is needed... Also i forgot to remove the id's in the JS Fiddle Example.. so just ignore them
THE CSS:
.success {
background-color:#00f;
}
.failed {
background-color:#f00;
}
THE HTML:
<button class="success"> Added </button>
<button class="success"> Added </button>
THE JAVSCRIPT:
$(function() {
$(".success").click(function(){
Reply(this);
});
});
function Reply(oElm) {
$(oElm).attr('class', 'failed');
}
EDIT - PURE JAVASCRIPT VERSION
Sorry, did not think to check the post tags if this was pure JS. But here you go anyway ;)
<style>
.success {
background-color:#00f;
}
.failed {
background-color:#f00;
}
</style>
<button class="success" onclick="Reply(this)"> Added </button>
<button class="success" onclick="Reply(this)"> Added </button>
<script>
function Reply(oElm) {
oElm.className = 'failed';
}
</script>
THE MAIN THING HERE
Once you have the element either by using 'this' or by using 'getElementBy', you can then simply use ".className" to adjust the class attribute of the selected element.
As already explained by others, id is for single use and is quicker than using class or type. So even if you have a group, if only one is ever used.. use an id.
Then you use the object/reference of 'this' from an event on an element, in this case the onclick... that will send that variable to the function / code called.
So using 'this' is a preferred option as it will always reference the element that it is used/called from.
pass elemenet, not it's Id
<button class="success" id="1" onClick="reply(this)"> Added </button>
<button class="success" id="1" onClick="reply(this)"> Added </button>
function reply(elem)
{
$(elem).setAttribute('class', 'failed');
if (elem.firstChild.data == "Added")
{
elem.firstChild.data = "Add";
}
}
the ID attribute must be unique or else it will get the last defined element with that ID.
See this for reference.
Use a class instead of an id. ids are supposed to be unique in a dom tree.
html:
<button class="success" onClick="reply()"> Added </button>
<button class="success" onClick="reply()"> Added </button>
js:
var ary_success = document.querySelectorAll(".success"); // once and forever. If the set of elements changes, move into function `reply`
function reply () {
var elem;
var s_myclasses;
for (var i=0; i < ary_success.length; i++) {
elem = ary_success[i];
s_myclasses = elem.getAttribute('class');
s_myclasses = s_myclasses.replace ( /(success|failed)/g, '' );
s_myclasses = s_myclasses + ' failed';
elem.setAttribute('class', s_myclasses );
if ( elem.firstChild.data.indexOf("Added") !== -1) {
elem.firstChild.data = "Add";
}
}
}
Live Demo here.
Notes
Make sure that you set ary_successin the onload handler or in an appropriately placed script section - at the timeof execution the buttons must be present in the dom ! If in doubt, move it to the start of reply' body.
If you employ jquery, the code simplifies (well...) to:
$(document).ready( function () {
$(".success").on ( 'click', function ( eve ) {
$(".success").removeClass("success").addClass("failed");
$(".success *:first-child:contains('Added')").text(" Add ");
});
});
Updates
Notes, Live Demo
Iterator method changed, every not supported on test platform