Set delay time for a loop execution - javascript

I'm trying to delay the execution of a loop by 3000ms, this is my code so far, but I keep on getting an error, does anyone can tell me why I'm getting error? Thanks in advance.
function contrEmpty(x,y,ev) {
setTimeout(function () {for (var i=0; i<=4; i++) {
if ((table[x+i+1][y] != 'R') && (table[x+i+1][y] != 'Y')) {
table[x+i+1][y] = table[x+i][y];
table[x+i][y] = 0;
var ultPosX = x+i+1;
var ultPosY = y;
var data = ev.dataTransfer.getData("text");
var dest=document.getElementById((x+i).toString()+y.toString()).childNodes;
var dom=document.getElementById((x+i).toString()+y.toString());
dom.removeChild(dest[0]);
var newRR= document.getElementById((x+i+1).toString()+(y).toString()).appendChild(document.getElementById(data).cloneNode(true));
}
}
}, 3000);
var cell = ev;
}

Related

JS queue array debug error

I am receiving this error,
Practice.html:formatted:20 Uncaught TypeError: queueArray.push is not a function
at Queue.add (Practice.html:formatted:20)
at Practice.html:formatted:30
but push isn't supposed to be a function. It is supposed to be a method executed on an array. So what could this mean??
var tickerArray = ['BP', 'AMZN', 'EARK'];
//also tried putting queueArray here because that would make it global, so i guess it isnt a scope issue?
function Queue() {
this.top = 0; //first item in the stack
var queueArray = []; //array to hold items
}
Queue.prototype.add = function(obj) {
queueArray.push(obj);
}
Queue.prototype.get = function() {
return queueArray.splice(this.top, 1);
}
var queueArray = new Queue();
for (i = 0; i < tickerArray.length; i++) {
queueArray.add(tickerArray[i]);
}
console.log(q.get());
Set queueArray as this.queueArray and return this.queueArray from .get()
var tickerArray = ['BP', 'AMZN', 'EARK'];
function Queue() {
this.top = 0; //first item in the stack
this.queueArray = []; //array to hold items
}
Queue.prototype.add = function(obj) {
this.queueArray.push(obj);
}
Queue.prototype.get = function() {
this.queueArray.splice(this.top, 1);
return this.queueArray; // `return` `this.queueArray` from the function
}
var queueArray = new Queue();
for (i = 0; i < tickerArray.length; i++) {
queueArray.add(tickerArray[i]);
}
console.log(queueArray.get());

javaScript:passing argument to eventListener

i'm try to make something and i made this piece of code,but when i press the botton it's happend for a sec and then disappear,am i donig passing the arguments wrong or something?
here the code is:
{
var fil1;
var rtextDiv;
for (var i = 0; i < dmsg.getElementsByClassName('refilter').length; i++) {
var refilterInput = dmsg.getElementsByClassName('refilter')[i];
refilterInput.addEventListener('keyup', firstfilter(rtextDiv, fil1,refilterInput));
}
};
function firstfilter(e, rtextDiv, fil1, refilterInput) {
rtextDiv = refilterInput.parentNode.parentNode.getElementsByClassName('rtext')[0];
while (rtextDiv.firstChild) {
rtextDiv.removeChild(rtextDiv.firstChild);
}
fil1 = filteredPropertiesTable(res, refilterInput.value);
rtextDiv.appendChild(fil1);
};
edited as the comment said:
{
var fil1;
var rtextDiv;
for (var i = 0; i < dmsg.getElementsByClassName('refilter').length; i++) {
var refilterInput = dmsg.getElementsByClassName('refilter')[i];
refilterInput.addEventListener('keyup', function()
{firstfilter(rtextDiv,fil1,refilterInput)(rtextDiv, fil1,refilterInput)});
);
}
};
function firstfilter(e, rtextDiv, fil1, refilterInput) {
rtextDiv = refilterInput.parentNode.parentNode.getElementsByClassName('rtext')[0];
while (rtextDiv.firstChild) {
rtextDiv.removeChild(rtextDiv.firstChild);
}
fil1 = filteredPropertiesTable(res, refilterInput.value);
rtextDiv.appendChild(fil1);
};
is it true know?can i pass argument that way?
Here you are actually executing the handler:
refilterInput.addEventListener('keyup', firstfilter(rtextDiv, fil1,refilterInput));
You should just present the handler name:
refilterInput.addEventListener('keyup', firstfilter);
And the handler can be improved:
function firstfilter(e) {
var rtextDiv = this.parentNode.parentNode.getElementsByClassName('rtext')[0];
while (rtextDiv.firstChild) {
rtextDiv.removeChild(rtextDiv.firstChild);
}
var fil1 = filteredPropertiesTable(res, this.value); // you didn't say what is res
rtextDiv.appendChild(fil1);
};

setTimeout in a loop and pass variables to use later

