I am implementing a Stopwatch in JavaScript.
I want to delete additional div elements when pushing a clear button. I added function cc();, but function cc() doesn't work. What's wrong with my code?
Javascript:
a = 0;
myButton = 0;
function myWatch(flug) {
if(myButton == 0) {
Start = new Date();
myButton = 1;
document.myForm.myFormButton.value = "Stop!";
myInterval = setInterval("myWatch(1)", 1);
} else {
if(flug == 0) {
myButton = 0;
document.myForm.myFormButton.value = "Start";
clearInterval(myInterval);
}
Stop = new Date();
T = Stop.getTime() - Start.getTime();
H = Math.floor(T / (60 * 60 * 1000));
T = T - (H * 60 * 60 * 1000);
M = Math.floor(T / (60 * 1000));
T = T - (M * 60 * 1000);
S = Math.floor(T / 1000);
Ms = T % 1000;
document.myForm.myClick.value = H + ":" + M + ":" + S + ":" + Ms;
}
}
b = 0;
function stop() {
b++;
stopa();
}
function stopa() {
var element = document.createElement('div');
element.id = pos;
var objBody = document.getElementsByTagName("body")
.item(0);
objBody.appendChild(element);
rap = "";
rap = "rap" + b + "=" + H + ":" + M + ":" + S + ":" + Ms;
element.innerHTML = rap;
}
function cc() {
document.body.removeChild(element);
}
HTML:
<form name="myForm" action="#">
<input type="text" size="20" name="myClick">
<input type="button" value="Start" name="myFormButton" onclick="myWatch(0)" />
<input type="button" value="Rap" name="Rap" onclick="stop()">
<input type="button" value="clear" name="clear" onclick="cc()">
</form>
<h3>
<div id="pos">
</div>
</h3>
Try to pass the context explicitly as parameter on the cc() function.
js
function cc(el) {
el.parentNode.removeChild(el);
}
html
<input type="button" value="clear" name="clear" onclick="cc(this)">
Open up your Console. It's found in most major browsers and will help you loads with JS development.
For example, if you look at your code exactly as is, you get an error:
Uncaught ReferenceError: element is not defined
As several have said, it's a variable scope issue. There's a few easy fixes, the easiest being simply making element have a larger scope - that is, define it outside of your functions first.
var element = null;
and then in stopa, don't use var because it'll make a new, local variable instead of using the global one.
element = document.createElement('div');
The next problem you'll notice is that element in cc still doesn't refer to the correct element - this is because in the following line, pos is not defined.
element.id = pos;
Again, take a look at the Console (now more specifically at the HTML section than the JS, but it's in the same developer options). You'll notice the created element's ID is [object HTMLDivElement] - not "pos". I'd recommend not even worrying about giving them ids, you have a div with id pos already in your HTML, simply append your results to that instead of the body.
objBody = document.getElementById("pos");
Then when you clear, clear all children from pos (you'll also want to clear the text box I'm sure, so here ya go)
while (objBody.hasChildNodes()) {
objBody.removeChild(objBody.lastChild);
}
document.myForm.myClick.value = "";
Notice now we no longer need element to be global, because it's only referenced in one function - it can be local to that function. However, objBody is now referenced in stopa and cc, so we'll make it global as we did with element and simply ensure all future references to it don't include var.
var element = null;
Add some error checking (clearing before you click Start causes errors, for example) and you're good to go!
http://jsfiddle.net/daCrosby/MMywX/1/
The function cc has no idea what 'element' is. The easiest way to fix this is to use jquery. When you delete the div, do something like
$('#pos').remove()
This finds the div with id 'pos' and removes it. You may need to pass the id of the div to cc if it's not just 'pos'.
Modern browsers supports remove() method on the element. You don't need to use external libraries as jQuery or long code. It's simple as :
var x = document.getElementById("myElement");
x.remove();
Working exemple here -> https://jsfiddle.net/tmj3p7t5/
Related
I'm using Wavesurfer.js to visualize waveforms from . Is there a way to use jQuery or Javascript to dynamically change the loaded audio file when I click on an HTML element?
I'm able to visualize a single file, but don't know how to change the loaded file dynamically.
Here's the Wavesurfer.js instance in my footer
<script>
var wavesurfer = WaveSurfer.create({
backend: 'MediaElement',
container: '#waveform',
barWidth: 1,
barGap: 3,
cursorColor: '#e15a13',
cursorWidth: 3,
mediaControls: true,
hideScrollbar: true,
waveColor: "#000000",
fillParent: true,
responsive: true,
});
wavesurfer.setHeight(40);
wavesurfer.load('http://dev.chrislamdesign.com/shortwave/wp-content/uploads/2019/10/Pharrell-Williams-Happy-Official-Music-Video-1.mp3');
wavesurfer.on('ready', updateTimer)
wavesurfer.on('audioprocess', updateTimer)
// Need to watch for seek in addition to audioprocess as audioprocess doesn't fire
// if the audio is paused.
wavesurfer.on('seek', updateTimer)
function updateTimer() {
var formattedTime = secondsToTimestamp(wavesurfer.getCurrentTime());
$('.waveform-time-indicator .time').text(formattedTime);
}
function secondsToTimestamp(seconds) {
seconds = Math.floor(seconds);
var h = Math.floor(seconds / 3600);
var m = Math.floor((seconds - (h * 3600)) / 60);
var s = seconds - (h * 3600) - (m * 60);
h = h < 10 ? '0' + h : h;
m = m < 10 ? '0' + m : m;
s = s < 10 ? '0' + s : s;
return h + ':' + m + ':' + s;
}
</script>
I want to replace the loaded file (wavesurfer.load) with an HTML string on click. I'm using Wordpress to loop song results, each have a URL printed in a paragraph tag with the class "move_to_wavesurfer". So, when I click on the song, i want to replace the wavesurfer.load value with the paragraph tag value.
Here's the HTML to inject
<div class="col-md-3">
<a class="song-link" data-target="#song-8">
<img width="606" height="610" src="http://dev.chrislamdesign.com/shortwave/wp-content/uploads/2019/07/cover.png" class="attachment-full size-full wp-post-image" alt="" srcset="http://dev.chrislamdesign.com/shortwave/wp-content/uploads/2019/07/cover.png 606w, http://dev.chrislamdesign.com/shortwave/wp-content/uploads/2019/07/cover-150x150.png 150w, http://dev.chrislamdesign.com/shortwave/wp-content/uploads/2019/07/cover-298x300.png 298w" sizes="(max-width: 606px) 100vw, 606px"></a>
<p class="move_to_wavesurfer>http://dev.chrislamdesign.com/shortwave/wp-content/uploads/2019/10/other_song.mp3</p>
</div>
</div>
<p>In your PHP loop... maybe you can put the urls in a data attribute</p>
<button rel='song-switch' data-song-url='song-url-a'>
play
</button>
<button rel='song-switch' data-song-url='other-song-url'>
play
</button>
...
console.clear();
// I'd normally write this in plain JavaScript - but since you are using WordPress - it has jQuery already
function switchTrack(url) {
// your code...
alert('play the song ' + url);
}
// get references to the HTML(DOM) elements
var $switches = $('[rel="song-switch"]');
// add event listeners to each switch
$switches.each( function() {
// $(this) refers to each switch
$(this).on('click', function() {
var url = $(this).data('song-url'); // get the value of that attr
//
switchTrack(url); // pass it into your function - to load a new track
// and this is where you'd work with the player's api...
// consider wrapping your current code in a function - or breaking it into some reusable functions
});
});
// yes... you should use event delegation... but you can look that up in the future.
From what I can see of your code - you probably don't have a script file / or aren't using it - so, remember to put this JS in a script tag / or generally - just make sure it's in the right place for you.
Here's where you can learn more about jQuery and all of it's functions: https://jquery.com/
https://jsfiddle.net/sheriffderek/teLm7drn
and also... keep in mind that with WordPress... you'll need to wrap your jQuery code with something like this:
(function($) {
// $ Works! You can test it with next line if you like
// console.log($);
})( jQuery );
I am trying to make a program in JavaScript that functions similar to a "Whack-a-Mole" game. I have everything figured out except for one thing. I would like to have each "mole" disappear after a brief time if it is not clicked on. The function that generates the moles is shown below. I am not entirely sure how to go about hiding the moles, but I would like to do so by selecting them by a uniquely generated ID, as shown in the code. There is a global variable "count" that is used to generate each ID.
function addMole(){
var yPos = numOne();
var xPos = numTwo();
if (timeLeft > 0){
$("#gamespace").append('<img id="i'+count+'" src="img/mole.gif" style="top:'+yPos+'px;left:'+xPos+'px;" />');
count++;
setTimeout("addMole()", Math.floor(Math.random()*2000));
};
};
I have tried using this function, but it doesn't seem to do anything and I'm not sure how or where to call it or if I'm even using the right selector.
function noMole(){
$("#i"+count).delay(2000).hide();
};
I'd probably go with something like the following:
function addMole() {
var yPos = numOne();
var xPos = numTwo();
if (timeLeft > 0) {
//make a new mole and have a reference to it
var newMole = $('<img src="img/mole.gif" style="top:' + yPos + 'px;left:' + xPos + 'px;" />');
//put the mole in the game
$("#gamespace").append(newMole);
//add another mole in a random amount of time
setTimeout(addMole, Math.floor(Math.random() * 2000));
//remove the created mole after 5 seconds
setTimeout(function(){ newMole.remove(); }, 5000);
};
};
You don't need a lookup. You just need the reference.
I'm trying to set up a function that sets up a countdown and then triggers another function/event when it reaches 0. I'm linking it with HTML to set up various button selectors to be able to increment the countdown by 1, 2, or 3 ticks.
The problem is that I can get the page to display the min/max timer with no issue, by adding document.getElementById("timer").innerHTML = myTime.curTime + "/" + myTime.maxTime
at the top of the HTML document, but I can't get it to update the curTime, and curTime never seems to update inside the object either. Is this just an issue with how I've structured it? Or should I be approaching this a different way?
Here is what I have so far:
(link to the jsfiddle: http://jsfiddle.net/g4Lu3n43/)
//set the initial value of timer
var timerDown = 0
//set up the countdown constructor
function Countdown(name, baseTime, inc) {
this.name = name;
this.timer = baseTime;
this.increment = inc;
this.maxTime = maxTime();
this.curTime = curTime();
}
//set up the functions for the Countdown prototype
Countdown.prototype = {
maxTime: function() {
return (this.timer + this.increment) * 2;
},
curTime: function() {
return maxTime - timerDown;
}
}
//set up the function to now de-increment the timer to 0
function deIncrement(numInc) {
timerDown += numInc;
if (myTime.curTime <= 0 ) {
alert("You've run out of time!");
} else {
updateTimer();
}
}
//set up the countdown object
var myTime = new Countdown("Timer", 10, 2);
//set up the function to update the div on the HTML page
function updateTimer() {
var timer = document.getElementById("timer")
timer.innerHTML = myTime.curTime + "/" + myTime.maxTime;
}
window.onload = updateTimer();
And the HTML portion of it:
<div id="timer">Time will go here</div>
<input type="button" id="inc1" onclick="deIncrement(1); return false" value="Coundown by 1">
<input type="button" id="inc2" onclick="deIncrement(2); return false" value="Coundown by 2">
<input type="button" id="inc3" onclick="deIncrement(3); return false" value="Coundown by 3">
<input type="button" id="inc4" onclick="deIncrement(4); return false" value="Coundown by 4">
There are a few issues with your code...
First you need to set a function to window.onload, not call the function and put the result in window.onload.
Next as briosheje said, you cannot have maxTime as a property and a function of the same object (even if you're using the prototype). Just use the function to get the latest value every time.
Be sure to use this.myFunction() (as opposed to myFunction()) to use another function/object from the object you're currently in.
Finally, your jsFiddle needed to run directly in the <head> element in order to use window.onload and named functions that are accessed from inline HTML attributes (ie. deIncrement). This was a configuration option set on the left-top of the page.
See the updated jsFiddle: http://jsfiddle.net/g4Lu3n43/2/
I'm a quite new in javascript, and I'm trying to do a script to get a soft color change, bbut when a call the objetc to be changed, I got some problems. My code is this:
<script lenguage="javascript">
hexadecimal = new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F")
function convierteHexadecimal(num){
var hexaDec = Math.floor(num/16)
var hexaUni = num - (hexaDec * 16)
return hexadecimal[hexaDec] + hexadecimal[hexaUni]
}
function convierteHexadecimal(num){
var hexaDec = Math.floor(num/16)
var hexaUni = num - (hexaDec * 16)
return hexadecimal[hexaDec] + hexadecimal[hexaUni]
}
color_decimal=0
function degradado(){
color_decimal ++
color_hexadecimal = convierteHexadecimal(color_decimal)
document.getElementById("title").style.color = color_hexadecimal + color_hexadecimal + color_hexadecimal
//la llamo con un retardo
if (color_decimal < 255)
setTimeout("degradado()",1)
}
degradado()
this is my code, but when I load it in chrome, an issue appears in:
document.getElementById("title").style.color
My h1 is:
<h1 align="center" id="title">Degradando...</h1>
I notice the id is correctly write, So, what is the problem?
Try to do this:
window.onload = function(){
document.getElementById("title").style.color
}
I think you are accessing the element even before it is created.
Call your function from the onload handler:
window.onload = function() {
degradado();
}
so that it will run after the DOM is loaded.
Hi Masters Of Web Development,
first I want to say that I did not believe in my eyes - I've got a piece of javascript that works just fine in IE7, and don't in Firefox!!! :)))) That was little joke. :)
So I already told you the problem (it wasn't joke), now I'm pasting the javascript:
<script type="text/javascript">
<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->
<!-- Begin
var ms;
ms = %%CONTENT_REFRESH%% - 5;
var stop;
stop = 0;
var myvalue;
function display() {
if (!stop) {
setTimeout("display();", 1000);
}
thetime.value = myvalue;
}
function recalc() {
var hours;
var minutes;
var seconds;
ms = ms - 1;
hours = Math.floor(ms / 3600);
minutes = Math.floor(ms / 60);
if (minutes < 10) {
minutes = "0"+minutes;
}
seconds = ms - (minutes*60) - (hours*3600);
if (seconds < 10) {
seconds = "0"+seconds;
}
myvalue = hours+":"+minutes+":"+seconds;
thetime.value = myvalue;
if (myvalue == "0:00:00") {
stop = 1;
}
if (!stop) {
setTimeout("recalc();", 1000);
}
}
// End -->
</SCRIPT>
This is very old script I know that. It takes my current remaining song time, from my winamp and countdowns in site. But as I said, it does not work in Firefox.
Body and code that calls countdown timer looks like this:
<body class="playlist_body" onLoad="recalc();display();">
Time Left In Song: <INPUT align="center" TYPE="text" Name="thetime" size=5 />
</body>
//Edit: I look at FireBug, and I saw the following error:
thetime is not defined
recalc()playlist.cgi (line 87)
function onload(event) { recalc(); display(); }(load )1 (line 2)
error source line: [Break on this error] thetime.value = myvalue;\n
The problem is that it's accessing DOM elements by name.
Add the following code to the top to declare a variable for the thetime element, add id="thetime" to the INPUT, and add a call to init(); in onload in the body element.
var thetime;
function init() {
thetime = document.getElementById('thetime');
}
By the way, you can replace the textbox with a regular DIV element by setting the div's ID to thetime, and replacing thetime.value with thetime.innerHTML.
Also, it's better to call setTimeout with a function instead of a string; you should replace "display();" and "recalc();" with display and recalc respectively.
IE has a "feature" where an element with a name attribute is placed in the window object, eg.
<div name=foo></div>
Will give you a variable "foo" -- this is non-standard, you should do
document.getElementByName("foo")
To get the timer output element.
var thetime = document.getElementById("thetime");
and add id="thetime" instead of just name="thetime" to the input