how to download multiple audio files using download attribute? - javascript

i was wondering if i can download all audio files from google word pronunciation
i came up with a solution that actually works
i created an html page with the following code
<a id="mylink" href='//ssl.gstatic.com/dictionary/static/sounds/de/0/word.mp3' download='word.mp3'>download audio "word"</a>
now if you click the above link , the browser will start downloading the audio file
and if you change word.mp3 to something else and click it again ,
it will start downloading the new word;
the problem is I tried to download the whole dictionary in mp3 format.
so i came up with the following javascript
var words=['cat','fish','police','office','ball'];//the whole dictioany.....
for(var z in words )
setTimeout(function(){
var lin=document.querySelector("a");//gets the above link
lin.href="//ssl.gstatic.com/dictionary/static/sounds/de/0/"+a[z]+".mp3";//changes link href to each of the array "words"
lin.download=a[z]+".mp3";//changes the file name to current word
lin.click();//after clicking this link , all downloads start at the same time
},1000)//even it setup to fire after 1 second
//all the downloads start at same time
the biggest problem is that only audio file downloaded is the last one "ball"
and it's downloaded multiple times
any solution is appreciated and thanks in advance
here is the example on jsfiddle click

You can't use a setTimeout() in a loop, as the loop will execute faster than the timeout. Thus, the final result will be ran for each event in the loop (a[z] will call a[4] five times). To get around this, you'll need to slightly modify your for loop, and not use a timeout:
var a = ['cat', 'fish', 'police', 'office', 'ball'];
for (var z = 0; z < a.length; z++) {
var l = document.querySelector("a");
l.href = "//ssl.gstatic.com/dictionary/static/sounds/de/0/" + a[z] + ".mp3";
l.download = a[z] + ".mp3";
l.click();
}
I've created an updated fiddle showcasing this here.
Hope this helps!

The problems with your code are:
The setTimeout is executed within the loop at nearly the same time. So that is why the function is also executed at the same time. Think of having ten egg timers that you all activate at the same time. They will also all ring at the same time.
The function triggered by setTmeout uses the variable z declared outside the function. It does not use the value of z at the time when setTimeout is executed, but at the time the function is executed. All instances of the function access the same variable, so they all use the value of z during the last loop.
Instead of having a loop, use setInterval to execute a function at a given interval and use a counter variable so that a different variable is used at each time the function is executed.
function run()
{
var words=['cat','fish','police','office','ball'];
var counter = 0;
// Setup IntervalFunction to run every 2 seconds
var interval = setInterval(IntervalFunction, 2000);
function IntervalFunction()
{
// Download word
downloadWord(words[counter]);
// Increase counter
counter++;
// When counter is beyond array, stop IntervalFunction from running
if(counter >= words.length)
{
clearInterval(interval);
}
}
}
function downloadWord(word)
{
var lin = document.querySelector("a");
lin.href = "https://ssl.gstatic.com/dictionary/static/sounds/de/0/" + word + ".mp3";
lin.download = word + ".mp3";
lin.click();
}

Related

How to have a variable increase over time (JS)

i was wondering how to make a variable go up over time, ive tried to do this -->
var i = 1;
var c = document.getElementById("click");
function workers() {
if (click >= workers*50000)) {
click += -(workers*50000)
click += i++
c.innerHTML = click;
}
}
but it hasnt worked, how do i fix this?
you could do this
let i = 0;
// instead of 2000 insert the frequency of the wanted update (in milliseconds)
const incrementInterval = setInterval(() => i++, 2000)
// when you want it to stop it
clearInterval(incrementInterval)
anyway, i don't really understand how the code supplied with the question has anything to do with it
You have an element and a variable 'click', which tells me you're really not wanting to grow over time per se, but rather grow with every click.
Another difficulty is finding out what you're trying to do with multiplying by 50000. I am assuming you are trying to reset the count after 50000.
One big thing you're missing is the actual association of the click event to your 'click' HTML element. Below, I'm using addEventListener to do that. From there, I'm resetting the counter to '1' if 'i' goes above '5' (I use 5 just to show the reset in a reasonable number of clicks). Then I take the value of 'i' and put it into the innerHTML label of the element that triggered the event.
var i = 1;
document
.getElementById("click")
.addEventListener('click', function(e) {
if (i > 5)
i = 1;
e.target.innerHTML = `click: ${i++}`;
})
<div id='click'>click<div>
Define your question better. What is your goal? What has your code achieved? What result are you getting and how is it different than your expectations? What is 'i' meant to be used for? How does it interact with the function? Why are you multiplying it with 50000? Is workers a separate variable that's globally defined and not shown? Communication is an important skill in this field, and comments are often helpful tools to document your code for others to understand.
I think an alternative answer could be formatted in this way:
let i = 0;
function increment(){
i++;
document.querySelector('h3').textContent = i
}
document.querySelector('button').addEventListener('click',increment)
<button>Click Me</button>
<h3>0</h3>

