What is the error with this tampermonkey code? - javascript

My goal is to go http://quizlet.com/12039115/scatter and get a score under 2 seconds. My plan is to do this by disabling the timer with setInterval/clearInterval.
I took some code off some site and tried adapting it to my purposes; it failed. Now I need to know what went wrong.
The original code can be found at blog.jazzychad.net/2011/03/20/inspect-javascript-timers-greasemonkey.html. When I loaded this to Tampermonkey and ran it on the page, only setInterval printed out(multiple times):
INSPECT_TIMERS: setInterval - 100ms
quizlib.2X5g7.js:340
INSPECT_TIMERS: function (){return c.apply(b,a||arguments)}
Thus, I can see that it finds the timer id. Now i need to clearInterval(). Here's where stuff goes wrong.
Code that gave output above:
var go = function(window){
var oldSetInterval = window.setInterval;
var newSetInterval = function(f,t) {
__log("INSPECT_TIMERS: setInterval - " + t + "ms");
__log("INSPECT_TIMERS: " + f);
var id = oldSetInterval(f,t);
return id;
};
window.setInterval = newSetInterval;
//setTimeoutDeleted
function __log(msg) {
if (window.console && window.console.log) {
window.console.log(msg);
}
}
};
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.textContent = '(' + go + ')(window);';
document.body.appendChild(script); // run the script
When I add
clearInterval(id);
immediately before
return id;
the page literally fails to respond to the click to start the "game". Am I approaching this wrong? Do I need some sort of delay, or am I missing the big picture?

You problem is, there are multiple setInterval calls, looks like 3 on my end.
If you run this code in your console before clicking "Start Game", it will log the following calls to setInterval.
var originalSetInterval = window.setInterval;
window.setInterval = function(func, intr) {
var id = originalSetInterval.apply(window, arguments);
console.log('----setInterval----');
console.log('function:', func);
console.log('interval:', intr);
console.log('id:', id);
console.log('-------------------');
return id;
};
Then when you click "Start Game", you will get output like the following.
----setInterval----
function: function()
interval: 17
id: 10
-------------------
----setInterval----
function: function()
interval: 17
id: 12
-------------------
----setInterval----
function: function()
interval: 100
id: 13
-------------------
Feel free to stop reading here and do some experimenting on your own before continuing to read.
You probably don't want to call clearInterval on all of these. The one that runs the clock appears to be the one with the 100 interval. To disable that interval without touching the other intervals, you can use a simple if statement.
var originalSetInterval = window.setInterval;
window.setInterval = function(func, intr) {
var id = originalSetInterval.apply(window, arguments);
console.log('----setInterval----');
console.log('function:', func);
console.log('interval:', intr);
console.log('id:', id);
console.log('-------------------');
if (intr === 100) {
clearInterval(id);
}
return id;
};
And doing this will successfully stop the clock. However, once you finish the game you will find that the game will still know how long you took. The clock is just a visual element.
If you want to cheat the game, you will need to target the code that actually calculates your final score. Sounds like a great opportunity to learn how to use your browser's developer tools, especially the JavaScript debugger (use the pretty-print feature to make the minified JS easier to read).

Related

JavaScript while loop + setInterval doesn't work in Django

