i'm trying to change images based on the user pressing the next button but that isn't happening
var my_image = document.getElementById(main_image);
var image_array = ["https://www.w3schools.com/jsref/klematis2.jpg"];
var image_index = 1;
function change_image(){
my_image.setAttribute("src", image_array[image_index]);
image_index++;
if(image_index > 1){image_index = 0;}
}
<img src="https://www.w3schools.com/jsref/klematis.jpg" id ="main_image">
<button onclick="change_image()"> next </button>
document.getElementById() needs to have a string passed into it. If main_image is an element, and not a string, this could be your issue.
Looks like your array index is set wrong
There are 2 problems in your code:
1- getElementByID expects a string. By not putting quote marks around "main_image" javascript thinks main_image is a variable name, not a value.
2- your array only has one element, so it's position is 0, not 1.
Below your code is working:
var my_image = document.getElementById("main_image");
var image_array = ["https://www.w3schools.com/jsref/klematis2.jpg"];
var image_index = 0;
function change_image(){
my_image.setAttribute("src", image_array[image_index]);
image_index++;
if(image_index > 1){image_index = 0;}
}
<img src="https://www.w3schools.com/jsref/klematis.jpg" id ="main_image">
<button onclick="change_image()"> next </button>
Alternatively you can querySelector.
Secondly instead of using onClick in the button use addEventListener.
`
let my_image = document.querySelector("#main_image");
let nextBtn = document.querySelector("button")
let image_array = ["https://www.w3schools.com/jsref/klematis2.jpg"];
let image_index = 0;
const change_image =() => {
my_image.setAttribute("src", image_array[image_index]);
image_index++;
if(image_index > 1){image_index = 0;}
}
nextBtn.addEventListener("click", change_image)
`
The answer has been given, I'm only improving on the syntax
Pass a string into the document.getElementById(). I hope this works for you.
Related
I have created a button using javascript and now I want to give it a onclick. however I want the function to have a parameter i. the problem is that when I inspect the console the onclick function is just onclick=playAudio(i). I want it to be different for each value of i in the for loop, but because it is in brackets it just stays as i instead of the current number in the for loop. I hope I have explained this properly. some of the code is below to help you understand.
var i;
var audioMp3 = ["audio/Un", "audio/Deux", "audio/Trois", "audio/Quatre", "audio/Cinq", "audio/Six", "audio/Sept", "audio/Huit", "audio/Neuf", "audio/Dix"];
for(i = 0; i < audioMp3.length; i++{
var audioBtn = document.createElement("BUTTON");
audioBtn.setAttribute("onclick", "playAudio(i);";
}
var audioMp3 = ["audio/Un", "audio/Deux", "audio/Trois", "audio/Quatre", "audio/Cinq", "audio/Six", "audio/Sept", "audio/Huit", "audio/Neuf", "audio/Dix"];
for(var i = 0; i < audioMp3.length; i++){
var node = document.createElement("BUTTON");
var textnode = document.createTextNode(audioMp3[i]);
node.appendChild(textnode);
node.setAttribute("onclick", "playAudio("+i+");");
document.getElementById("element").appendChild(node);
}
function playAudio(i){
alert(i);
}
<div id="element"></div>
I'm pretty sure that this should work :
audioBtn.setAttribute("onclick", "playAudio("+i+");");
audioBtn.onclick = function(){
playAudio(i)
}
Create an array with all the possible values, loop through the values to create the buttons, each button should have their click event listener to play their own button's song.
I don't know your precise code but that is the pseudo-code to do it.
When I click the "change lights" button I have to click it twice for the picture to change. What could be going wrong? Any ideas?
Here is my HTML:
<p>Click the button to change to the next light.</p>
<img id="starting_light" src="green.jpg">
<button type="button" onclick="nextLightClick()">Change</button>
And my JavaScript:
var gyr = new Array("green.jpg","yellow.jpg","red.jpg");
var index = 0;
var gyrLen = gyr.length;
function nextLightClick() {
if (index == gyrLen)
index = 0;
var image = document.getElementById('starting_light');
image.src = gyr[index];
index++;
}
I suspect the main problem to be in the JavaScript because once I started messing around with the variables the issue was introduced.
The first time this runs, the image is green.
It then sets the image to gyr[0], the green image, then index is incremented.
You can either increment the index before setting the image, or reorder the array to have green be last.
The first time you click the button, index is equal to 0, so nextLightClick() is setting image.src to "green.jpg", which is the same (assuming "1green.jpg" is a typo) as the starting image.
The solution is to move index++ to the first line of nextLightClick().
Your index is still 0 on the first time you enter the function and set the image.
Move the index++; to the start of the function, or initialize the index to value 1.
var index = 1;
If you want to initialize the index to 1, then you should rename the variable to something like nextIndex.
I don't think it is the case. Your code is working correctly. Your first image is green and the first time you click you are replacing it with the first image, that's the reason you don't see any difference.
You might consider doing it as:
var gyr = new Array("http://i.imgur.com/eucAMTA.jpg", "http://is2.mzstatic.com/image/thumb/Purple122/v4/be/9a/f0/be9af074-90f2-5894-99a0-17460783db6c/source/1200x630bf.jpg", "https://i0.wp.com/fusion.net/wp-content/uploads/2016/05/RED.jpg?resize=1600%2C900&quality=80&strip=all");
var index = 0;
var gyrLen = gyr.length;
function nextLightClick() {
index++;
// alert("hello" + index);
if (index == gyrLen)
index = 0;
var image = document.getElementById('starting_light');
image.src = gyr[index];
}
img {
width: 200px;
height: 200px;
}
p>Click the button to change to the next light.</p>
<img id="starting_light" src="http://i.imgur.com/eucAMTA.jpg">
<button type="button" onclick="nextLightClick()">Change</button>
Ah I seem to have found the answer thanks to Zac and American the problem was that index should have been at the first line of 'nexlightclick'
Fixed script below:
<p>Click the button to change to the next light.</p>
<img id="starting_light" src="green.jpg">
<button type="button" onclick="nextLightClick()">Change lights</button>
<script>
var gyr = new Array("green.jpg","yellow.jpg","red.jpg");
var index = 0;
var gyrLen = gyr.length;
function nextLightClick() {
index++;
if (index == gyrLen)
index = 0;
var image = document.getElementById('starting_light');
image.src = gyr[index];
}
</script>
</body>
</html>
There is a little problem with index update logic. You must evaluate its value and if it's less than gry.length add one else reinitialize to 0.
The inside script code:
var gyr = new Array("green.jpg","yellow.jpg","red.jpg");
var index = 0;
function nextLightClick() {
index = index + 1 < gyr.length ? index + 1 : 0;
document.getElementById('starting_light').alt = gyr[index];
}
I am working client side on a web page that I am unable to edit.
I want to use JS to click on a particular button, but it does not have a unique identifier.
I do know the class and I do know a (unique) string in the innerHTML that I can match with, so I am iterating through the (varying number) of buttons with a while loop looking for the string:
var theResult = '';
var buttonNum = 0;
var searchString = '720p';
while (theResult.indexOf(searchString) == -1
{
theResult = eval(\"document.getElementsByClassName('streamButton')[\" + buttonNum + \"].innerHTML\");
buttonNum++;
}
Now I should know the correct position in the array of buttons (buttonNum-1, I think), but how do I reference this? I have tried:
eval(\"document.getElementsByClassName('streamButton')[\" + buttonNum-1 + \"].click()")
and variation on the position of ()'s in the eval, but I can't get it to work.
You could try something like:
var searchStr = '720p',
// Grab all buttons that have the class 'streambutton'.
buttons = Array.prototype.slice.call(document.querySelectorAll('button.streamButton')),
// Filter all the buttons and select the first one that has the sreachStr in its innerHTML.
buttonToClick = buttons.filter(function( button ) {
return button.innerHTML.indexOf(searchStr) !== -1;
})[0];
You don't need the eval, but you can check all the buttons one by one and just click the button immediately when you find it so you don't have to find it again.
It is not as elegant as what #Shilly suggested, but probably more easily understood if you are new to javascript.
var searchString = '720p';
var buttons = document.getElementsByClassName("streamButton"); // find all streamButtons
if(buttons)
{
// Search all streamButtons until you find the right one
for(var i = 0; i < buttons.length; i++)
{
var button = buttons[i];
var buttonInnerHtml = button.innerHTML;
if (buttonInnerHtml.indexOf(searchString) != -1) {
button.click();
break;
}
}
}
function allOtherClick() {
console.log("Wrong button clicked");
}
function correctButtonClick() {
console.log("Right button clicked");
}
<button class='streamButton' onclick='allOtherClick()'>10</button>
<button class='streamButton' onclick='allOtherClick()'>30</button>
<button class='streamButton' onclick='correctButtonClick()'>720p</button>
<button class='streamButton' onclick='allOtherClick()'>abcd</button>
I would stay clear of eval here, what if the text on the button is some malicious javaScript?
Can you use jQuery? if so, check out contains. You can use it like so:
$(".streamButton:contains('720p')")
I’m getting an ".addEventListener is not a function" error. I am stuck on this:
var comment = document.getElementsByClassName("button");
function showComment() {
var place = document.getElementById('textfield');
var commentBox = document.createElement('textarea');
place.appendChild(commentBox);
}
comment.addEventListener('click', showComment, false);
<input type="button" class="button" value="1">
<input type="button" class="button" value="2">
<div id="textfield">
</div>
The problem with your code is that the your script is executed prior to the html element being available. Because of the that var comment is an empty array.
So you should move your script after the html element is available.
Also, getElementsByClassName returns html collection, so if you need to add event Listener to an element, you will need to do something like following
comment[0].addEventListener('click' , showComment , false ) ;
If you want to add event listener to all the elements, then you will need to loop through them
for (var i = 0 ; i < comment.length; i++) {
comment[i].addEventListener('click' , showComment , false ) ;
}
document.getElementsByClassName returns an array of elements. so may be you want to target a specific index of them: var comment = document.getElementsByClassName('button')[0]; should get you what you want.
Update #1:
var comments = document.getElementsByClassName('button');
var numComments = comments.length;
function showComment() {
var place = document.getElementById('textfield');
var commentBox = document.createElement('textarea');
place.appendChild(commentBox);
}
for (var i = 0; i < numComments; i++) {
comments[i].addEventListener('click', showComment, false);
}
Update #2: (with removeEventListener incorporated as well)
var comments = document.getElementsByClassName('button');
var numComments = comments.length;
function showComment(e) {
var place = document.getElementById('textfield');
var commentBox = document.createElement('textarea');
place.appendChild(commentBox);
for (var i = 0; i < numComments; i++) {
comments[i].removeEventListener('click', showComment, false);
}
}
for (var i = 0; i < numComments; i++) {
comments[i].addEventListener('click', showComment, false);
}
var comment = document.getElementsByClassName("button");
function showComment() {
var place = document.getElementById('textfield');
var commentBox = document.createElement('textarea');
place.appendChild(commentBox);
}
for (var i in comment) {
comment[i].onclick = function() {
showComment();
};
}
<input type="button" class="button" value="1">
<input type="button" class="button" value="2">
<div id="textfield"></div>
The first line of your code returns an array and assigns it to the var comment, when what you want is an element assigned to the var comment...
var comment = document.getElementsByClassName("button");
So you are trying to use the method addEventListener() on the array when you need to use the method addEventListener() on the actual element within the array. You need to return an element not an array by accessing the element within the array so the var comment itself is assigned an element not an array.
Change...
var comment = document.getElementsByClassName("button");
to...
var comment = document.getElementsByClassName("button")[0];
Another important thing you need to note with ".addEventListener is not a function" error is that the error might be coming a result of assigning it a wrong object eg consider
let myImages = ['images/pic1.jpg','images/pic2.jpg','images/pic3.jpg','images/pic4.jpg','images/pic5.jpg'];
let i = 0;
while(i < myImages.length){
const newImage = document.createElement('img');
newImage.setAttribute('src',myImages[i]);
thumbBar.appendChild(newImage);
//Code just below will bring the said error
myImages[i].addEventListener('click',fullImage);
//Code just below execute properly
newImage.addEventListener('click',fullImage);
i++;
}
In the code Above I am basically assigning images to a div element in my html dynamically using javascript. I've done this by writing the images in an array and looping them through a while loop and adding all of them to the div element.
I've then added a click event listener for all images.
The code "myImages[i].addEventListener('click',fullImage);" will give you an error of "addEventListener is not a function" because I am chaining an addEventListener to an array object which does not have the addEventListener() function.
However for the code "newImage.addEventListener('click',fullImage);" it executes properly because the newImage object has access the function addEventListener() while the array object does not.
For more clarification follow the link: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_a_function
The main reason of this error is this line
document.getElementsByClassName("button")
Cause the getElementsByClassName returns an array-like object of all child elements or a collection of elements.
There are two possible solutions AFAIK -
Treat the variable containing document.getElementsByClassName("button") as an array and be specific when using an event listener.
Example -
comment[0].addEventListener('click' , showComment , false )
Use id for selecting that specific element.
Example-
document.getElementById('button')
Try this one:
var comment = document.querySelector("button");
function showComment() {
var place = document.querySelector('#textfield');
var commentBox = document.createElement('textarea');
place.appendChild(commentBox);
}
comment.addEventListener('click', showComment, false);
Use querySelector instead of className
<script src="main.js" defer></script>
which makes execute your code after the document fully loaded hence the javascript has complete reference
I have been strugling with this for a while and I am sure there is a simple answer to this. What happens is I remove a div called "payment" then dynamicaly create it again so I can add to it. That then gets repeated as the infomation that needs to be added to it changes.
I have mangaged to get this so far.
function clearPage()
{
var d = document.getElementById("contain");
var d_nested = document.getElementById("payment");
var deleteNode = d.removeChild(d_nested);
}
function createPayment()
{
payment = document.createElement("div");
payment.id = "mine";
document.getElementById("contain").appendChild(payment);
}
function printOnPage()
{
var x = names.length;
for( var i = 0 ; i < x ; i++ )
{
var para = document.createElement("p");
var paymentDiv = document.getElementById("payment");
paymentDiv.appendChild(para);
var txtName = document.createTextNode("Item: ");
para.appendChild(txtName);
var txtNameArray = document.createTextNode(names[i]);
para.appendChild(txtNameArray);
var txtQty = document.createTextNode(" Qty: ");
para.appendChild(txtQty);
var txtQtyArray = document.createTextNode(qty[i]);
para.appendChild(txtQtyArray);
var txtCost = document.createTextNode(" Cost: ");
para.appendChild(txtCost);
var txtCostArray = document.createTextNode(prices[i]);
para.appendChild(txtCostArray);
}
}
Related HTML
<div id="contain">
<p>Payment</p>
<div id="payment">
<br />
</div>
</div>
It needs the ID of payment for both my CSS rules and for my creating the text that goes in it.
This is the error I get in FireFox
Error: paymentDiv is null Source File:
http://itsuite.it.brighton.ac.uk/ks339/sem2/javascript/js.js Line: 76
Hope someone can provide some insight in to this and please tell me if I am completly off!
Thanks
Edit: Is it easior to clear the div rather than delete it, how would I go about doing such a thing?
In create_payment(), you set the ID to 'mine'. Shouldn't it be 'payment'?
I do not understand your requirements very well, but anyway you cannot create multiple items in the page using the same id attribute, if you want to duplicate an item and still have control over it, you should be using class instead.
Try switching your code into jquery it will be cleaner and easier to understand for you & me.
Your problem is the fact that in createPayment() you're setting the id to 'mine':
payment.id = "mine";
while later on in printOnPage() you're looking for the element using id 'payment':
var paymentDiv = document.getElementById("payment");
As you mention in your edit, it is far easier just to clear the div than to remove it, specially if you still need it later.
To clear a DIV-block just set it's content to empty:
document.getElementById('payment').innerHTML = "";
I hope you find a solution! Good luck!