Multiple Javascript functions embedded in html - javascript

I am trying to implement two sliders in HTML and use Javascript functions to update the indicator of the values of those sliders. I don't know how to structure the code for the output of each slider. I think there is a problem with the way that the Javascript codes are embedded. Does anyone know how I can solve this issue?
Purpose: Have two sliders with two separate indicators in HTML
Thanks!
<body>
<h1>Round Range Slider</h1>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<p>Value: <span id="demo"></span></p>
</div>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange1">
<p>Value1: <span id="demo1"></span></p>
</div>
</body>
<head>
<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
</script>
<script>
var slider = document.getElementById("myRange1");
var output = document.getElementById("demo1");
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
</script>
</head>

Duplicating the code, taking into account the introduction of small changes - is bad.
I made you a js code with the forEach() method. This means that now you can control many input without having to write js logic for every.
Just replace your js code with this one:
let input = document.querySelectorAll('.slidecontainer input');
let result = document.querySelectorAll('.slidecontainer span');
input.forEach(function(input_current, index) {
input_current.oninput = function() {
result[index].innerHTML = this.value;
}
});

Declaring variables in separate script tags does not create two copies of the variable. You can declare a variable for each slider by giving them different names.
<body>
<h1>Round Range Slider</h1>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50"
class="slider" id="myRange">
<p>Value: <span id="demo"></span></p>
</div>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50"
class="slider" id="myRange1">
<p>Value1: <span id="demo1"></span></p>
</div>
</body>
<head>
<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
var slider1 = document.getElementById("myRange1");
var output1 = document.getElementById("demo1");
output1.innerHTML = slider1.value;
slider1.oninput = function() {
output1.innerHTML = this.value;
}
</script>
</head>
Better yet, use a loop:
<body>
<h1>Round Range Slider</h1>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50"
class="slider" id="myRange">
<p>Value: <span id="demo"></span></p>
</div>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50"
class="slider" id="myRange1">
<p>Value1: <span id="demo1"></span></p>
</div>
</body>
<head>
<script>
let sliders = document.querySelectorAll(".slidecontainer");
sliders.forEach(slideContainer => {
// Get a reference to the children of the current container.
let sliderChild = slideContainer.children[0];
let spanChild = slideContainer.children[1].children[0];
// Attach an event listener to each slider.
sliderChild.oninput = () => spanChild.innerText = sliderChild.value;
// Initialize the label.
spanChild.innerText = sliderChild.value;
});
</script>
</head>

Related

Update Input field value with value from a range slider using javascript

I'm trying to modify a how-to example which I got from W3Schools
The example is a range slider which display the value of the slider inside a <span>
tag
What I would like to do is display the value inside an input field
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<p>Value: <span id="demo"></span></p>
</div>
<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
</script>
Source: W3Schools range slider example
I would like to display the value inside an input field instead of the <span>
tag so I have tried to modify the example:
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<input type="number" id="demo" name="fname" value="">
</div>
<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("demo").value = slider.value;
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
</script>
but this doesn't work as it only display the initial value and does not update if I move the slider knob
You can store the element's reference in the output var & instead of innerHTML you could just use the value attribute.
Here's the updated code for your reference:
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.value = slider.value;
slider.oninput = function() {
output.value = this.value;
}
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<input type="number" id="demo" name="fname" value="">
</div>
setting an onchange function on the range onchange="myfunction()"so this function will be called every time you change the slider.
inside the function setting demo.value to slider.value
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
function myfunction() {
demo.value = slider.value
}
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange" onchange="myfunction()">
<input type="number" id="demo" name="fname" value="">
</div>

Change value on event oninput typescript