I'm developing a website using Django. I have about 50 functions. And it takes about 1 minute to get the result for all of them.
The problem is that I use heroku for my app. And heroku has a limit of 30 sec to get the request. I was suggested to use background tasks. Now I am using background jobs in Python RQ. For each function I made a separate task in Views. Here is an example of one of the tasks:
task_robots_url = q.enqueue(Robots(url).get_url)
robots_url = task_robots_url.result
And now I need to check whether the job is finished in the Template. And when it's finished, display the result.
I want to check with JS each second whether the job is finished. If it's not finished - show "Loading ... " message to the user. If it's finished - show the result.
Here is my JS code:
<script>
var h1 = document.getElementById("h1");
var job_result = "{{ robots_url }}"
var test = function () {
if (job_result == "") {
h1.innerText = "Waiting...";
} else if (job_result == "None") {
h1.innerText = "Waiting ...";
} else if (job_result == undefined) {
h1.innerText = "Waiting ...";
} else {
clearInterval(inter);
h1.innerText = job_result;
}
}
var inter = setInterval(test, 1000);
</script>
But this doesn't work. When the result page starts - I've got an empty result. And it displays Waiting. Then I have None result. And it still displays Waiting. But now after waiting there is no result.
In the documentation for Python RQ it is said I should put time.sleep() for several seconds in my code. And if I put time.sleep(2) - I got the result. But if I put time.sleep(2) for each of my 50 functions - I will get 100 sec. And the limit in Heroku is only 30 sec... So I need to check and display the result without sleep()...
The setInterval() method calls a function or evaluates an expression at specified intervals (in milliseconds).
The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed.
You are calling setInterval so many times which cause your browser to crash eventually.
assuming job_result value changes after 10 sec you can write the following code:
var job_result = {{ job_result }};
var loadingMessage = function (){
if (!job_result) {
document.write("Loading ...");
}
else {
return
}
}
setInterval(() => loadingMessage, 1000);
You can call return to stop the Interval for running or you can use setTimeout and to call a function that clears the interval

function increment sync with video (or auto increment)