javascript: var i is not defined? (clearly defined)

WHAT I WANT TO HAPPEN
So what I want to happen is function partA() to click button [z] every 2 seconds. The button that is being clicked should change, because the script is a looping script, so for instance. The first loop, it would click button 1, then button 2, then button 3, because var z = 1 + i++. Is this possible? z is supposed to equal the number 1, plus the loop number. This should loop as long as variable i is less than 50.
WHAT IS HAPPENING
It works properly, looping and all, if I test the script without variable z. However, without variable z, I have to manually change the number that would equal z, which is painstaking, and annoying.
var z = 1 + i++
for(i=0;i<50;i++) {
setInterval(partA, 2000);
function partA() {
buttons = document.getElementsByTagName('button');
document.getElementsByTagName('button')[z].click();
}
}
Should i++ be defined another way? The error I'm getting when running the script in console is:
Uncaught ReferenceError: i is not defined (...)
at :2:13
at Object.InjectedScript._evaluateOn (:878:140)
at Object.InjectedScript._evaluateAndWrap (:811:34)
at Object.InjectedScript.evaluate (:667:21)
There's a couple of suggestions I could advise with your code so I'll try and address each one individually.
Firstly define your function outside of your loop. If you would like to know the reasons behind this please read: Don't make functions within a loop
Secondly you should really declare i as a variable to set the scope to which it applies. Some good information on this is at: Declaring variables without var keyword
Thirdly when you run your loop you could run the code inside an IIFE. The reason for this is when you run setInterval, by the time it runs i will actually be 3 (or the last number of your loop). This is due to the asynchronous nature of setInterval, and that the reference to i is bound to the function, not the value of i.
Example
for(var i=0;i<3;i++) {
(function(i) {
setInterval(clickButton(i), 2000);
})(i)
}
function clickButton(idx) {
return function() {
buttons = document.getElementsByTagName('button');
document.getElementsByTagName('button')[idx].click();
}
}
JSBin Demo
http://jsbin.com/harigewuze/edit?html,js,output
Why are you trying to define z outside the loop? Just use i.
for (var i = 0; i < 50; i++) {
...
document.getElementsByTagName('button')[i].click();
}
without changing your code too much I would write it like this...
you know its looping 50 times, you know i is incrementing from 0 to 49, use i to change the button name and you don't need z...
for(i=0;i<50;i++) {
setInterval(partA, 2000);
function partA() {
buttons = document.getElementsByTagName('button');
document.getElementsByTagName('button')[i + 1].click();
}
}
1) This is how you want your code to look like :
var z;
for(i=0;i<50;i++) {
z=i;
setInterval(partA, 2000);
}
function partA() {
buttons = document.getElementsByTagName('button');
document.getElementsByTagName('button')[z].click();
}
2) Unfortunately, in javascript you have a problem with this code due to the fact of scopes. My recommendation is to read this link first http://www.mennovanslooten.nl/blog/post/62 and understand how it works.
If you did understand it, then thumb up..you just promoted yourself to a higher level in javascript ;)
3) If you are still having issues, post it on JSFiddle

setTimeout in for loop

