how to place time condition in this code? - javascript

Here is the block of code. The facebook page keeps loading until string "End of results" found and then this function exits. Sometimes this takes more than 30 minutes of loading therefore I want to work it like
if ( string "end of results" found OR 5 minutes passed)
so this will be bound to 5 minutes or less if string found earlier. Thank you
var nodes = [].slice.call(document.getElementsByClassName('_64f'));
var bottomNode = nodes.filter(function isBottomNode(el) {
return !!(
el &&
el.textContent &&
el.textContent.indexOf('End of Results')=== 0
);
});
return !!bottomNode.length;
}

Focusing just with the 5 Min delay. You can use javascript setTimeout() which gives a delay of 5 min.
var nodes = [].slice.call(document.getElementsByClassName('_64f'));
var bottomNode = nodes.filter(function isBottomNode(el, isForced = false) {
return !!(
(el && el.textContent && el.textContent.indexOf('End of Results')=== 0)
|| isForced === true
);
});
return !!bottomNode.length;
}
Here is the set time out now,
var isForced = false;
setTimeout(function(){
isForced = true;
}, 60*5);
// When calling the function
isBottomNode(el, isForced);

Sorry for being late, my free times is very low.
Try code below. i have added some important descriptions to it as inline comments (you can check the result with clicking Run code snippet button):
window.onload=function(){
//This is the element that 'End Of Results' will add to it
var mC = document.getElementById('must-capture');
var ti2=setTimeout(function(){
alert("timeout!! not found!");
}, 10000/*for 5 minutes use 5*60*1000*/);
var obs=new MutationObserver(function(list){
var fnd=0;
list.every(function(c){
Array.prototype.every.call(c.addedNodes, function(n){
if(n.innerHTML.indexOf("End Of Results")>-1){
obs.disconnect()
fnd=1;
return false;
}
});
if(fnd) return false;
});
if(fnd) {
clearTimeout(ti2);
//put the codes you need here...
console.log("It's just same time that 'End Of Results' is ready to be added!!");
}
});
obs.observe(mC, { characterData: true, childList: true, subtree: true });
//TIP:
//Now we need to simulate adding new contents to page with specified intervals. one of this contents is same "End Of results" text. (this part is not needed in final project and will happen automatically as you said in your original question):
var i=0,
texts=["hello", "salam", "test", "sample", "tavakkol", "bttola", "End Of Results"];
var ti=setInterval(function(){
var d=document.createElement("div");
d.innerHTML=texts[i++];
mC.appendChild(d);
if(i==7) clearInterval(ti);
}, 500);
};
<!-- The element that 'End Of Results' will be added to it.
this must be the wrapper element that desired text will be added to it later. -->
<div id='must-capture'></div>
But, if you need to the code runs on IE9 or because any reason you like to use timers, you must combine two timers together. one for running in short delays (for example per 2 seconds) that you must run your above code there (for finding childs and check for existing 'End Of Results' text). in body of it, you must call clearTimeout of another timer that you must create it for run just after 5 minuts.

Related

Check is class exist longer than X in javascript

