I have a server (mysite.com/status), which returns number of active tasks (just a single integer).
How can I check number of active tasks each 10 seconds with JavaScript and show user something like:
Number of remaining tasks: XXX
And, if number of tasks is 0, then I should load another page.
Make a function set a new timeout calling itself.
function checkTasks(){
// Make AJAX request
setTimeout(checkTasks, 10000);
}
checkTasks(); // Start task checking
with jQuery for AJAX functions... (untested code)
setInterval(function(){
$.get('http://example.com/status',function(d){
// where there is html element with id 'status' to contain message
$('#status').text('Number of remaining tasks: '+d)
if(d == 0){
window.location = '/another/page'
}
})
},10000)
I have thought of different approach, without any AJAX. As you just need to show simple plain data, just use <iframe> to show that dynamic data then with simple JS "reload" the frame every 10 seconds.
HTML would be:
Number of remaining tasks: <iframe id="myFrame" src="mysite.com/status"></iframe>
And the JavaScript:
window.onload = function() {
window.setTimeout(ReloadTime, 10000);
};
function ReloadTime() {
var oFrame = document.getElementById("myFrame");
oFrame.src = oFrame.src;
window.setTimeout(ReloadTime, 10000);
}
Live test case, using time for the same of example.
With some CSS you can make the frame look like part of the text, just set fixed width and height and remove the borders.
setInterval(function(elem){ // here elem is the element node where you want to display the message
var status=checkStatus(); // supposing that the function which returns status is called checkStatus
if(status == 0){
window.location = '/another/page'
}
else {
elem.innerHTML="Number of remaining tasks:"+status;
}
},10000)
Using the javascript library jquery, you can set a repeating infinite loop.
That gets the data from a page and then sets the inner html of an element.
http://jsfiddle.net/cY6wX/14/
This code is untested
edit: demonstration updated
Also I did not use the jquery selector for setting the value in case you do not want to use jquery.
Related
I have an internet radio station and I need a script that will display a picture of the current song in a particular dvi with an id. The image is automatically uploaded via ftp to the server each time the song changes..
HTML:
<div id="auto"></div>
JS:
$ (document).ready(function() {
$('#auto').html('<img src="artwork.png"></img>');
refresh();
});
function refresh() {
setTimeout (function() {
$('#auto').html('<img src="artwork.png"></img>');
refresh();
}, 1000);
}
I tried this, but all I get is that the image is loaded, but in case of a change, I have to manually refresh the whole page again..
I'll point out multiple things here.
I think your code is just fine if you are going for the setTimeout recursive calls instead of one setInterval action to repeat it.
File Caching
your problem is probably the browser's cache since you are using the same image name and directory all the time. browsers compare the file name and directory and to decide to load it from its cache or else it will request it from the server. there are different tricks you can do to reload the image from the server in this particular case.
Use different file names/directories for the songs loaded dynamically
Use a randomized GET query (e.g. image.png?v=current timestamp)
Your method for switching
you are replacing the file with FTP, I wouldn't recommend that. maybe you should have all your albums and thumbnails uploaded to the server and use a different dynamic switching for efficiency and less error proneness and will help you achieve method #1 in the previous section better.
Loading with constant refresh
I would like to highlight that if you are using nodeJs or nginx servers - which are event based - you can achieve the same functionality with much less traffic. you don't need a refresh method since those servers can actually send data on specific events to the browser telling it to load a specific resource at that time. no constant refresh is required for this.
You consider your options, I tried to be as comprehensive as I could
At the top level, browser cache the image based on its absolute URL. You may add extra query to the url to trick browser that is another new image. In this case, new URL of artist.png will be artist.png?timestamp=123
Check this out for the refresh():
function refresh() {
setTimeout (function() {
var timestamp = new Date().getTime();
// reassign the url to be like artwork.png?timestamp=456784512 based on timestmap
$('#auto').html('<img src="artwork.png?timestamp='+ timestamp +'"></img>');
refresh();
}, 1000);
}
You may assign id attribute to the image and change its src url
html
<img id="myArtworkId" src="artwork.png"/>
js in the refresh method
$('#myArtworkId').attr('src', 'artwork.png?timestamp=' + new Date().getTime());
You can use window.setInterval() to call a method every x seconds and clearInterval() to stop calling that method. View this answer for more information on this.
// Array containing src for demo
$srcs = ['https://www.petmd.com/sites/default/files/Acute-Dog-Diarrhea-47066074.jpg',
'https://www.catster.com/wp-content/uploads/2018/05/Sad-cat-black-and-white-looking-out-the-window.jpg',
'https://img.buzzfeed.com/buzzfeed-static/static/2017-05/17/13/asset/buzzfeed-prod-fastlane-03/sub-buzz-25320-1495040572-8.jpg?downsize=700:*&output-format=auto&output-quality=auto'
]
$i = 0;
$(document).ready(function() {
$('#auto').html('<img src="https://images.pexels.com/photos/617278/pexels-photo-617278.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"></img>');
// call method after every 2 seconds
window.setInterval(function() {
refresh();
}, 2000);
// To stop the calling of refresh method uncomment the line below
//clearInterval()
});
function refresh() {
$('#auto').html('<img src="' + $srcs[$i++] + '"></img>');
// Handling of index out of bound exception
if ($srcs.length == $i) {
$i = 0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="auto"></div>
So i am working on a Userscript and there is one major step i'm trying to find the easiest resolve with since i am very new to Javascript coding...I'm trying to perform/code a function that will open a specified URL:
EXAMPLE: Homepage ("http://www.EXAMPLE.com")
(page can be opened as 'Window.open' = Blank, or _self);
...when the parent or (current) URL that is open
EXAMPLE: innner.href = ("www.EXAMPLE.com/new/01262016/blah/blah/blah");
...has a text on the HTML documnt page that reads:
EXAMPLE TEXT from page ("www.EXAMPLE.com/new/01262016/blah/blah/blah");:
"this is the end of the page, please refresh to return back to homepage"
(TEXT: not the real keyword, but want to use phase as a detection for a setTimeout function to return back to home.)
Any help will be much appreicated, you guys are veryinformative here. Thanks in advance.
I think I have the gist of you question. It is a straighforward, though quite intensive, task to scan the entire text content of a page for specific keywords with JavaScript. However, if the keywords appear more than once (on multiple pages that should not redirect) then your users will get undesirable results.
A simple solution would be to add a class="last-page" attribute to the body-tag of the final page and run a function that checks for this. Something like....
HTML
<body class="last-page"><!--page content--></body>
JS
window.onload = function() {
var interval = 5000; // five seconds
if (document.body.classList.contains('last-page')) {
setTimeout(function() {
window.location.assign('http://the-next-page.com/');
}, interval);
}
};
Alternatively, if you have the ability to wrap the specified text in a uniquely identified html-tag, such as...
<span id="last-page">EXAMPLE TEXT</span>
...then the presence of this tag can be checked on each page load - similar to the function above:
window.onload = function() {
var interval = 5000;
if (document.getElementById('last-page') {
setTimeout(/* code as before */);
}
};
Yet another solution is to check the page URL against a variable...
window.onload = function() {
var finalURL = 'http://the-last-page.com/blah/...';
if (window.location === finalURL) {
/* same as before */
}
};
If this kind of thing is not an option please leave a comment and I'll add a function that gathers a pages entire text content and compares adjacent words to a pre-defined set of keys.
What would be the most efficient way to show and hide iframes in a page every x time?
I was thinking on using a setInterval on a function that uses jQuery's hide and show but this seems inneficient and not very scalable if I needed to hide and show 1 out of 10 iframes in one page that I would also need to hide and show.
$(document).ready(function(){
setInterval(function() {
if ($('#basic').is(":visible") && $('#advanced').not(":visible") ) {
$('#basic').hide();
$('#advanced').show();
}else if($('#basic').not(":visible") && $('#advanced').is(":visible")) {
$('#basic').show();
$('#advanced').hide();
}else if($('#basic').is(":visible") && $('#advanced').is(":visible")) {
$('#basic').hide();
$('#advanced').show();
};
}, 30000);
});
Each id refers to 1 iframe so right now I am only dealing with 2 iframes. The reason I have that last if else statement is because both iframes are being displayed when I load the page.
Just a snippet since the OP asked for it. Posting as an answer so I can format the code a bit better. (warning: I haven't 100% tested it myself yet, this isn't meant as a copy/paste implementation.)
This should show all the hidden frames and hide all the visible frames every 30 sec.
You can obviously easily extend it to only show/hide specific nodes that you can reference by id since frames[theFramesID] will give you the reference and visible status. If you don't need to be able to access specific frames, you can obv simplify this and use an array instead of an object.
Just using some form of loop and caching your nodes instead of requerying the same node over and over again will already increase the scalability. Since you don't need to change the code once you add another frame.
One could probably replace the vanilla functions I used with jquery specific ones if needed. I'm not sure which version of jquery has built-in reduce.
$(document).ready(function(){
var frames = $('iframe').reduce(function ( accumulator, frame ) {
accumulator[frame.id] = {
'reference' : frame,
'visible' : frame.is(":visible")
};
return accumulator;
}, {});
setInterval(function() {
Object.keys(frames).forEach(function ( id ) {
var frame = frames[id];
if (frame.visible) {
frame.visible = false;
frame.reference.hide();
}
else {
frame.visible = true;
frame.reference.show();
}
});
}, 30000);
});
I'm having a few issues with the script below.
To explain the background, the full script gets data from a JSON feed and if it has been updated since the last check it changes a marker on a map and adds a line to an array called updata[], which is straightforward enough.
Once the JSON refresh is complete I then want to display a notification of each refreshed item inside a small notifiation div at the bottom of the screen for 1 second before disappearing. The process should repeat until updata[] is empty.
Any ideas what I'm doing wrong?
<script type='text/javascript'>
//updata[] is populated by JSON in the full version, but for now...
var updata=["Site A Updated at 00:20"," Site B Updated at 00:22"," Site C Updated at 00:24"];
var val=0;
var max=updata.length+1;
function addtodiv()
{
document.getElementById('alarms').innerHTML = '<span>'+window.val+':'+window.updata[window.val]+'</span>'
setTimeout(cleardiv(), 1000); // refresh in 1 secs
}
function cleardiv()
{
window.val++;
document.getElementById('alarms').innerHTML = '<span> </span>'
if (window.val==window.max)
{
window.val=0;
window.updata=[];
} else {
setTimeout(addtodiv(), 200); // refresh in 0.2 secs
}
}
addtodiv();
</script>
setTimeout accepts function reference as the first argument. So change your code:
setTimeout(cleardiv(), 1000);
to this:
setTimeout(cleardiv, 1000);
...
setTimeout(addtodiv, 200);
You don't want to invoke functions immediately cleardiv(), you just need to provide a reference.
$(document).ready(function() {
$('#domain').change(function() {
//
});
});
The code inside the change function will basically send ajax request to run a PHP script. The #domain is a text input field. So basically what I want to do is to send ajax requests as user types in some text inside the text field (for example search suggestions).
However, I would like to set a time interval in order to lessen the load of PHP server. Because if jQuery sends AJAX request every time user adds another letter to the text field it would consume lots of bandwidth.
So I would like to set let's say 2 seconds as an interval. The AJAX request will be fired every time the user types a letter but with maximum frequency of 2 seconds.
How can I do that?
$(function() {
var timer = 0;
$("#domain").change(function() {
clearTimeout(timer);
timer = setTimeout(function(){
// Do stuff here
}, 2000);
});
});
$(document).ready(function() {
var ajaxQueue;
$('#domain').change(function() {
if(!ajaxQueue) {
ajaxQueue = setTimeout(function() {
/* your stuff */
ajaxQueue = null;
}, 2000);
}
});
});
What you really want to do is check how long since the last change event so you keep track of the number of milliseconds between events rather than make a call every 2 seconds.
$(document).ready(function() {
var lastreq = 0; //0 means there were never any requests sent
$('#domain').change(function() {
var d = new Date();
var currenttime = d.getTime(); //get the time of this change event
var interval = currenttime - lastreq; //how many milliseconds since the last request
if(interval >= 2000){ //more than 2 seconds
lastreq = currenttime; //set lastreq for next change event
//perform AJAX call
}
});
});
Off the top of my head without trying this in a browser. Something like this:
$('#domain').change(function() {
if (!this.sendToServer) { // some expando property I made up
var that = this;
this.sendToServer = setTimeout(function(that) {
// use "that" as a reference to your element that fired the onchange.
// Do your AJAX call here
that.sendToServer = undefined;
}, yourTimeoutTimeInMillis)
}
else {
clearTimeout(this.sendToServer);
}
});
two variables, charBuffer, sendFlag
Use a setTimeout to have a function be called every two seconds.
This function checks if the buffer has stuff in it.
If it does, it sends/empties the stuff and clears the sent flag (to false).
and It should also clear the timeout, and set it again
else it sets the flag (to true).
Everytime the user hits a key, store it in the buffer.
if the sent flag is clear (it's false), do nothing.
else (it's true) send/empty the stuff currently in the buffer and clear the flag (to false),
and It should also clear the timeout, and set it again
This will make it so that the first time you press a key, it is sent, and a minimum of 2 seconds must pass before it can send again.
Could use some tweaking, but i use this setup to do something similar.
I am coming across this problem more and more (the more i do UI ajax stuff) so i packaged this up into a plugin available here