I have a span that I want to change in according to a value from an input on the event oninput
Here is my html :
<div class="slidecontainer">
<input type="range" min="1" max="1000" value="50" class="slider" id="myRange" step="3" class="myRange">
<p>Value: <span id="demo"></span></p>
<p>Gain de temps: <span id="time"></span></p>
</div>
My typescript file :
var slider = document.getElementById("myRange") as HTMLInputElement;
var output = document.getElementById("demo");
output.innerHTML = slider.value;
var convertSlider = parseInt(slider.value);
var gainTime = Math.round(convertSlider * 4* (1 - Math.min(convertSlider, 200) * 40 / 10000)).toString();
var gainTimeOutput = document.getElementById("time");
gainTimeOutput.innerHTML = gainTime;
slider.oninput = e => {
output.innerHTML = ((<HTMLTextAreaElement>e.target).value);
gainTimeOutput.innerHTML = gainTime;
};
With this solution, I have the value in my span #time but it doesn't change when I move the value of the slider, how to catch the event to also make change the value of my span #time ?
I don't know what you're trying to do with this code: output.innerHTML = ((<HTMLTextAreaElement>e.target).value); But to accomplish what you described the assignment should rather be to the value of the slider.
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
var gainTimeOutput = document.getElementById("time");
slider.oninput = e => {
output.innerHTML = slider.value;
var convertSlider = parseInt(slider.value);
var gainTime = Math.round(convertSlider * 4* (1 - Math.min(convertSlider, 200) * 40 / 10000)).toString();
gainTimeOutput.innerHTML = gainTime;
};
<div class="slidecontainer">
<input type="range" min="1" max="1000" value="50" class="slider myRange" id="myRange" step="3">
<p>Value: <span id="demo"></span></p>
<p>Gain de temps: <span id="time"></span></p>
</div>
I think you have to put onChange attribute to your input, so it can change its value
something like:
<input type="range" min="1" max="1000" value="50" onChange="handleInputChange()" class="slider" id="myRange" step="3" class="myRange" />
and in your script, put your code into a function
funtion handleInputChange() {
console.log("hello")
// your logic
}

JavaScript to output html range slider values for multiple sliders

I want to create two range sliders in html and display their current value with a JS script below each slider. But in my code both sliders will output their value to the same "value output" (the one for the slider with id="myRange2"). Why does this happen and how can I fix this?
I tried to make the slider and output variables unique for each slider script, but that does not solve my problem.
This issue is similar, but I am not so familiar with JS and I think my solution might be more simple.
This is my .html code with the JS scripts at the end:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<p>Value: <span id="demo"></span></p>
</div>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange2">
<p>Value: <span id="demo2"></span></p>
</div>
<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
</script>
<script>
var slider = document.getElementById("myRange2");
var output = document.getElementById("demo2");
output.innerHTML = slider.value;
slider.oninput = function() {
output.innerHTML = this.value;
}
</script>
</body>
</html>
You have to use different names for variables
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
<p>Value: <span id="demo"></span></p>
</div>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange2">
<p>Value: <span id="demo2"></span></p>
</div>
<script>
var slider1 = document.getElementById("myRange");
var demo = document.getElementById("demo");
demo.innerHTML = slider1.value;
slider1.oninput = function() {
demo.innerHTML = this.value;
}
</script>
<script>
var slider2 = document.getElementById("myRange2");
var output = document.getElementById("demo2");
output.innerHTML = slider2.value;
slider2.oninput = function() {
output.innerHTML = this.value;
}
</script>
</body>
</html>

Display values of multiple input type range in one page

I'm trying to display values of every slider I have on my page, this is my code so far:
var i = 0;
var st = 'slider';
var ot = 'output';
var s = '';
var o = '';
for (var x = 0; x < 3; x++) {
i++;
s = st+i;
o = ot+i;
var s = document.getElementById("range"+i);
var o = document.getElementById("limit"+i);
o.innerHTML = s.value;
s.oninput = function() {
o.innerHTML = this.value;
}
}
<div id="slidecontainer">
<input type="range" min="2" max="50" value="20" class="slider" id="range1" >
<label>You chose <span id="limit1"></span></label>
</div>
<div id="slidecontainer">
<input type="range" min="2" max="50" value="20" class="slider" id="range2" >
<label>You chose <span id="limit2"></span></label>
</div>
<div id="slidecontainer">
<input type="range" min="2" max="50" value="20" class="slider" id="range3" >
<label>You chose <span id="limit3"></span></label>
</div>
It's only changing the last value when I move any slider, I want to display the value of each slider respectively. I'm using a loop in my JavaScript code because I have more than 20 sliders and I don't want to write a function for each of them unless that is the only way of doing it. Any suggestions?
The problem you are having is related to variable scope. There is only one variable named o, each iteration of the loop changes this variable. So when the
oninput function is evaluated o equals the last value you set it to equal. The current value of o is not "saved" in the function definition.
See https://www.w3schools.com/js/js_scope.asp for more information.
See solution below, here I find the limit in each call to the function.
function updateLabel() {
var limit = this.parentElement.getElementsByClassName("limit")[0];
limit.innerHTML = this.value;
}
var slideContainers = document.getElementsByClassName("slidecontainer");
for (var i = 0; i < slideContainers.length; i++) {
var slider = slideContainers[i].getElementsByClassName("slider")[0];
updateLabel.call(slider);
slider.oninput = updateLabel;
}
<div class="slidecontainer">
<input type="range" min="2" max="50" value="20" class="slider">
<label>You chose <span class="limit"></span></label>
</div>
<div class="slidecontainer">
<input type="range" min="2" max="50" value="20" class="slider">
<label>You chose <span class="limit"></span></label>
</div>
<div class="slidecontainer">
<input type="range" min="2" max="50" value="20" class="slider">
<label>You chose <span class="limit"></span></label>
</div>