I wrote simple monitor which check few things on my networks and display status - I am fetching statuses using ajax.
When something is wrong I am adding class error to div which is displaying current status.
Later I add player with error sound when class error is present it plays music. I set 3 second interval and thats all.
But not always error mean error, sometimes I recive false warning.
Now I am looking for way to play sound when class error exists longer than XX seconds.
I suppose I have to wrote function with interval 1s, add every hit 1 to temp variable and check is variable bigger than else clean temp variable, but maybe is there more elegant way.
i guess it should work
$('.error').each(function(){
var e = $(this)
setTimeout(function(){
if (e.attr('class') == 'error'){
e.attr('class','error-with-sound');
}
},2000);
});
You should take two vars store the current time at their respective events.
var oldTime, newTime;
// Now when you are adding the class
$(something).addClass("someclass");
oldTime = new Date().getTime(); // Store the timestamp.
//And when you are removing the class
$(something).removeClass("someclass");
newTime = new Date().getTime(); // Store the timestamp.
// Now you check whether class was added for more then XX Seconds
var _diff = (newTime - oldTime)/1000; // Diference is in seconds.
There is no direct way for that, you can add timestamps in your class with separator something like error_1448953716457 and later you can split that and can compare with current timestamps
$('#na').click(function () {
var t = new Date().getTime();
$('h1').addClass("error_" + t);
});
$('#nr').click(function () {
var t = new Date().getTime();
$("[class^=error]").each(function (e) {
$("span").html("Diff. Seconds : " + ((t - ($(this).attr('class').split(' ').pop().split('_')[1])) / 1000).toString());
});
});
input {
width:100px;
}
.error {
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<h1>.addClass()</h1>
<input id="na" value="Add Class1" type="button" />
<br/>
<input id="nr" value="Calculate Diff" type="button" />
<span></span>
If you want to track .error elements on the page, set an independent interval that looks for those elements and tracks the ones it has seen before by setting an attribute or data value in jquery.
Remember to clearInterval(interval) if you no longer need to check for .error elements.
(function ($) {
// set constants in milliseconds as desired
var INTERVAL_LENGTH = 100, // how often to check DOM for error elements
NOTIFY_AFTER = 3000; // handle error after this length
// check for .error elements and handle those that have been around for a while
var interval = setInterval(function () {
var now = Date.now();
$(".error").each(function () {
var t = $(this).data('error-time');
if(t) {
if(now - t > NOTIFY_AFTER) {
handleErrorElement(this);
}
}
else {
$(this).data('error-time', now);
}
});
}, INTERVAL_LENGTH);
function handleErrorElement(elem) {
// do what you need for error elements visible past a threshold
console.log("handling error element: ", elem);
}
})(jQuery);

JS Browser with pause function, help please

I wrote this program in js that goes through a list of URLs, where it stays on each page for a few seconds, closes the current window, and open the next in line. Everything works perfect, now I need it to stop/pause every 5 links. The second part of this project would be to create my own browser that open up like a program and there would be three buttons (start, continue, stop, maybe pause as well). I'd like start button to obviously start the function which goes through the pages, continue would be when it pauses on the fifth link I'd like a pop up message to say "wake up" and have the option to click "ok" only. Then you would have to click on continue in order for the function to continue. Stop would stop the function no matter where it has reached in the list. I'd like the links to show up in my browser not in Google Chrome or any other. What program should I use to design the browser? Here is the code of the current program:
var urlList = ['www.youtube.com',
'www.google.com',
'www.bing.com',
'www.yahoo.com',
'www.facebook,com',
'www.windows.com',
'www.opera.com',];
var wnd;
var curIndex = 0; // a var to hold the current index of the current url
function openWindow(){
wnd = window.open(urlList[curIndex], '', '');
if (curIndex % 5 == 0) {
}
setTimeout(function () {
wnd.close(); //close current window
curIndex++; //increment the index
if(curIndex < urlList.length) openWindow(); //open the next window if the array isn't at the end
}, 4000);
}
openWindow();
Help me finish the if statement...
Add a variable for your timeout period, instead of using the value 4000. Note that it must have global scope. I've added a variable calleddelay here:
var wnd;
var curIndex = 0; // a var to hold the current index of the current url
var delay;
Then, use the new variable in your openWindow() function, setting its value to a longer period in your if statement when you want the pauses to happen.
I've used a ternary operator here for instead of an if statement, but you could use an if statement just as well:
function openWindow(){
wnd = window.open('http://' + urlList[curIndex], '', '');
// pause for 30 seconds instead of 4 if the condition is met
delay = (curIndex > 0 && curIndex % 3 == 0 ? 30000 : 4000)
setTimeout(function () {
wnd.close(); //close current window
curIndex++; //increment the index
if(curIndex < urlList.length) openWindow(); //open the next window if the array isn't at the end
}, delay);
}

setTimeout executes itself right away/on clear

I'm making a webpage where user events are logged in.
To test the feature I made a small, independant webpage with a teaxtarea and a text input. The events logged are those performed on the input element.
I want to prevent the same event text to be shown multiple times in a row, but I can't seem to prevent them from showing up!
I also want to add a line to separate event groups 0.5 seconds after no other event happened, but the line seems to appear on every event trigger, evenif I use clearTimeout with the timeout ID.
Basically: I don't want any line to be repeated. If the last line is a separator line, then it must not add another one. Yet it doesn't see to work.
JSFiddle Demo
Here is my code:
JavaScript
var timerID = 0;
function addSeparateLine()
{
document.getElementById('listeEvenements').value += "--------------------\n";
}
function show(newEventText)
{
var eventListField = document.getElementById('listeEvenements');
var eventList = [];
if (eventListField.value.length > 0)
{
eventList = eventListField.value.split("\n");
}
var eventCounter = eventList.length;
if (eventList[eventCounter - 2] == newEventText)
{
clearTimeout(timerID);
newEventText = "";
}
timerID = setTimeout(addSeparateLine, 500);
if (newEventText !== "")
{
eventListField.value += newEventText + "\n";
}
return true;
}
HTML
<fieldset id="conteneurLogEvenements">
<legend>Events called from HTML attribute</legend>
<textarea id="listeEvenements" rows="25"></textarea>
<input id="controleEcoute" type="text" onBlur="show('Blur');" onchange="show('Change');" onclick="show('Click');" onfocus="show('Focus');" onMousedown="show('MouseDown');" onMousemove="show('MouseMove');" onMouseover="show('MouseOver');" onkeydown="show('KeyDown');"
onkeypress="show('KeyPress');" onkeyup="show('KeyUp');" />
</fieldset>
http://jsfiddle.net/z6kb4/2/
It sounds like what you want is a line that prints after 500 milliseconds of inactivity, but what your code currently says to do is "print a line 500 milliseconds after any action, unless it gets canceled". You can get better results by structuring the code more closely to your intended goal.
Specifically, instead of scheduling a new timeout every time an event occurs, simply start a loop when the first event occurs that checks the time that has elapsed since the most recent event received and then prints a line when the elapsed time exceeds the desired threshold (500 milliseconds). Something like:
function addSeparateLine() {
var elapsed = new Date().getTime() - lastEventTime;
if (elapsed >= 500) {
document.getElementById('listeEvenements').value += "--------------------\n";
clearInterval(timerID);
timerID = -1;
}
}
...and then you schedule it like:
if(newEventText !== "") {
lastEventTime = new Date().getTime();
eventListField.value += newEventText+"\n";
if (timerID == -1) {
timerID = setInterval(addSeparateLine,100);
}
}
Working example here: http://jsfiddle.net/z6kb4/4/
Because you are not actually stopping the show function in any way. The clearTimeout only applies to the separator add. I have updated your fiddle. You need to wrap your function with
if (+new Date() - lastfire < 500) return;
and
lastfire = +new Date();
(before the last return--see the updated fiddle). Also, make sure to stick the global definition var lastfire = -1; somewhere up top.

Count the number of mouse clicks in one second

Hi I'm working on an application that I want to improve the performance.(I know the question is kinda lengthy one- I apologize.)
I will explain in detail its a bidding application that uses only qtscript/qscript(kinda javascript) and no html.
When a user click on a Button, I want to point to a text field(For a normal user its okay like -1 or 2 clicks per second). But the user crazily click on button(5 -10 clicks per second - yeah some people click like that), it decreases the performance like the amount take delay to display because every click it points to focus on text field.
I'm thinking of some work around like if the user clicks more than 3 times in 1 second we call the focus function only after the last click- I don't know this is a right solution if you guys know anything better please suggest. Another problem is I can't use setInterval() and clearInterval().
Any help would be greatly appreciated.
I would take a look at Underscore.js's _.throttle function.
_.throttle = function(func, wait, options) {
var context, args, result;
var timeout = null;
var previous = 0;
options || (options = {});
var later = function() {
previous = options.leading === false ? 0 : new Date;
timeout = null;
result = func.apply(context, args);
};
return function() {
var now = new Date;
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
clearTimeout(timeout);
timeout = null;
previous = now;
result = func.apply(context, args);
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
};
};
It looks really complex, but a basic example would be:
var func = function(){alert("Only do this once every second");},
throttled = _.throttle(func, 1000);
// Call func() three times in under a second, and
// you get 3 message boxes
func(); // alerts
func(); // alerts
func(); // alerts
// Call throttled() three times in under a second, and
// you only get a message box the first time
func(); // alerts
throttled(); // does nothing
throttled(); // does nothing
// ... wait >1 second ...
func(); // alerts
throttled(); // does nothing
throttled(); // does nothing
example.xhtml - No frameworks, no script elements in the body and counts both left and right clicks.
Additionally you can add e.preventDefault(); at the end of the anonymous onclick event function. Keep in mind that if you're trying to protect content you will ultimately fail against anyone smart enough to realize that if it's already on their computer (memory, cache, etc) that they already have it in their possession. If you're trying to protect images you must use watermarks.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Click Counter</title>
<script type="application/javascript">
//<![CDATA[
var click_left = 0;
var click_right = 0;
window.onclick = function(e)
{
if (e.which==1) {click_left++;}
else if (e.which==3) {click_right++;}
alert('Left clicks: '+click_left+'\n\nRight Clicks: '+click_right);
}
//]]>
</script>
</head>
<body>
<div><p>Left or right click</p></div>
</body>
</html>
First of all you should add check that the text edit you want to select after user clicked certain button already has focus. That will dramatically reduce loading on event queue.
Second you can implement your own button (by subclassing) and play around with options, like for example just ignore clicks which came within certain (small) interval. In case user starts spawning clicks very fast, you can also 'visualise' it on a button in certain way, showing to a user that your application had limit reactions on user input, switching it off after specified timeout.

display message javascript while a calculation is being made

I have been looking around and I cannot seem to figure out how to do this, although it seems like it would be very simple.(mobile development)
What I am trying to do is display a message (kind of like an alert, but not an alert, more like a dialog) while a calculation is being made. Simply like a Loading please wait. I want the message to appear and stay there while the calculation is being done and then be removed. I just cannot seem to find a proper way of doing this.
The submit button is pressed and first checks to make sure all the forms are filled out then it should show the message, it does the calculation, then hides the message.
Here is the Calculation function.
function scpdResults(form) {
//call all of the "choice" functions here
//otherwise, when the page is refreshed, the pulldown might not match the variable
//this shouldn't be a problem, but this is the defensive way to code it
choiceVoltage(form);
choiceMotorRatingVal(form);
getMotorRatingType();
getProduct();
getConnection();
getDisconnect();
getDisclaimer();
getMotorType();
//restore these fields to their default values every time submit is clicked
//this puts the results table into a known state
//it is also used in error checking in the populateResults function
document.getElementById('results').innerHTML = "Results:";
document.getElementById('fuse_cb_sel').innerHTML = "Fuse/CB 1:";
document.getElementById('fuse_cb_sel_2').innerHTML = "Fuse/CB 2:";
document.getElementById('fuse_cb_result').innerHTML = "(result1)";
document.getElementById('fuse_cb_res_2').innerHTML = "(result2)";
document.getElementById('sccr_2').innerHTML = "<b>Fault Rating:</b>";
document.getElementById('sccr_result').innerHTML = "(result)";
document.getElementById('sccr_result_2').innerHTML = "(result)";
document.getElementById('contactor_result').innerHTML = "(result)";
document.getElementById('controller_result').innerHTML = "(result)";
//Make sure something has been selected for each variable
if (product === "Choose an Option." || product === "") {
alert("You must select a value for every field. Select a Value for Product");
**************BLAH************
} else {
//valid entries, so jump to results table
document.location.href = '#results_a';
******This is where the message should start being displayed***********
document.getElementById('motor_result').innerHTML = motorRatingVal + " " + motorRatingType;
document.getElementById('voltage_res_2').innerHTML = voltage + " V";
document.getElementById('product_res_2').innerHTML = product;
document.getElementById('connection_res_2').innerHTML = connection;
document.getElementById('disconnect_res_2').innerHTML = disconnect;
if (BLAH) {
}
else {
}
populateResults();
document.getElementById('CalculatedResults').style.display = "block";
} //end massive else statement that ensures all fields have values
*****Close out of the Loading message********
} //scpd results
Thank you all for your time, it is greatly appreciated
It is a good idea to separate your display code from the calculation code. It should roughly look like this
displayDialog();
makeCalculation();
closeDialog();
If you are having trouble with any of those steps, please add it to your question.
Computers are fast. Really fast. Most modern computers can do several billion instructions per second. Therefore, I'm fairly certain you can rely on a a setTimeout function to fire around 1000ms to be sufficient to show a loading message.
if (product === "Choose an Option." || product === "") {
/* ... */
} else {
/* ... */
var loader = document.getElementById('loader');
loader.style.display = 'block';
window.setTimeout(function() {
loader.style.display = 'none';
document.getElementById('CalculatedResults').style.display = "block";
}, 1000);
}
<div id="loader" style="display: none;">Please wait while we calculate.</div>
You need to give the UI main thread a chance to render your message before starting your calculation.
This is often done like this:
showMessage();
setTimeout(function() {
doCalculation();
cleanUp()
}, 0);
Using the timer allows the code to fall through into the event loop, update the UI, and then start up the calculation.
You're already using a section to pop up a "results" page -- why not pop up a "calculating" page?
Really, there are 4,000,000 different ways of tackling this problem, but why not try writing a "displayCalculatingMessage" function and a "removeCalculatingMessage" function, if you don't want to get all object-oriented on such a simple thing.
function displayCalculatingMessage () {
var submit_button = getSubmitButton();
submit_button.disabled = true;
// optionally get all inputs and disable those, as well
// now, you can either do something like pop up another hidden div,
// that has the loading message in it...
// or you could do something like:
var loading_span = document.createElement("span");
loading_span.id = "loading-message";
loading_span.innerText = "working...";
submit_button.parentElement.replaceChild(loading_span, submit_button);
}
function removeCalculatingMessage () {
var submit_button = getSubmitButton(),
loading_span = document.getElementById("loading-message");
submit_button.disabled = false;
loading_span.parentElement.replaceChild(submit_button, loading_span);
// and then reenable any other disabled elements, et cetera.
// then bring up your results div...
// ...or bring up your results div and do this after
}
There are a billion ways of accomplishing this, it all comes down to how you want it to appear to the user -- WHAT you want to have happen.

Categories