i'm creating a chrome extension. i have an array of urls and i want to download them all one by one, one at a time (meaning the second download will start only after the first one finished etc...)
i've tried this: ("links" is the array)
function doDownloads(links, iterator, max) {
chrome.downloads.download({
url: links[iterator],
saveAs: false
}, function(downloadId) {
if (iterator < max)
chrome.downloads.onChanged.addListener(function goToNextDL(delta) {
if (delta.id == downloadId) {
chrome.downloads.onChanged.removeListener(goToNextDL);
if (delta.state && delta.state.current === 'complete' && iterator + 1 < max)
doDownloads(links, iterator + 1, max);
}
});
});
}
but it doesn't work ):
any ideas?
This should work...
var Dest='';
for(var i=0; i<links.length; i++){
Dest='image'+i+'.jpg';
chrome.downloads.download({url:links[i] ,filename:Dest, conflictAction:'overwrite'});
}
NB: I've added simple logic for changing the destination file name.
How's this method?
var Counter=0; // global var
function DownloadURL(URL){
var DL=new XMLHttpRequest();
DL.onload=function(evt){var arraybuffer=DL.response;};
DL.addEventListener('load', function(evt){ Counter++; if(Counter<Links.length){DownloadURL(Links[Counter]);} }); // increment to next file
DL.open('GET',URL,true);
DL.responseType='arraybuffer';
DL.send();
}
Call it once to get the ball rolling...
DownloadURL(Links[Counter]);
After a few more tries, I got the solution to my problem.
Here is the correct code:
function doDownloads(links, iterator, max) {
chrome.downloads.download({
url: links[iterator],
saveAs: false
}, function(downloadId) {
if (iterator < max + 1)
var goToNextDL = function(delta) {
if ((delta.id == downloadId) && (delta.state) && (delta.state.current != "in_progress")) {
chrome.downloads.onChanged.removeListener(goToNextDL);
if (delta.state.current === 'complete')
doDownloads(links, iterator + 1, max);
}
};
chrome.downloads.onChanged.addListener(goToNextDL);
});
}
var array_of_links = [...];
doDownloads(array_of_links, 0, array_of_links.length);
Related
I'm trying to make a web page that has its wallpaper change every time you refresh. I'd like it to display the next image in the array every time the page is refreshed. So every refresh works its way through the list until the end, and then starts over.
Right now I'm using an array and accessing it with a random index, but I need to access it using one that increases by 1 each time, and once I reach the array length I need it to start over again... Right now I'm using this (which took me forever to figure out):
$(function background() {
var images = [
"wallpaper1.jpg",
"wallpaper2.jpg",
"wallpaper3.jpg",
"wallpaper4.jpg"
];
$("#hero").css({
"background-image":
"url(images/wallpapers/" +
images[Math.floor(Math.random() * images.length)]
+ ")"
});
});
I have found out about incrementing numbers in an array using this:
var arr = [1,2,3,4];
arr = arr.map(function(val){return ++val;});
console.log(arr);
But I can't seem to get the number solution to work with strings. I'm ultra new at all this and I am losing my mind :/
You need to save a counter to localStorage that you can retrieve on each page load, increment,, make the check, and then save again.
$(function () {
const images = [
'wallpaper1',
'wallpaper2',
'wallpaper3',
'wallpaper4'
];
// We must check to see if localStorate exists before
// we do anything
function hasLocalStorage() {
try {
localStorage.setItem('count', 0);
if (localStorage.getItem('count') === '0') {
return true;
}
} catch(e) {
return false;
}
return false;
}
// Fetch the count from localStorage. Because it's
// saved as a string we need to coerce it to a number
let count = Number(localStorage.getItem('count'));
$("#hero").css({
'background-image': `url(${images[count]})`
});
// Increase the count
count++;
// If the count is the length of the array (minus one
// because the array is indexed-based) set the
// localStorate count to zero, otherwise save the count
if (count === images.length - 1) {
localStorage.setItem('count', 0);
} else {
localStorage.setItem('count', count);
}
});
You can add a helper function to do this:
var getNextImage = (() => {
var i = 0;
return () => {
if (i >= images.length)
{
i = 0;
}
return images[i++];
};
})();
and then replace the images[Math.floor(Math.random() * images.length)] call with getNextImage()
Like so:
$(function background() {
var images = [
"wallpaper1.jpg",
"wallpaper2.jpg",
"wallpaper3.jpg",
"wallpaper4.jpg"
];
var getNextImage = (() => {
var i = 0;
return () => {
if (i >= images.length)
{
i = 0;
}
return images[i++];
};
})();
$("#hero").css({
"background-image":
"url(images/wallpapers/" + getNextImage() + ")"
});
});
<!DOCTYPE html>
<html>
<body>
<script>
// Checking if the Local Storage feature is available.
if (typeof(Storage) !== "undefined") {
// If it is available, check if there is a value stored by the name 'val'.
if(localStorage.getItem("val") != null) {
// If yes increase it by 1.
localStorage.setItem("val", parseInt(localStorage.getItem("val")) + 1);
}
else {
// If no then create one and set it to 1.
localStorage.setItem("val", 1);
}
// Printing the value on the console and the page to check if it is working (You can remove this later.)
console.log(localStorage.getItem("val"));
document.write(localStorage.getItem("val"));
}
// If it is not available notify the user.
else {
console.log("Sorry, your browser does not support Web Storage...");
document.write("Sorry, your browser does not support Web Storage...");
}
var num = parseInt(localStorage.getItem("val"));
</script>
</body>
</html>
Local Storage is a feature is in HTML. It can be used to store data in the tab and will be there as long as the tab isn't closed. So, now whenever you reload your page you will get the next number starting from one.
Possible, but the persistence is only becuase of the localStorage
Hey! Check this out.
This basically selects an image from the array and then changes the background continuously according to the current image. If the last image (when the user last visited the page) was wallpaper4.jpg, the next would be automatically the wallpaper1.jpg.
Assuming that the target browser has localStorage enabled, this would be the JavaScript code
var images = [
"wallpaper1.jpg",
"wallpaper2.jpg",
"wallpaper3.jpg",
"wallpaper4.jpg"
];
getBgImage = () => {
var lastImage = localStorage.getItem("wallpaperIdx");
if (lastImage && images.indexOf(lastImage) < (images.length - 1) && images.indexOf(lastImage) >= 0) {
localStorage.setItem("wallpaperIdx", images[(images.indexOf(lastImage) + 1)]);
return images[(images.indexOf(lastImage) + 1)];
} else if (images.indexOf(lastImage) === (images.length - 1)) {
localStorage.setItem("wallpaperIdx", images[0]);
return images[0];
} else {
localStorage.setItem("wallpaperIdx", images[0]);
return images[0];
}
}
$(function () {
setInterval(() => {
var image = getBgImage();
$('#hero').css({
"background-image": `url("images/wallpapers/${image}")`,
"transition": "1s"
});
}, 1000)
clearInterval();
});
$(() => {
$(window).on("load", () => {
document.getElementById("hero").style.backgroundImage = `url("images/wallpapers/${image}")`;
})
})
Javascript array:
var urls = ['https://www.google.com', 'https://www.msn.com', 'https://stackoverflow.com'];
I am having the array of URLs. I want to open each URL every 15 seconds in a new tab or window.
function g(){
setTimeout(o, 1);
}
function o(){
window.open('page.php');
}
The above code is not working.
I think you are finding setInterval.
var urls = ['https://www.google.com', 'https://www.msn.com', 'https://stackoverflow.com'];
var index = 0;
var interval = setInterval(o, 15000);
function o() {
if (typeof urls[index] !== typeof undefined) {
window.open(urls[index]);
index++;
} else {
clearInterval(interval);
}
}
Fiddle
I am using google maps and i am trying to put a pause in execution to prevent QUERY_LIMIT usage issue. My function that plots the addresses looks like this.
The code works, however i want to try setTimeout or setInterval to see if its going to look better on UI.
How do i call it, what should be the first argument?
Thanx alot.
vLocations = [];
for (var i = 0; i < vAddresses.length; i++) {
//pause to prevent OVER_QUERY_LIMIT issue
//geocode "free" usage limit is 5 requests per second
//setTimeout(PlotAddressesAsUnAssigned, 1000);
//sleep(500);
//this will resolve the address and store it in vLocations
AddWaypointAndUnassigned(vAddresses[i]);
var z = i % 4;
if (z==0 && i != 0) {
//sleep after every 5th geocode call
//alert('going to sleep...i: ' + i);
//sleep(3000);
}
}
Doing a pause (asynchronous execution) inside a loop (synchronous) will usually result in a lot of trouble.
You can use recursive calls that are done only when a timeout ends.
var vLocations = [];
// Manages the timeout and recursive calls
function AddWaypointAndUnassignedWithPause(index){
setTimeout(function(){
// When the timeout expires, we process the data, and start the next timeout
AddWaypointAndUnassigned(vAddresses[index]);
// Some other code you want to execute
var z = i % 4;
if (z==0 && i != 0) {
//sleep after every 5th geocode call
//alert('going to sleep...i: ' + i);
//sleep(3000);
}
if(index < vAddresses.length-1)
AddWaypointAndUnassignedWithPause(++index);
}, 1000);
}
// Start the loop
AddWaypointAndUnassignedWithPause(0);
JSFiddle example.
Try this, hope this will help
vLocations = [];
for (var i = 0; i < vAddresses.length; i++) {
//pause to prevent OVER_QUERY_LIMIT issue
setTimeout(function(){
//this will resolve the address and store it in vLocations
AddWaypointAndUnassigned(vAddresses[i]);
}, 500);
var z = i % 4;
if (z==0 && i != 0) {
//sleep after every 5th geocode call
//alert('going to sleep...i: ' + i);
//sleep(3000);
}
}
What about a waiting line, thats fired when an item is added and stopped when there are no items left.
With setTimeout:
var INTERVAL = 1000 / 5;
var to = null;
var vLocations = [];
function addAddress(vAddress) {
vLocations.push(vAddress);
startTimeout();
}
function startTimeout() {
if( to === null ) {
to = setTimout(processLocation, INTERVAL);
}
}
function processLocation() {
if( vLocations.length ) {
var vAddress = vLocations.shift();
AddWaypointAndUnassigned(vAddress);
to = setTimout(processLocation, INTERVAL);
} else {
to = null;
}
}
With setInterval:
var INTERVAL = 1000 / 5;
var to = null;
var vLocations = [];
function addAddress(vAddress) {
vLocations.push(vAddress);
startInterval();
}
function startInterval() {
if( to === null ) {
to = setInterval(processLocation, INTERVAL);
}
}
function processLocation(cb) {
if( vLocations.length ) {
var vAddress = vLocations.shift();
AddWaypointAndUnassigned(vAddress);
} else
clearInterval(to);
to = null;
}
}
So I have a loop, which performs an ajax call on each iteration and I want to set the progress bar updated.. But it is not updating, it goes to 100% directly when ending...
I've tried to put the bar update call outside the success action (inside the loop directly) but it isn't working either..
$('button.page').on('click', function(e){
var $userList = textArray($('#page-userlist').val().replace('http://lop/', '').split(/\n/));
var $proxyList = textArray($('#page-proxylist').val().replace('http://', '').split(/\n/));
var $question = $('#page-question').val();
var data = {
question: $question,
users: $userList,
proxies: $proxyList
};
var i = 0, p = 0, max = data.proxies.length, totalusers = data.users.length, percent = 0;
$('#log').append("\n" + moment().calendar() + "\n");
var progressbar = $('#page-progress');
$.each(data.users, function(k, u){
if(typeof(p) !== 'undefined' && p !== null && p > 0)
{
if(i % 10 == 0 && i > 1) p++;
if(p == max) return false;
}
var proxy = data.proxies[p];
percent = Math.round((i / totalusers) * 100);
$.ajax({
type: "POST",
url: Routing.generate('viral_admin_bot_page'),
data: {question: $question, user: u, proxy: proxy},
success: function(result) {
$('#log').append("\nAtacado usuario " + u + " con proxy: " + proxy + "\n");
$(progressbar).width(percent + "%");
},
error: function(error) {
$('#log').append(error);
}
});
i++;
});
});
If i do console.log(percent); it is updating perfectly on each iteration, so I don't know where can be the problem.
Here is my code (without the ajax call because it isn't the problem) http://jsfiddle.net/dvo1dm03/20/
it will output to console the percentage, the objetive is to update the bar to the percentage completed in each loop, so it goes in "realtime" with loop.
Ok, here's how to do it asynchrounously.
var speed = 75;
var number_of_calls_returned = 0; // add number_of_calls_returned++ in your ajax success function
var number_of_total_calls;
var loaded = false;
function processUserData(){
if( number_of_calls_returned < number_of_total_calls){
setTimeout(function(){processUserData();}, 200);
}
else{
//received all data
// set progressbar to 100% width
loaded = true;
$("#page-progress").animate({width: "100%"},500);
$("#page-proxylist").val("Received data");
}
}
function updateProgress(percent, obj){
setTimeout(function(x){
if(!loaded)
$(obj).width(x + "%");
}, percent*speed, percent);
}
$('button.page').on('click', function (e) {
var $userList = textArray($('#page-userlist').val().replace('http://lop/', '').split(/\n/));
var $proxyList = textArray($('#page-proxylist').val().replace('http://', '').split(/\n/));
var $question = $('#page-question').val();
var data = {
question: $question,
users: $userList,
proxies: $proxyList
};
var i = 0,
p = 0,
max = data.proxies.length,
totalusers = data.users.length,
percent = 0;
//$('#log').append("\n" + moment().calendar() + "\n");
var progressbar = $('#page-progress');
number_of_total_calls = totalusers;
$.each(data.users, function (k, u) {
if (typeof (p) !== 'undefined' && p !== null && p > 0) {
if (i % 10 == 0 && i > 1) p++;
if (p == max) return false;
}
var proxy = data.proxies[p];
percent = (i / totalusers) * 100; //much smoother if not int
updateProgress(percent, progressbar);
i++;
// simulate ajax call
setTimeout(function(){number_of_calls_returned++;}, Math.random()*2000);
});
//callback function
setTimeout(function(){processUserData();}, 200);
});
var textArray = function (lines) {
var texts = []
for (var i = 0; i < lines.length; i++) {
// only push this line if it contains a non whitespace character.
if (/\S/.test(lines[i])) {
texts.push($.trim(lines[i]));
}
}
return texts;
}
Check it out here! jsFiddle (really cool!)
Your problem is cause by the fact that you have a closure for your success function and every success function shares the same percent variable. You can fix it like this:
success: function(percent, result) {
$('#log').append("\nAtacado usuario " + u + " con proxy: " + proxy + "\n");
$(progressbar).width(percent + "%");
}.bind(percent),
Where you'll need to shim bind in older browsers, or like this, which is a little uglier, but should work everywhere without a shim:
success: (function(percent) { return function(result) {
$('#log').append("\nAtacado usuario " + u + " con proxy: " + proxy + "\n");
$(progressbar).width(percent + "%");
}; }( percent ),
if what you want is to increase the update bar with each success of AJAX calls I'd suggest an easier solution (I've simplified the js code for clarity's sake):
$('button').click(function (e) {
var i = 0,
cont = 0,
totalusers = 100,
percent = 0;
var progressbar = $('#page-progress');
for (; i < totalusers; i++) {
$.ajax({
type: "POST",
url: '/echo/json/',
data: {
question: 'something',
user: 1,
proxy: 2
},
success: function (result) {
cont += 1;
percent = Math.round((cont / totalusers) * 100);
progressbar.width(percent + "%");
},
error: function (error) {
$('#log').append(error);
}
});
};
});
You can see it in action in this fiddle.
Hope this helps or at least give you some ideas.
Update the progress bar using setTimeout method.
it will wait for some time and then update the width of progressbar.
myVar = setTimeout("javascript function",milliseconds);
Thanks,
Ganesh Shirsat
I would like to make a recommendation of trying to make a self contained example that doesn't rely on the post so that it is easier for you or us to solve the problem
As well, you can console log elements so you could try logging the progressbar element, percent and the response of the ajax request
(This code is to replace the javascript sections of the fiddler)
var i = 0;
moveProgress();
function moveProgress(){
if(i < 10000)
{
setTimeout(function(){
$('#page-progress').width((i / 1000) * 100);
moveProgress();
},2);
i++;
}
}
The reason that it wasn't working was because the loop ran so fast that it was loaded by the time the script loaded it, the timeout allows you to delay the execution a bit(Though not necessarily recommended to use because of potential threading issues.
I'm currently looking for a way to load in multiple scripts/plugins without having a laundry list listed out in the header.
To simply have a load.js have everything load in would be very elegant to me.
$(function() {
var scripts = ['scripts/jquery1.5.js','scripts/easing.js','scripts/scroll.js','scripts/main.js'];
for(var i = 0; i < scripts.length; i++) {
$.getScript(scripts[i]);
}
})
I currently have something like this but can't get it to work for some reason. Any ideas?
Have you looked at head.js?
Here is my conclusion for head.js, I have done some benchmarks myself:
http://blog.feronovak.com/2011/03/headjs-script-is-it-really-necessary.html
It is subjective opinion and benchmarks are not by any means scientific.
This is my solution : check if file is added (stored in array) and then load one file after another. Works perfectly!
var filesadded = "" //list of files already added
function loadJSQueue(array, success) {
if (array.length != 0) {
if (filesadded.indexOf("[" + array[0] + "]") == -1) {
filesadded += "[" + array[0] + "]" //List of files added in the form "[filename1],[filename2],etc"
oHead = document.getElementsByTagName('head')[0];
var oScript = document.createElement('script');
oScript.type = 'text/javascript';
oScript.src = array[0];
array.shift();
oScript.onreadystatechange = function () {
if (this.readyState == 'complete') {
loadJSQueue(array, success);
}
}
oHead.appendChild(oScript);
}
else {
array.shift();
loadJSQueue(array, success);
}
}
else {
success();
}
}
call it with
loadJSQueue(["../../JavaScript/plupload/js/jquery.plupload.queue/jquery.plupload.queue.js",
"../../JavaScript/plupload/js/plupload.js",
"../../JavaScript/plupload/js/plupload.html4.js"
], function(){alert("success");})
loadScripts(['script1.js','script2.js'], function(){ alert('scripts loaded'); }
function loadScripts(scripts, callback){
var scripts = scripts || new Array();
var callback = callback || function(){};
for(var i = 0; i < scripts.length; i++){
(function(i) {
$.getScript(scripts[i], function() {
if(i + 1 == scripts.length){
callback();
}
});
})(i);
}
}