Why does nesting my divs break document.getElementById()?

I'm having an issue while designing a music player. My music player works with the following code:
playlist_index = 0;
// Set object references
playbtn = document.getElementById("playpausebtn");
seekslider = document.getElementById("seekslider");
volumeslider = document.getElementById("volumeslider");
curtimetext = document.getElementById("curtimetext");
durtimetext = document.getElementById("durtimetext");
playlist_status = document.getElementById("playlist_status");
playerImg = document.getElementById("playerImg");
// Audio Object
audio = new Audio();
audio.src = dir+playlist[0].song_url;
audio.loop = false;
playlist_status.innerHTML = playlist[playlist_index].song_name + '-' + playlist[playlist_index].band_name;
// Add Event Handling
playbtn.addEventListener("click",playPause);
mutebtn.addEventListener("click", mute);
seekslider.addEventListener("mousedown", function(event){ seeking=true; seek(event); });
seekslider.addEventListener("mousemove", function(event){ seek(event); });
seekslider.addEventListener("mouseup",function(){ seeking=false; });
volumeslider.addEventListener("mousemove", setvolume);
audio.addEventListener("timeupdate", function(){ seektimeupdate(); });
audio.addEventListener("ended", function(){ switchTrack(); });
audio.addEventListener("play", function(){ playbtn.style.background = "url(http://localhost/wordpress/wp-content/themes/virtue-child/pause.png) no-repeat"; });
// Functions
function switchTrack(){
if(playlist_index == (playlist.length - 1)){
playlist_index = 0;
} else {
playlist_index++;
}
playlist_status.innerHTML = playlist[playlist_index].song_name + '-' + playlist[playlist_index].band_name;
audio.src = dir+playlist[playlist_index].song_url;
setTimeout(audio.play(), 2000);
}
(plus some more functions for updating seek bars and times) and the following HTML:
<div id="audio_player">
<div id="playerImg"></div>
<div id="audio_controls">
<button id="playpausebtn"></button>
<p id="playlist_status"></p>
<div id="sliderHolder">
<input id="seekslider" type="range" min="0" max="100" value="0" step="1">
<span id="curtimetext">00:00</span>
<span id="durtimetext">00:00</span>
</div>
<button id="mutebtn"></button>
<br/>
<input id="volumeslider" type="range" min="0" max="100" value="100" step="1">
</div>
</div>
But when I start housing elements in container divs, the above code fails to update the time and the seek slider doesn't work. The housed and styled audio player HTML looks like this:
<div id="audio_player">
<img src="wp-content/uploads/band-photos/Logo.png" id="playerImg">
<p id="playlist_status"></p>
<div id="audio_controls">
<div id="sliderHolder">
<input id="seekslider" type="range" min="0" max="100" value="0" step="1">
<span id="curtimetext">00:00</span>
<span id="durtimetext">00:00</span>
</div>
<div id="musicButtons">
<button id="playpausebtn"></button>
<div id="volumeHolder">
<img src="http://localhost/wordpress/wp-content/themes/virtue-child/speaker.png" id="volButton">
<input id="volumeslider" type="range" min="0" max="100" value="100" step="1">
</div>
</div>
</div>
</div>
Is there an issue when I begin to house elements in divs and searching the DOM for them? Again, the JavaScript works with the first set of HTML, not the second.
Thank you everyone for the input. It looks like in styling the new player I removed the mute button. Therefore: 'mutebtn.addEventListener("click", mute);' was throwing an error and causing the rest of the functions not to work.

Categories

Resources