I'm busy with a webdoc that I'm partially creating on hype, the video are hosted on vimeo (so I need to use the vimeo api for some tasks like seekto) but my difficulties should be limited to js.
the objective is to display a given image at a given time interval of the video.
With my code below, I do get the string "test", "success" and "confirmed success" at the right time in my div id=popimgbox, and I can seek back and forth in the video and still get the right "answear", if I may say so.
Now, I have images that are all stored in the same folder, and all named popimgX.jpg, with X being a number.
I want
to store the URLs of my images in a variable let's say "popimgurl"
that my variable is updated (by a function???) in order to contain the URL of a given immage for a given interval of time of the video
to still be able seekto back and forth in the video and get the right URL at the right time
To do so I created a function increment, and a pair of variable. With the code below, my popimgurl variable is indeed updated once the video reach 3 seconds, but it do not increment only once... untill the video reach 6 seconds, when I want to update my popimgurl variable once again.
I tried to use for with js break and js closure but did not manage for some understandable reasons after thought;
I did quite some try with switch, but I'm stuck with the fact that the case must be string or single numerical value, not numerical interval or comparaison.
thank's in advance for your help :-)
var iframe = $('#vplayer_1')[0];
var player = $f(iframe);
var status = $('.status');
fired = 0;
//my try to sync increment
var dia = (function () {
var n = 0;
return function increment() {return n += 1;}
})();
function dian(){
popimgurl = '${resourcesFolderName}/popimg'+ dia() +'.jpg';
popimgloader = '<img src ="' + popimgurl + '">';
}
// When the player is ready, add listeners for pause, finish, and playProgress
player.addEvent('ready', function() {
status.text('ready');
player.addEvent('pause', onPause);
player.addEvent('finish', onFinish);
player.addEvent('playProgress', onPlayProgress);
});
// Call the API when a button is pressed
$('button').bind('click', function() {
player.api($(this).text().toLowerCase());
});
function onPause(id) {
status.text('paused');
}
function onFinish(id) {
status.text('finished');
}
function onPlayProgress(data, id) {
status.text(data.seconds + 's played');
//my chapters, when I want the img to change within popimgbox
if (data.seconds >= 1) {
popimgbox.innerHTML = "test";
}
if (data.seconds >= 3) {
// popimgbox.style.display = "success"
dian();
popimgbox.innerHTML = popimgurl;
}
if (data.seconds >= 6) {
// popimgbox.style.display = "confirmed success"
dian();
popimgbox.innerHTML = popimgurl;
}
}
PS1: disclamer, I'm a beginer coder, i do my best so excuse my french if my question isn't well formulated or if the answer is somewhere but I was unable to see/understand it
PS2 : i did quite a try with popcornjs, but not way to make it work with vimeoapi and within hype, quite frustrated ;-)
PS3: as this is my first post I would like to thank's you all for the great support available here; I owe you most ;-)
Finally I'll answer myself.
It's a solution that only stand for vimeo, as this is what I use to host my videos, but very little changes have to be done to work with the html5 <video> tag as well.
First you need to define your variables and your intervals:
var intervals =[11.56, 44.08, 115, 125, 127.92, 177.72];
var index;
Then you need to add an event listener timeupdate that return the elapsed time , filter intrevals according to the elapsed time data.seconds or seconds and define the value of index as the indexOf the last entry of your filtered array intervals
player.on('timeupdate', function(data) {
seconds = data.seconds;
index = intervals.indexOf(intervals.filter(function(nb) {
return seconds < nb;
})[0]);
if (diaIndex == -1) {
// do something if seconds > the higher value of your last interval
}
And that's it !
Now for
seconds = [0, 11.56[ --> index = 0
seconds = [11.56, 44.08[ --> index = 1
seconds = [44.08, 115[ --> index = 2
and so on
Now we can use index as a variable for instance to display a given image :
var imgNum = 0;
function diaplayImg(index) {
if(index === imgNum) {
return;
// this will avoid that the same image is releaded on every timeupdate events
}
else {
imgNum =+ index
document.getElementById('myImageWraper').innerHTML = "<img src='img" + imgNum+ ".png'>"
};
}
Don't forget, you need to call the function displayImage() in your timeupdate event listener, it will then be fired every ±250ms but the image won't be reloaded each time
PS : vimeo has realeased its new api between my question and my answer so the question use the old api while the answer use the new one

setInterval refuses to run my function after recent edit to my code... why?

To give you a grasp of what I mean in my title.
Take a look at this code which is before the setInterval stopped working.
var anime = function(){
_.each(db.get('','animedb'), function(site){
var ann = function(){
^ the function is in a var
for (var epid in eps) {
epid = parseInt(epid, 10);
var eptime = (new Date(eps[epid].pubDate[0])*1000)/1000;
if(eptime > site.lastbuilddate){
counter = counter+1;
if(counter < 6){
list.push(font(colors['normal'])+eps[epid].title[0] +' - ['+ utils.secondsToString((new Date() - (eptime+site.delay))/1000, 1)+' ago.]</f>');
}
}
};
^ this is the part that breaks everything after its been edited
var run = setInterval(ann, site.interval*60000);
^ here is the setInterval its at the bottom of the each
anime();
^ here is the call for the whole function that calls the setInterval
The above code is part of an anime announcement for chat rooms owned by anime sites owners using their rss feeds.
The above code works and excuse me for saying this but at this point.
I'm going to say "I have no idea why". Because i really have no idea why setInterval picks and chooses when to work.
I talked to a friend who had more knowledge than me in javascript and time based functions and he said that there are no "conditions" required for setInterval to run.
for (var epid in eps) {
epid = parseInt(epid, 10);
var eptime = (new Date(eps[epid].pubDate[0])*1000)/1000;
if(eptime > site.lastbuilddate){
counter = counter+1;
if(counter < 6){
var url = eps[epid].link.split('//')[1];
var keyword = '';
var words = url.substr(0, url.length-1).split('/').join('-').split('-');
for (var wid in words) {
keyword += words[wid].charAt(0);
}
http.get({hostname:'dev.ilp.moe', port:80, path:'/surl/yourls-api.php?username=usernameremovedforsecurity&password=passwordremovedforsecurity&format=json&action=shorturl&url='+url+'&title='+ctitle+' - '+eps[epid].title[0]+'&keyword='+keyword}, function(r) {
if(r.statusCode === 200) { //200 is success
var b = '';
r.on('data', function(c) {
b += c;
});
r.on('end', function() {
list.push(font(colors['normal'])+eps[epid].title[0] +' - ['+ utils.secondsToString((new Date() - (eptime+site.delay))/1000, 1)+' ago.] - http://dev.ilp.moe/surl/'+keyword+'</f>');
}
}
});
}
}
};
The above code is the part for creating shorturls.
Here is the json DB that is being loaded.
{"0":{"lastbuilddate":1426441081000,"delay":0,"host":"www.animerush.tv","path":"/rss.xml","chats":["animerushtv"],"interval":15},"1":{"lastbuilddate":1424068119000,"delay":28800000,"host":"dubbedanime.tv","path":"/feed/","chats":["dubbed-anime-tv"],"interval":15},"2":{"lastbuilddate":1426415086000,"delay":32400000,"host":"bestanimes.tv","path":"/feed/","chats":["bestanimestv"],"interval":15},"3":{"lastbuilddate":1426434866000,"delay":0,"host":"www.theanime.tv","path":"/feed/","chats":["timecapsule"],"interval":15}}
The recent edit to my code was supposed to implement Shortened links for each episode released using the links provided in the rss feeds from the sites in the database.
The domain http://ilp.moe is my domain.
I have console logged everywhere and tested as much as I possibly could.
At this point I do not understand why the edit is making code that used to be executed by setInterval no longer be executed.
The reason why the code wasn't executed is because the functions were assigned to a variable so they weren't run until it got to setInterval.
When they reach setInterval the errors prevent setInterval from executing (depends on the severity of the error).
after taking the function and just running it without putting it in a var or setInterval and console logging for a bit i found the error was caused by this line
var url = eps[epid].link.split('//')[1];
in this case
eps[epid].link; // === ["http://blah.com/animelolep1"]
my problem was that the var url was trying to split on a list and not a string
here is the fix
var url = eps[epid].link[0].split('//')[1]; // grabs the first item from the list and then splits

How can I get this JSONP call to return a value?

The purpose of the following functions are to access a script on Yahoo's servers and lookup a live currency conversion rate which will later be used to process a customer's purchases.
I'm able to access the rates in the JavaScript alert but I can't seem to return them to the Jquery method which originally called the getRate() function.
I've tried a standard return rate; at the end of the parseExchangeRate() function, which doesn't work. I've also tried setting rate as a global variable within parseExchangeRate() but that doesn't work either.
function getRate(from, to) {
var script = document.createElement('script');
script.setAttribute('src', "http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D"+from+to+"%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json&callback=parseExchangeRate");
document.body.appendChild(script);
}
function parseExchangeRate(data) {
var name = data.query.results.row.name;
rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
}
$(function() {
getRate('USD', 'PHP');
xRatePHP = rate;
/* Do stuff with rate */
});
Firebug informs me the rate is undefined when I try to access it in Jquery function.
The other thing I tried was setting the last parameter of the http request to callback=rate=parseExchangeRate which (not surprisingly) didn't work either.
UPDATE
#Relfor solved the original problem, which was that rate was not properly declared as a global variable in the global scope. I fixed that and then found a further issue which some have also identified below, which is that after getRate() is called (which can take about 2000ms to update the variable rate), the script moves on immediately without waiting for rate to be updated and uses rate regardless of whether it's ready.
I tried was attempting to use window.setInterval to create a delay to solve this, when it came to my attention that their was still activity in the thread even though I'd already accepted #Relfor's answer, so I'd prefer to bring it back here so that when we have this working, others can benefit from the solutions.
There is one final (I hope - final!) problem and that is that in order simplify the original question for posting, I ommitted to disclose that I'm actually trying to get two rates from Yahoo! (which possibly a few more planned) and therefore, I'm calling getRate() in a loop as follows:
function getRate(from, to) {
var script = document.createElement('script');
script.setAttribute('src', "http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D"+from+to+"%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json&callback=parseExchangeRate");
document.body.appendChild(script);
}
function parseExchangeRate(data) {
var name = data.query.results.row.name;
rate = parseFloat(data.query.results.row.rate, 10);
}
var rate = 1.00;
var timer;
var q;
var xRatePHP, xRateGBP;
$(function() {
function getTheRates() {
var rateArr = new Array('PHP','GBP');
for (var x=0; x < rateArr.length; x++) {
getRate('USD', rateArr[x]);
q = 0;
timer = window.setInterval(function(){manageTimer(rateArr[x])},100);
}
}
function manageTimer(c) {
if (rate != 1) {
window.clearInterval(timer);
/* Note that 'c' is undefined according to 'alert' below,
* so this next line is not working correctly.
*/
eval("xRate"+c+" = rate;");
alert(c + " = " + rate); // displays 'undefined 43.543'
rate = 1.00;
}
q++;
if (q > 30 ) {
window.clearInterval(timer);
// added below because above isn't working (but neither does this!)
timer = '';
alert(c+' timeout'); // 'c' is undefined according to alert ???
q = 0;
}
}
getTheRates();
/* Do stuff with the rates */
});
It was suggested that I move /* Do stuff with the rates */ to inside the function parseExchangeRate() but not sure whether that advice would still stand given my revelations about calling getRate() in a loop?
UPDATE 3 (replaced update 2)
I have created a JSbin here: http://jsbin.com/udikas/3/edit with the above which apart from these two issues appears to be working:
1) The timeout mechanism appears not to be working.
2) On line 33 this line alert('start timer (' + x +')'); without which, the timer doesn't seem to start! I have no idea why, but I can't leave that line in.
the variable rate has not been defined
$(function() {
getRate('USD', 'PHP');
xRatePHP = rate;
/* Do stuff with rate */
});
after studying your code it seems that rate is defined in the parseExchange(data) function as
function parseExchangeRate(data) {
var name = data.query.results.row.name;
rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
}
if you want rate to be accessible from the function namespaces without declaring them from within then the rates would have to specified in the global namespace, which is outside any of the functions or loops.
Edit: The namespace problem has been solved and the answer I've given has been accepted, however I would like to add details about the code you are handling here. It has been taken from the gist here: https://gist.github.com/henrik/265014
We are dealing with JSONP here
the reason why parseExchangeRate exists and the context of it can seem mysterious at first glance, albeit its existence is the primary connection between your JSONP request and the data returned by the response.
If you take a closer look at the request:
http://query.yahooapis.com/v1/public/yql?
q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2F
download.finance.yahoo.com%2Fd%2F
quotes%3Fs%3DUSDPHP%253DX%26f%3Dl1n'%20and%20
columns%3D'rate%2Cname'&format=json&callback=parseExchangeRate
(I broke the link up into many lines to make it easier to read)
Carefully look at the last segment of the url: callback=parseExchangeRate
This here is the connection, when the JSONP request is complete parseExchangeRate will be called.
So then why did it not work?
Let me display the code once again:
$(function() {
getRate('USD', 'PHP');
xRatePHP = rate;
/* Do stuff with rate */
});
We should break this up:
getRate('USD', 'PHP') does the job of loading the JSONP with the respective currency types of 'USD' and 'PHP'
xRatePHP = rate assigns the right hand side which is rate to xRatePHP. But this line gave us a problem! our console pal told us that rate is undefined!
The truth: mr.console did not lie, rate is actually undefined, however mr.console without any further commands given by you a few moments later if asked again would reply that rate is actually defined. Is this magic?
What is actually happening is that between the time you go from this line
getRate('USD', 'PHP');
to
xRatePHP = rate;
the JSONP response from mr.yahoo hasn't yet come back, which is why when xRatePHP = rate is issued rate seems to be undefined.
Hard Code Solution
Let us hard code a duration for our code to wait before using rate so that we know that mr.yahoo responded, setTimeout will helps us here:
getRate('USD', 'PHP');
setTimeout(function(){alert(rate)}, 2000);
and everything works now! check the demo at: http://jsbin.com/udikas/1/edit
Soft Code
did you ever consider the case where mr.yahoo takes more than 2000 ms to respond? or maybe even lesser than that? (yahoo is pretty fast!) let us instead take a different approach, this will let us use rate the exact moment we calculate it with parseExchangeRate
for this we will have to add a callback from parseExchangeRate:
function parseExchangeRate(data) {
var name = data.query.results.row.name;
rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
}
to
function parseExchangeRate(data) {
var name = data.query.results.row.name;
rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
gotTheRate(rate)
}
and then change
$(function() {
getRate('USD', 'PHP');
alert(rate)
});
to
function gotTheRate(rate){
alert(rate);
}
$(function() {
getRate('USD', 'PHP');
});
a demo of this can be found at http://jsbin.com/udikas/2/edit
Multiple Callbacks (in response to question update)
Remember hard coding setTimeouts isn't fun, so let us remove that, manageTimer, q, and other such elements from your code, instead we can have:
function getRate(from, to) {
var script = document.createElement('script');
script.setAttribute('src', "http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D"+from+to+"%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json&callback=parseExchangeRate");
document.body.appendChild(script);
}
function parseExchangeRate(data) {
var name = data.query.results.row.name;
rateDict[name.match(/USD to ([\w]*)/)[1]] = parseFloat(data.query.results.row.rate, 10);
total_responses++;
if (total_responses === rateArr.length){
for (var k in rateDict){
alert("USD to " + k + " is " + rateDict[k]);
}
}
}
var rate = 1.00;
var timer;
var q;
var rateArr = new Array('PHP','GBP')
var total_responses = 0;
var rateDict = {};
$(function() {
function getTheRates() {
for (var x=0; x < rateArr.length; x++) {
getRate('USD', rateArr[x]);
}
}
getTheRates();
});
http://jsbin.com/udikas/4/edit
-Relfor
You should re order your code flow:
function getRate(from, to) {
var script = document.createElement('script');
script.setAttribute('src', "http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D"+from+to+"%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json&callback=parseExchangeRate");
document.body.appendChild(script);
}
function parseExchangeRate(data) {
var name = data.query.results.row.name;
var rate = parseFloat(data.query.results.row.rate, 10);
alert("Exchange rate " + name + " is " + rate);
xRatePHP = rate;
/* Do stuff with rate */
}
$(function() {
getRate('USD', 'PHP');
// rate is not yet available here, so don't do anything with it
});
try to put:
var rate = 0;
on top of your code. This will fix the error.
Then you have to consider that if you get 0 maybe you are reading the variable at the wrong time, before it gets populated.

Rate limiting to prevent malicious behavior in ExpressJS

Someone made me aware of some flaws in an application I'm working on (mostly within my JavaScript on the front-end), that leaves open the possibility of, say, clicking a ton of buttons at once and sending out a ton of transactional emails. This is clearly not good.
I think one way to handle this in ExpressJS is by using app.all() to count the number of requests that happen within a certain timeframe. I'd store this in the session metadata with timestamps, and if more than X requests happen in Y time, I cut them off for awhile until the limit expires.
Has anyone done this before or have any tips/hints to help me out? Something that's easy to drop in and out of my app is preferable. Thanks!
You could use the Collate object in your webpage.
function Collate(timeout) {
this.timeout = timeout || 1000;
}
Collate.prototype = {
time: 0,
idle: function() {
var t = new Date().getTime();
return (t - this.time > this.timeout && (this.time = t));
},
prefer: function(func) {
this.func = func;
clearTimeout(this.timer);
this.timer = setTimeout(func, this.timeout);
}
};
If you want a function to run once and not run again within the next 1 second.
Like if you want to prevent the user from submitting a form many times, you do this:
var timer = new Collate(3000); //3 seconds
button1.onclick = function() {
if(timer.idle()) {
button1.form.submit();
} else alert("Don't click too quickly!");
}
//or on the form tag
<script>var submitTimer = new Collate(3000);</script>
<form action="post" onsubmit="return submitTimer.idle();">
If you expect an event to fire multiple times and only want to react to the last time it fires.
Like if you want to search after a user has finished typing, you do this:
var timer = new Collate(700); //0.7 seconds
textfield1.onkeyup = function() {
timer.prefer(function() {
autocomplete.search(textfield1.value);
});
};

Categories

Resources