Consider the following code:
function func() {
var totalWidths = 0;
for( var i = 0, count = arr.length; i < count; i++ ) {
var image = arr[i];
insertElemInDOM(image);
preloadImage(image,function(){
var w = image.width();
totalWidths += w;
});
}
// do something with the variable "totalWidths"
doSomething(totalWidths)
}
I have 2 problems here. The image will be always the same (first problem), which one can solve with an anonymous function:
for(...) {
(function(image) {
preload(image,function() {
// now image is the correct one
});
})(image);
}
But how do I manage the totalWidths variable in order to use it later on doSomething(totalWidths)? The previous code would have a value of 0 for totalWidths.
Thanks!
You could timeout the whole loop and the doSomething, that's much more performant than setting up so many timeouts:
setTimeout(function() {
var inc = 0;
for (var i = 0; i < count; i++) {
var w = arr[i].width();
inc++;
}
doSomething(inc);
}, 1000);
However, what you actually seem to want are nested timeouts, i.e. waiting 1s for each iteration step and doing something after all have finished:
var inc = 0, count;
function asyncLoop(i, callback) {
if (i < count) {
var w = arr[i].width();
inc++;
setTimeout(function() {
asyncLoop(i+1, callback);
}, 1000);
} else {
callback();
}
}
asyncLoop(0, function() {
doSomething(inc);
});
OK, now that we know what you need the solution is to check after each load event whether all images are loaded:
var totalWidths = 0,
count = arr.length,
loaded = 0;
for (var i = 0; i < count; i++)
(function (image) {
insertElemInDOM(image);
preload(image, function() {
totalWidths += image.width();
// counter:
loaded++;
if (loaded == count-1) // the expected value
doSomething(totalWidths); // call back
});
})(arr[i]);

Javascript dynamic onChange event on select

I have this javascript snippet:
var selectName["id1","id2","id3"];
setOnClickSelect = function (prefix, selectName) {
for(var i=0; i<selectName.length; i++) {
var selId = selectName[i];
alert(selId);
$(selId).onchange = function() {
$(selId).value = $(selId).options[$(selId).selectedIndex].text;
}
}
}
But when I change value to my id1 element, the alert wrote me always "id3".
Can I fix it?
EDIT:
I've changed my snippet with these statements:
setOnChangeSelect = function (prefix, selectName) {
for(var i=0; i<selectName.length; i++) {
var selId = selectName[i];
$(selId).onchange = (function (thisId) {
return function() {
$(selId).value = $(thisId).options[$(thisId).selectedIndex].text;
}
})(selId);
}
}
But selId is always the last element.
This is caused by the behavior of javaScript Closure, selId has been set to the selectName[2] at the end of the loop and that's why you get 'id3' back.
An fix is as following, the key is wrap the callback function inside another function to create another closure.
var selectName = ["id1","id2","id3"];
var setOnClickSelect = function (prefix, selectName) {
for(var i = 0; i < selectName.length; i++) {
var selId = selectName[i];
$(selId).onchange = (function (thisId) {
return function() {
$(thisId).value = $(thisId).options[$(thisId).selectedIndex].text;
}
})(selId);
}
};
Ps: there is synyax error for var selectName["id1","id2","id3"], you should use var selectName = ["id1","id2","id3"];

Why is my interval time is not get cleared?

This is my function, I wrote this for moving my div from left to right. After iter reach 5, the interval has to stop. But now it is keep on running. My interval is not clearing, what is wrong with my function?
var mydiv = document.getElementById('news-variety');
var iter = 0;
if (mydiv) {
var columns = mydiv.getElementsByTagName('DIV');
function animeColumn(index, col) {
var timerID = window.setInterval(function () {
var current = window.getComputedStyle(col);
var matrix = new WebKitCSSMatrix(current.webkitTransform);
col.style.webkitTransform = matrix.translate(10, 0);
if (iter++ == 5) {
window.clearInterval(timerID);
}
}, 50);
}
for (var i = 0; i < columns.length; i++) {
if (columns[i].className.toLowerCase() == "column") {
columns[i];
animeColumn(i, columns[i]);
}
}
}
There is a weird behavior (bug?) in firefox that requires you to specify the second parameter of getComputedStyle to 'null'. Try:
var current = window.getComputedStyle(col,null);
It is likely that in your current case, the code is throwing an 'argument count' error in the timeout handler, which prevents further execution and thus, never clears the timeout.
Alternatively, you may want to do your loop counting at the start of your loop, as such:
function animeColumn(index, col) {
var timerID = window.setInterval(function () {
if (iter++ == 5) {
window.clearInterval(timerID);
}
var current = window.getComputedStyle(col);
var matrix = new WebKitCSSMatrix(current.webkitTransform);
col.style.webkitTransform = matrix.translate(10, 0);
}, 50);
}
I think it is because your var timerID is not defined at window's level
var mydiv = document.getElementById('news-variety');
var iter = 0;
var timerID;
if (mydiv) {
var columns = mydiv.getElementsByTagName('DIV');
function animeColumn(index, col) {
timerID = window.setInterval(function () {
var current = window.getComputedStyle(col);
var matrix = new WebKitCSSMatrix(current.webkitTransform);
col.style.webkitTransform = matrix.translate(10, 0);
if (iter++ == 5) {
window.clearInterval(timerID);
}
}, 50);
}
for (var i = 0; i < columns.length; i++) {
if (columns[i].className.toLowerCase() == "column") {
columns[i];
animeColumn(i, columns[i]);
}
}
}
iter is global, so it will reach 5 for only one of multiple columns.
Try moving it into the function like this:
function animeColumn(index, col) {
var iter = 0;
var timerID = window.setInterval(function () {
// ...
if (iter++ == 5) {
window.clearInterval(timerID);
}
}, 50);
}
i have created a fiddle for this http://jsfiddle.net/DXSNp/

Categories