Currently I am trying to make a little game maninly for myself for having fun while making it and using it, but i got stuck at a part.
I would like to make a memory game where the program generates a certain array filled with the names of the arrows that should change. So e.g.: left,left,up,down,right with this I would like to change the left arrow 1st only to green than back to normal then since the 2nd time it would happen twice since the 1st 2 elements of the array are "left".
So I have been trying to use setTimeout in JS and tried to look it up how to use it and managed to slowly advance but i kidna got lost in all of the explanations.
My current code changes all the arrows that are listed in the array green then changes them back to normal 1 by 1 (actually I can't see the 1st arrow changin at all but i assume it does just the setTimeout doesnt apply to it since the rest is changing).
for (var j = 0; j < narray.length; j++) {
var image = document.getElementById(narray[j]);
image.src = "arrow-"+narray[j]+"-good.png";
function(j){
sesetTimeout(function(){
var image2 = document.getElementById(narray[j]);
image2.src = "arrow-"+narray[j]+".png";
}, j*1000);
})(j);
I know it is really messy but I have totally got lost in the tutorials I have tried to learn from. So if anyone could help me I would be really greatful.
Thanks in advance!
Here's what I think will work.
k=0;
for (var j = 0; j < narray.length; j++) {
var image = document.getElementById(narray[j]);
image.src = "arrow-"+narray[j]+"-good.png";
setTimeout(function(){
var image2 = document.getElementById(narray[k]);
image2.src = "arrow-"+narray[k]+".png";
k++;
}, j*1000+500);
}
So besides the typos, there's an issue with using "j" from the for loop in the timeout functions because they run later. So we introduce "k" to keep track of how many of them we've done. So k will be incremented each time, and here it's a global variable, so as each timeout function actually runs, k will be a different number, and will increment k to be ready for the next one that will be called.
What if you don't use a for loop and you call the function recursive, something like this:
function doSomething(j,l){
if(j>=l) return 'done';
setTimeout(function(){
console.log('step: ' + j + ' from: ' + l);
// add your code here :)
}, j*1000);
doSomething(++j,l);
}
doSomething(0,narray.length); // start with 0 and the length of the array

Making a total number count appear to increase

Basically I have a class counting system that displays the number of classes and displays them in a span element. Below is the code:
$.get('other.html', function(data) {
$('#total').html($('.doc', data).length);
});
This works perfectly, however I'd like a way to have the numbers increasing one by one since the span element contains 0 when the page loads. Here's an example (the numbers increasing on here).
For this I have tried setTimeout and despite this not working anyway, I released it would simply delay the function and then display the end number. I have heard of periodical or something similar being used but could not find this in the example source code.
I am really sorry for more poor phrasing. If you have no idea what I mean then just ask and I'll try rephrase or find a better example.
The key is the function which increases the number should set a setTimeout to call itself, before termination. This way it will always be called again. If you want the option to stop the incrementing, you can add a global variable, and the function will only set a new timeout when that variable is true.
Example:
var doIncrement = true;
var numberToIncrement = 0;
function increment {
numberToIncrement++;
$('#mySpan').text(numberToIncrement);
if (doIncrement) {
setTimeout(increment, 1000);
}
}
You could use the setInterval function that allows you to run code at some time intervals. clearInterval allows to stop the task.
http://jsfiddle.net/d52Pw/
var $totalEl = $('#total');
$.get('other.html', function(data) {
var len = $('.doc', data).length,
count = 0,
int = setInterval(function () {
if (++count === len) {
//when we reach len, we stop the task
clearInterval(int);
}
$totalEl.html(count);
}, 500); //run every 1/2 sec
});

Sequentially firing multiple random timeouts in JavaScript

I know at first glance (due to the title) this looks like one of the "Did you try searching Google before posting?" questions, but I can't seem to find an answer for the specific issue I'm experiencing. Sorry if I'm a noob.... still learning :)
I need to simulate a pause in javascript, but the setTimeout(function_call, timeout) function is not working for me. Reason being... when that setTimeout function is called, it then makes the function call asynchronously.
A little background:
I'm trying to simulate text being typed into a div at randomly timed intervals. I want it to appear as if a person is actually typing a message while the user is viewing the page. Since the timeout is a random interval and the function call is made asynchronously, the text ends up being printed in a random order.
Here is a snippet of what I have thus far:
typeString: function(s)
{
for(var i=0;i<s.length;i++)
{
var c = s.charAt(i);
var temp = setTimeout("MessageType.typeChar('" + c + "')", this.genRandomTime());
}
}
Thanks in advance for your help.
CJAM
UPDATE: By adding the timer delay to a varialbe, it enabled me to offset timeOut for the asynchronous calls. Thank you all for your quick responses. Here is the updated code:
typeString: function(s)
{
var delay = 0;
for(var i=0;i<s.length;i++)
{
var c = s.charAt(i);
setTimeout("GoogleTyper.typeChar('"+c+"')", delay += this.genRandomTime());
}
}
Have you tried cumulatively setting the timeout? Stick a variable outside of your loop and initialize it to 0. Let's call it timeout for now. Add a random amount of time to this variable at the beginning of each iteration of your loop, and make the timeout work off of that. This way, you are ensured that functions are being called in order.
Your problem is you are using one all your times are delayed starting from now - the next timer needs to be fired after the previous. Simply add the previous timer delay to the new timer.
typeString: function(s)
{
var delay = 0;
for(var i=0;i<s.length;i++)
{
var c = s.charAt(i);
delay = delay + this.genRandomTime();
var temp = setTimeout("MessageType.typeChar('" + c + "')", delay );
}
}
Instead of passing to each timer event that character to be displayed, let each event handler grab the next character off of a queue (array, list whatever), so the order is maintained.

Categories

Resources